diff --git a/q4-scalability/architecture-diagram.png b/q4-scalability/architecture-diagram.png
new file mode 100755
index 0000000..a917d48
Binary files /dev/null and b/q4-scalability/architecture-diagram.png differ
diff --git a/q4-scalability/architecture.md b/q4-scalability/architecture.md
new file mode 100644
index 0000000..7a00538
--- /dev/null
+++ b/q4-scalability/architecture.md
@@ -0,0 +1,49 @@
+# Scalable Architecture Design
+
+## Overview
+
+The application is designed to handle up to **15,000 requests per second (req/s)** on Ghaymah using multiple application containers behind a Load Balancer.
+
+The architecture distributes incoming traffic evenly across multiple container instances to ensure high availability, scalability, and fault tolerance.
+
+---
+
+## Architecture Components
+
+- Internet Users
+- Ghaymah Load Balancer
+- Multiple Application Containers
+- Ghaymah Block Storage
+- Database
+
+---
+
+## Traffic Flow
+
+1. Users send requests to the application.
+2. The Load Balancer receives all incoming traffic.
+3. Requests are distributed evenly across the application containers.
+4. Each container processes the request.
+5. Stateful data is stored in the database using Ghaymah Block Storage.
+
+---
+
+## High Availability
+
+If one container becomes unavailable, the Load Balancer automatically routes traffic to healthy containers without affecting users.
+
+ Internet Users
+ │
+ ▼
+ Ghaymah Load Balancer
+ │
+ ┌───────────────┼───────────────┐
+ ▼ ▼ ▼
+ App Container App Container App Container
+ │ │ │
+ └───────────────┼───────────────┘
+ │
+ Database
+ │
+ ▼
+ Ghaymah Block Storage
\ No newline at end of file
diff --git a/q4-scalability/block-storage.md b/q4-scalability/block-storage.md
new file mode 100644
index 0000000..2b1223a
--- /dev/null
+++ b/q4-scalability/block-storage.md
@@ -0,0 +1,49 @@
+# Ghaymah Block Storage for Stateful Workloads
+
+## Overview
+
+Stateful applications store persistent data that must remain available even if a container is restarted, replaced, or moved to another node.
+
+Ghaymah Block Storage provides persistent storage that can be attached to stateful workloads such as databases.
+
+---
+
+## Common Stateful Workloads
+
+- MySQL
+- PostgreSQL
+- MongoDB
+- Redis (Persistent Mode)
+
+---
+
+## How It Works
+
+1. The database container stores its data on a Ghaymah Block Storage volume.
+2. If the container fails, a new container can be started.
+3. The same Block Storage volume is reattached.
+4. The application continues using the existing data.
+
+---
+
+## Benefits
+
+- Persistent data storage
+- High durability
+- Faster recovery after failures
+- Data remains available after container restarts
+- Suitable for production database workloads
+
+---
+
+## Example Architecture
+
+```text
+Application Containers
+ │
+ ▼
+ Database Container
+ │
+ ▼
+ Ghaymah Block Storage
+```
\ No newline at end of file
diff --git a/q4-scalability/cold-start-strategy.md b/q4-scalability/cold-start-strategy.md
new file mode 100644
index 0000000..028302f
--- /dev/null
+++ b/q4-scalability/cold-start-strategy.md
@@ -0,0 +1,38 @@
+# Cold Start Strategy
+
+## Overview
+
+A cold start occurs when a new application container is created to handle increased traffic. During startup, the container needs time to initialize before it can receive requests.
+
+---
+
+## Strategy
+
+### 1. Keep Warm Containers
+
+Maintain a small number of standby containers that are already running and ready to receive traffic immediately.
+
+### 2. Auto Scaling
+
+Automatically create additional containers when CPU usage, memory usage, or request rate exceeds predefined thresholds.
+
+### 3. Lightweight Container Images
+
+Use small Docker images to reduce image download and startup time.
+
+### 4. Health Checks
+
+Only send traffic to containers after they successfully pass health checks.
+
+### 5. Container Image Caching
+
+Cache frequently used container images on the compute nodes to avoid downloading them repeatedly.
+
+---
+
+## Benefits
+
+- Faster application startup
+- Lower request latency
+- Better user experience during traffic spikes
+- Improved application availability
\ No newline at end of file
diff --git a/q4-scalability/container-calculation.md b/q4-scalability/container-calculation.md
new file mode 100644
index 0000000..3e55785
--- /dev/null
+++ b/q4-scalability/container-calculation.md
@@ -0,0 +1,41 @@
+# Container Capacity Calculation
+
+## Given
+
+- Expected traffic: **15,000 requests/second**
+- Capacity per container: **500 requests/second**
+- Safety margin: **30%**
+
+---
+
+## Step 1: Calculate Minimum Containers
+
+Minimum Containers = Total Requests ÷ Capacity per Container
+
+```
+15000 ÷ 500 = 30 Containers
+```
+
+---
+
+## Step 2: Add Safety Margin
+
+```
+30 × 30% = 9 Containers
+```
+
+---
+
+## Total Required Containers
+
+```
+30 + 9 = 39 Containers
+```
+
+---
+
+## Final Result
+
+To safely handle **15,000 requests per second**, the application should run **39 application containers**.
+
+The additional containers provide extra capacity during traffic spikes and improve overall reliability.
\ No newline at end of file
diff --git a/q5-mithal-monitor/Dockerfile b/q5-mithal-monitor/Dockerfile
new file mode 100644
index 0000000..025be5f
--- /dev/null
+++ b/q5-mithal-monitor/Dockerfile
@@ -0,0 +1,13 @@
+FROM python:3.12-slim
+
+WORKDIR /app
+
+COPY . .
+
+RUN pip install --no-cache-dir -r requirements.txt
+
+RUN chmod +x start.sh
+
+EXPOSE 8000
+
+CMD ["./start.sh"]
\ No newline at end of file
diff --git a/q5-mithal-monitor/README.md b/q5-mithal-monitor/README.md
new file mode 100644
index 0000000..e69de29
diff --git a/q5-mithal-monitor/dashboard/app.js b/q5-mithal-monitor/dashboard/app.js
new file mode 100644
index 0000000..568e63e
--- /dev/null
+++ b/q5-mithal-monitor/dashboard/app.js
@@ -0,0 +1,120 @@
+async function loadData() {
+
+ try {
+
+ const response = await fetch("data.json?t=" + Date.now());
+ const data = await response.json();
+
+ if (data.length === 0) {
+ return;
+ }
+
+ const latest = data[data.length - 1];
+
+ const upCount = data.filter(item => item.uptime === "UP").length;
+ const uptimePercentage = ((upCount / data.length) * 100).toFixed(1);
+
+ document.getElementById("uptime").innerText =
+ uptimePercentage + "%";
+
+ document.getElementById("latency").innerText =
+ (latest.latency_ms ?? "-") + " ms";
+
+ document.getElementById("dns").innerText =
+ (latest.dns_ms ?? "-") + " ms";
+
+ if (latest.ssl && latest.ssl.valid) {
+
+ document.getElementById("ssl").innerHTML = `
+ Valid
+ ${latest.ssl.expires}
+ `;
+
+ } else {
+
+ document.getElementById("ssl").innerHTML = `
+ Invalid
+ `;
+
+ }
+
+ const table = document.getElementById("historyTable");
+ table.innerHTML = "";
+
+ data
+ .slice()
+ .reverse()
+ .forEach(item => {
+
+ table.innerHTML += `
+
+ | ${item.timestamp} |
+ ${item.uptime} |
+ ${item.latency_ms ?? "-"} |
+ ${item.dns_ms ?? "-"} |
+ ${item.ssl && item.ssl.valid ? "Valid" : "Invalid"} |
+
+ `;
+
+ });
+
+
+ const labels = data.map(item => item.timestamp);
+ const latency = data.map(item => item.latency_ms);
+
+ if (!window.latencyChart) {
+
+ window.latencyChart = new Chart(
+ document.getElementById("latencyChart"),
+ {
+ type: "line",
+
+ data: {
+ labels: labels,
+ datasets: [{
+ label: "Latency (ms)",
+ data: latency,
+ borderColor: "#0b7dda",
+ backgroundColor: "rgba(11,125,218,0.15)",
+ fill: true,
+ tension: 0.3
+ }]
+ },
+
+ options: {
+ responsive: true,
+ plugins: {
+ legend: {
+ display: true
+ }
+ },
+ scales: {
+ y: {
+ beginAtZero: false
+ }
+ }
+ }
+ }
+ );
+
+ } else {
+
+ window.latencyChart.data.labels = labels;
+ window.latencyChart.data.datasets[0].data = latency;
+ window.latencyChart.update();
+
+ }
+
+ }
+
+ catch (error) {
+
+ console.error(error);
+
+ }
+
+}
+
+loadData();
+
+setInterval(loadData, 60000);
diff --git a/q5-mithal-monitor/dashboard/data.json b/q5-mithal-monitor/dashboard/data.json
new file mode 100644
index 0000000..c598310
--- /dev/null
+++ b/q5-mithal-monitor/dashboard/data.json
@@ -0,0 +1,62 @@
+[
+ {
+ "timestamp": "2026-07-28 17:50:54",
+ "status_code": 200,
+ "uptime": "UP",
+ "latency_ms": 994.55,
+ "dns_ms": 39.1,
+ "search_response_ms": 1170.81,
+ "ssl": {
+ "valid": true,
+ "expires": "Sep 15 13:10:47 2026 GMT"
+ }
+ },
+ {
+ "timestamp": "2026-07-28 17:50:58",
+ "status_code": 200,
+ "uptime": "UP",
+ "latency_ms": 986.42,
+ "dns_ms": 40.91,
+ "search_response_ms": 1130.27,
+ "ssl": {
+ "valid": true,
+ "expires": "Sep 15 13:10:47 2026 GMT"
+ }
+ },
+ {
+ "timestamp": "2026-07-28 17:51:01",
+ "status_code": 200,
+ "uptime": "UP",
+ "latency_ms": 980.57,
+ "dns_ms": 51.6,
+ "search_response_ms": 1168.75,
+ "ssl": {
+ "valid": true,
+ "expires": "Sep 15 13:10:47 2026 GMT"
+ }
+ },
+ {
+ "timestamp": "2026-07-28 17:51:04",
+ "status_code": 200,
+ "uptime": "UP",
+ "latency_ms": 969.79,
+ "dns_ms": 40.75,
+ "search_response_ms": 1209.84,
+ "ssl": {
+ "valid": true,
+ "expires": "Sep 15 13:10:47 2026 GMT"
+ }
+ },
+ {
+ "timestamp": "2026-07-28 17:51:07",
+ "status_code": 200,
+ "uptime": "UP",
+ "latency_ms": 976.47,
+ "dns_ms": 42.13,
+ "search_response_ms": 1147.52,
+ "ssl": {
+ "valid": true,
+ "expires": "Sep 15 13:10:47 2026 GMT"
+ }
+ }
+]
\ No newline at end of file
diff --git a/q5-mithal-monitor/dashboard/index.html b/q5-mithal-monitor/dashboard/index.html
new file mode 100644
index 0000000..7af797d
--- /dev/null
+++ b/q5-mithal-monitor/dashboard/index.html
@@ -0,0 +1,94 @@
+
+
+
+
+
+
+ Mithal Monitoring Dashboard
+
+
+
+
+
+
+
+
+
+
+
Mithal Monitoring Dashboard
+
+
+ Website Monitoring Dashboard for mithal.space
+
+
+
+
+
+
+
Latency History
+
+
+
+
+
+
+
+
Last 10 Checks
+
+
+
+
+
+
+
+ | Time |
+
+ Status |
+
+ Latency (ms) |
+
+ DNS (ms) |
+
+ SSL |
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/q5-mithal-monitor/dashboard/style.css b/q5-mithal-monitor/dashboard/style.css
new file mode 100644
index 0000000..72fd044
--- /dev/null
+++ b/q5-mithal-monitor/dashboard/style.css
@@ -0,0 +1,122 @@
+* {
+ margin: 0;
+ padding: 0;
+ box-sizing: border-box;
+}
+
+body {
+ font-family: Arial, Helvetica, sans-serif;
+ background: #f4f7fb;
+ color: #333;
+}
+
+.container {
+ width: 95%;
+ max-width: 1300px;
+ margin: 40px auto;
+}
+
+h1 {
+ text-align: center;
+ margin-bottom: 10px;
+ color: #2c3e50;
+}
+
+.subtitle {
+ text-align: center;
+ margin-bottom: 35px;
+ color: gray;
+}
+
+.cards {
+ display: grid;
+ grid-template-columns: repeat(4, 1fr);
+ gap: 20px;
+ margin-bottom: 35px;
+}
+
+.card {
+ background: white;
+ border-radius: 10px;
+ padding: 25px;
+ text-align: center;
+ box-shadow: 0 2px 8px rgba(0,0,0,.08);
+}
+
+.card h2 {
+ margin-bottom: 15px;
+ color: #555;
+ font-size: 20px;
+}
+
+.card p {
+ font-size: 30px;
+ font-weight: bold;
+ color: #0b7dda;
+}
+
+.chart-card,
+.table-card {
+ background: white;
+ border-radius: 10px;
+ padding: 25px;
+ margin-top: 30px;
+ box-shadow: 0 2px 8px rgba(0,0,0,.08);
+}
+
+.chart-card h2,
+.table-card h2 {
+ margin-bottom: 20px;
+}
+
+table {
+ width: 100%;
+ border-collapse: collapse;
+}
+
+thead {
+ background: #0b7dda;
+ color: white;
+}
+
+th,
+td {
+ padding: 12px;
+ text-align: center;
+ border-bottom: 1px solid #ddd;
+}
+
+tbody tr:hover {
+ background: #f5f5f5;
+}
+
+canvas {
+ width: 100% !important;
+ max-height: 350px;
+}
+
+@media (max-width:900px){
+
+.cards{
+
+grid-template-columns:repeat(2,1fr);
+
+}
+
+}
+
+@media (max-width:600px){
+
+.cards{
+
+grid-template-columns:1fr;
+
+}
+
+table{
+
+font-size:12px;
+
+}
+
+}
\ No newline at end of file
diff --git a/q5-mithal-monitor/data.json b/q5-mithal-monitor/data.json
new file mode 100644
index 0000000..c598310
--- /dev/null
+++ b/q5-mithal-monitor/data.json
@@ -0,0 +1,62 @@
+[
+ {
+ "timestamp": "2026-07-28 17:50:54",
+ "status_code": 200,
+ "uptime": "UP",
+ "latency_ms": 994.55,
+ "dns_ms": 39.1,
+ "search_response_ms": 1170.81,
+ "ssl": {
+ "valid": true,
+ "expires": "Sep 15 13:10:47 2026 GMT"
+ }
+ },
+ {
+ "timestamp": "2026-07-28 17:50:58",
+ "status_code": 200,
+ "uptime": "UP",
+ "latency_ms": 986.42,
+ "dns_ms": 40.91,
+ "search_response_ms": 1130.27,
+ "ssl": {
+ "valid": true,
+ "expires": "Sep 15 13:10:47 2026 GMT"
+ }
+ },
+ {
+ "timestamp": "2026-07-28 17:51:01",
+ "status_code": 200,
+ "uptime": "UP",
+ "latency_ms": 980.57,
+ "dns_ms": 51.6,
+ "search_response_ms": 1168.75,
+ "ssl": {
+ "valid": true,
+ "expires": "Sep 15 13:10:47 2026 GMT"
+ }
+ },
+ {
+ "timestamp": "2026-07-28 17:51:04",
+ "status_code": 200,
+ "uptime": "UP",
+ "latency_ms": 969.79,
+ "dns_ms": 40.75,
+ "search_response_ms": 1209.84,
+ "ssl": {
+ "valid": true,
+ "expires": "Sep 15 13:10:47 2026 GMT"
+ }
+ },
+ {
+ "timestamp": "2026-07-28 17:51:07",
+ "status_code": 200,
+ "uptime": "UP",
+ "latency_ms": 976.47,
+ "dns_ms": 42.13,
+ "search_response_ms": 1147.52,
+ "ssl": {
+ "valid": true,
+ "expires": "Sep 15 13:10:47 2026 GMT"
+ }
+ }
+]
\ No newline at end of file
diff --git a/q5-mithal-monitor/monitor.py b/q5-mithal-monitor/monitor.py
new file mode 100644
index 0000000..71966ee
--- /dev/null
+++ b/q5-mithal-monitor/monitor.py
@@ -0,0 +1,135 @@
+import json
+import os
+import socket
+import ssl
+import time
+from datetime import datetime
+
+import dns.resolver
+import requests
+
+URL = "https://mithal.space"
+DATA_FILE = "data.json"
+
+
+def get_dns_time():
+ try:
+ start = time.time()
+
+ dns.resolver.resolve("mithal.space", "A")
+
+ end = time.time()
+
+ return round((end - start) * 1000, 2)
+
+ except Exception:
+ return None
+
+
+def get_ssl_info():
+ try:
+ hostname = "mithal.space"
+
+ context = ssl.create_default_context()
+
+ with context.wrap_socket(
+ socket.socket(),
+ server_hostname=hostname
+ ) as sock:
+
+ sock.settimeout(10)
+ sock.connect((hostname, 443))
+
+ cert = sock.getpeercert()
+
+ return {
+ "valid": True,
+ "expires": cert["notAfter"]
+ }
+
+ except Exception:
+
+ return {
+ "valid": False,
+ "expires": None
+ }
+
+
+def get_search_response():
+ try:
+ start = time.time()
+
+ requests.get(URL, timeout=10)
+
+ end = time.time()
+
+ return round((end - start) * 1000, 2)
+
+ except Exception:
+ return None
+
+
+def check_website():
+ try:
+ response = requests.get(URL, timeout=10)
+
+ result = {
+ "timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
+ "status_code": response.status_code,
+ "uptime": "UP" if response.status_code == 200 else "DOWN",
+ "latency_ms": round(response.elapsed.total_seconds() * 1000, 2),
+ "dns_ms": get_dns_time(),
+ "search_response_ms": get_search_response(),
+ "ssl": get_ssl_info()
+ }
+
+ except Exception as e:
+
+ result = {
+ "timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
+ "status_code": None,
+ "uptime": "DOWN",
+ "latency_ms": None,
+ "dns_ms": None,
+ "search_response_ms": None,
+ "ssl": {
+ "valid": False,
+ "expires": None
+ },
+ "error": str(e)
+ }
+
+ return result
+
+
+def load_data():
+ if not os.path.exists(DATA_FILE):
+ return []
+
+ with open(DATA_FILE, "r") as file:
+ try:
+ return json.load(file)
+ except json.JSONDecodeError:
+ return []
+
+
+def save_data(data):
+ with open(DATA_FILE, "w") as file:
+ json.dump(data, file, indent=4)
+
+
+def main():
+ data = load_data()
+
+ result = check_website()
+
+ data.append(result)
+ data = data[-10:]
+
+ save_data(data)
+
+ print(result)
+
+
+if __name__ == "__main__":
+ main()
\ No newline at end of file
diff --git a/q5-mithal-monitor/requirements.txt b/q5-mithal-monitor/requirements.txt
new file mode 100644
index 0000000..16ad02c
--- /dev/null
+++ b/q5-mithal-monitor/requirements.txt
@@ -0,0 +1,2 @@
+requests
+dnspython
\ No newline at end of file
diff --git a/q5-mithal-monitor/start.sh b/q5-mithal-monitor/start.sh
new file mode 100644
index 0000000..f8a3848
--- /dev/null
+++ b/q5-mithal-monitor/start.sh
@@ -0,0 +1,13 @@
+#!/bin/sh
+
+while true
+do
+ python monitor.py
+
+ cp data.json dashboard/data.json
+
+ sleep 60
+done &
+
+cd dashboard
+python -m http.server 8000
\ No newline at end of file