# v2 git bundle
5419a512653611fdce84290c40b13b48b3687ee5 refs/heads/bundle
5419a512653611fdce84290c40b13b48b3687ee5 HEAD

PACK      %x ,tree 058b78371a352c276d49dc0c309fb555004c20a5
parent 4fd4bb72e10d210a5921ea8099bb1d35dab2d878
author mac <mac@macs-iMac.local> 1785149530 +0300
committer mac <mac@macs-iMac.local> 1785149530 +0300

first commit
P=Wx tree 180c983537969993b83c73873b2dab2943bc52dc
author mac <mac@macs-iMac.local> 1785149084 +0300
committer mac <mac@macs-iMac.local> 1785149084 +0300

feat: complete initial project structure for API and Monitoring Dashboards
Fxz40000 .github N4X8zAK?
100644 .gitignore 7OA~:z+wK100644 README.md m,3uHRS@Ր40000 api :䞅6}+tTx340000 architecture 2I;ϬP40000 ci v-hI.#H40000 dashboard b,019UDia40000 mithal_monitor `N(wg`ÍqI40000 monitor eBqevqH&lǾ40000 postmortem w._3HA3pp40000 scaling H0\rH1*x	!bx$ 40000 workflows D;R]_`GfKx" 100644 ci.yml 	tPpsI?̳f
xxTMo@+FiTS\V㴲CNv~8+iJ	X7oVCby)\`U5	Y%KyR@eu b"Q_ >CrGh<],!(̸6jΆj8Bx7HAfU峊{OoOBll~jEN!=1@׭ xKB&|+r)3ࢧ0*72C5(dƅ_8_}lIVZ 7*K⨸18Bdx=Nn~,y7bZKY~]=Ν[pd»a+%'^Υ?d`B =n`!Gul:ik~z:gt
~S)uصk\IQ MӶ6pmZG\Y4?If 8z+at9%˒؅mR~=忠0բVNJn|#4Hf-oW21aYt(nyfaunBc!Α7r+!wS:eCE^uK_DU{7gW4xK venv/
__pycache__/
*.pyc
.env
monitor.log
api.log
monitor_sh.log
.DS_Store
'>x # SRE-project
B\xt 100644 Dockerfile 5eIcΨxT)<100644 app.py }HHBEslw?ptB100644 requirements.txt fYlK"k0xsU(,ϳ234-
vRO,(rT(J-,,JM+)+(

S(,P+.IQMNLHM,R-6h^A%rvU00ruQV8NIGA	D) ̈< x5
 Jc=5Jl]ݛ2s9|3~u\{+UDFG[ߕ)y]x^7ǭVň"ⷑǋƠ$6$"yԔ+wf^==x Flask==3.0.3
|h
x \100644 block_storage.md ի1D~jܦ	100644 capacity.md nL&Iڐ[ 9<'4q100644 cold_start.md 5|bǘ^100644 diagram.mmd 7Etd(_kt#7@жXxy# Using ghaymah Block Storage for Stateful Workloads

Containers are inherently stateless; they lose their local filesystem data when they are destroyed or rescheduled. For applications that require persistent data (Stateful Workloads), we utilize **ghaymah Block Storage**.

## 1. What is Block Storage?
Block Storage provides persistent, highly available disk volumes that can be attached to containers. Unlike object storage (S3), it behaves like a physical hard drive mounted to the OS.

## 2. Use Cases in our Architecture
While our API application is mostly stateless, certain workloads require persistence:
- **Local Caching:** If a container downloads large datasets or machine learning models upon startup, these can be stored on Block Storage so subsequent container restarts are faster.
- **Session Data / Logs:** If we are writing complex audit logs that haven't yet been shipped to a centralized logging service.
- **Databases:** If running a self-managed database (e.g., PostgreSQL or Redis) within a container, Block Storage is mandatory to prevent data loss.

## 3. Configuration & Mounting
When deploying via the `ghaymah deploy` CLI or dashboard, we specify a volume mount:
```yaml
volumes:
  - name: my-persistent-data
    size: 50GB
    mountPath: /mnt/data
```
Inside the container, the application can simply read/write files to `/mnt/data/` knowing the data will survive container restarts.
IFx}S͎0)FZ!unZ$";I&2v ^'an=biZtθ#|FWY|8LweK8vY54c1nc!G]E X
,VvJ!l	֑hh1ҨׅL4N~〮$g|@&xm0"A/[Q/1rt	wgqyo$SOin&o͋#g5eS]SĆ`g  ~eA&_Ov3dy$,+;Vht^rRMD`AL}c,rLalr`6?ndٽ
Z(Qf#W$!Ү\ʾKrp`u]g_p?~;3o{{dC/r1E.E;,5%^^B=C@[h;6^\=$cZ0mZJY[!AODn#K&CPC'` cxCe}W Ǫ"ú6%pk^ww-Sj[0M`~tJt7YE}}BHy.bh-k
7sYxn# Cold Start Strategy

When auto-scaling responds to a traffic spike, new containers must be initialized. The time it takes from the scaling decision to the container actually serving requests is the "cold start" latency.

To minimize this delay and prevent dropped requests, we implement the following strategy:

## 1. Lightweight Base Images
- Use Alpine or distroless base images (e.g., `python:3.11-alpine`).
- Smaller images pull faster from the Container Registry over the network.

## 2. Pre-warming (Buffer Pool)
- Configure the Auto-Scaling Group to always maintain a "buffer" of idle containers (e.g., 10% of the current required capacity).
- If we need 43 containers for active load, we run ~47 containers. When traffic spikes, these 4 idle containers can serve requests instantly while the ASG provisions new ones.

## 3. Lazy Loading & Readiness Probes
- Defer non-critical initialization (like building large in-memory caches) until *after* the container has started accepting requests.
- Configure Kubernetes/ghaymah readiness probes to accurately reflect when the app is ready to serve traffic, ensuring the load balancer doesn't route traffic to a container that is still booting.

## 4. Keep-Alive & Connection Pooling
- Ensure idle containers aren't prematurely terminated. Keep database connections alive in a connection pool to avoid the latency of establishing new TCP handshakes during a sudden burst.
=x*```mermaid
graph TD
    Client((Client Requests <br> 15,000 req/s)) --> WAF[Web Application Firewall]
    WAF --> LB[ghaymah Load Balancer]

    subgraph Auto-Scaling Group
        direction LR
        LB -->|Traffic Distribution| API1[myapp-api Container 1 <br> ~350 req/s]
        LB --> API2[myapp-api Container 2 <br> ~350 req/s]
        LB --> API3[myapp-api Container 3]
        LB -.-> APIN[myapp-api Container N <br> Total: 43 Containers]
    end

    API1 --> BS1[(ghaymah Block Storage <br> /mnt/data)]
    API2 --> BS2[(ghaymah Block Storage <br> /mnt/data)]
    API3 --> BS3[(ghaymah Block Storage <br> /mnt/data)]
    APIN --> BSN[(ghaymah Block Storage <br> /mnt/data)]

    classDef container fill:#e3f2fd,stroke:#1565c0,stroke-width:2px;
    classDef lb fill:#fff3e0,stroke:#e65100,stroke-width:2px;
    classDef storage fill:#e8f5e9,stroke:#2e7d32,stroke-width:2px;

    class API1,API2,API3,APIN container;
    class LB lb;
    class BS1,BS2,BS3,BSN storage;
```
3(MxO 100644 README.md ڷGvwdky100644 ghaymah_cli.md Q-Xxj+ofe`TU_]x## Environments: Staging vs Production

In our deployment pipeline, we utilize two main environments: **Staging** and **Production**. Understanding the differences between them is crucial for safe software delivery.

## 1. Staging Environment (`staging`)
- **Purpose:** A pre-production area for QA testing, integration testing, and final review by stakeholders before a release goes live.
- **Data:** Uses dummy, sanitized, or replicated data. NEVER connects to the live production database.
- **Access:** Restricted to internal team members, developers, and QA testers. Often protected by VPN, IP whitelisting, or Basic Auth.
- **Scale:** Typically scaled down (fewer containers, smaller database instances) to save costs, as it doesn't need to handle user traffic.
- **Deployment:** Automatic upon merging code to the `main` branch.

## 2. Production Environment (`production`)
- **Purpose:** The live environment that real users interact with.
- **Data:** Contains live, sensitive, real user data. Strict access controls and backups are enforced.
- **Access:** Publicly accessible (for web apps/APIs). Infrastructure access is strictly limited to authorized SREs/DevOps personnel.
- **Scale:** Scaled up to handle expected user load, with Auto-Scaling policies enabled to handle traffic spikes.
- **Deployment:** Requires a **Manual Approval** step in the CI/CD pipeline (e.g., in GitHub Actions) to ensure that the code deployed to staging has been properly vetted and approved for live release.
 ͶLx9# Integrating with the ghaymah CLI

To manage and deploy applications to ghaymah.systems from your local machine or CI/CD pipeline, you need to use the `ghaymah` CLI.

## 1. Installation
Depending on your OS, install the CLI (example for macOS/Linux):
```bash
curl -sL https://cli.ghaymah.systems/install.sh | bash
```

## 2. Authentication
Log in to your ghaymah account:
```bash
ghaymah login
```
This will open a browser window to authenticate. If you are in a CI/CD environment (headless), use a token:
```bash
ghaymah login --token $GHAYMAH_TOKEN
```

## 3. Pushing Images to ghaymah Container Registry
Authenticate Docker with the ghaymah registry:
```bash
docker login registry.ghaymah.systems -u $GHAYMAH_USERNAME -p $GHAYMAH_TOKEN
```
Build and push your image:
```bash
docker build -t registry.ghaymah.systems/my-org/myapp-api:v1 .
docker push registry.ghaymah.systems/my-org/myapp-api:v1
```

## 4. Deploying the Application
Once the image is in the registry, deploy it using the CLI:
```bash
ghaymah deploy \
  --name myapp-api \
  --image registry.ghaymah.systems/my-org/myapp-api:v1 \
  --port 8080 \
  --env production
```
You can also monitor logs in real-time:
```bash
ghaymah logs myapp-api --follow
```
Txp 100644 index.html +V"gޒ'qu100644 script.js ;p9\6Kk100644 style.css SɿK-x"k6xc/n@x <!DOCTYPE html>
<html lang="ar" dir="rtl">
<head>
  <meta charset="UTF-8">
  <title>Ghaymah API Monitoring</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <h1>نظام المراقبة السحابي (API)</h1>
  
  <div class="dashboard-container">
    <div class="card">
      <div class="card-title">حالة الخدمة</div>
      <div id="status" class="card-value">
        <span class="status-indicator unknown"></span>
        <span class="text unknown">جاري الفحص...</span>
      </div>
    </div>
    
    <div class="card">
      <div class="card-title">زمن الاستجابة</div>
      <div id="latency" class="card-value">
        <span class="unknown">-</span> <span style="font-size:1rem; color:var(--text-muted)">ms</span>
      </div>
    </div>
    
    <div class="card">
      <div class="card-title">إجمالي الطلبات</div>
      <div id="requests" class="card-value counter">0</div>
    </div>
  </div>

  <script src="script.js"></script>
</body>
</html>
pjoMx!let requestCount = 0;

async function checkHealth() {
  const startTime = Date.now();
  try {
    const response = await fetch('http://localhost:8080/health');
    const latency = Date.now() - startTime;
    requestCount++;
    
    if (response.ok) {
      document.getElementById('status').innerHTML = `
        <span class="status-indicator good"></span>
        <span class="text good">متصل ويعمل</span>
      `;
    } else {
      document.getElementById('status').innerHTML = `
        <span class="status-indicator bad"></span>
        <span class="text bad">خطأ بالخادم</span>
      `;
    }
    
    document.getElementById('latency').innerHTML = `<span class="good">${latency}</span> <span style="font-size:1rem; color:var(--text-muted)">ms</span>`;
    document.getElementById('requests').innerHTML = requestCount.toLocaleString();

  } catch (error) {
    document.getElementById('status').innerHTML = `
      <span class="status-indicator bad"></span>
      <span class="text bad">غير متصل</span>
    `;
    document.getElementById('latency').innerHTML = `<span class="unknown">-</span> <span style="font-size:1rem; color:var(--text-muted)">ms</span>`;
  }
}

setInterval(checkHealth, 5000);
checkHealth();
Uƶxv@import url('https://fonts.googleapis.com/css2?family=Outfit:wght@300;400;600;700&display=swap');

:root {
  --bg-color: #0f172a;
  --card-bg: rgba(30, 41, 59, 0.7);
  --text-main: #f8fafc;
  --text-muted: #94a3b8;
  --accent: #3b82f6;
  --success: #10b981;
  --danger: #ef4444;
  --glow-success: rgba(16, 185, 129, 0.4);
  --glow-danger: rgba(239, 68, 68, 0.4);
}

body {
  font-family: 'Outfit', sans-serif;
  background-color: var(--bg-color);
  background-image: 
    radial-gradient(at 0% 0%, rgba(59, 130, 246, 0.15) 0px, transparent 50%),
    radial-gradient(at 100% 100%, rgba(139, 92, 246, 0.15) 0px, transparent 50%);
  color: var(--text-main);
  text-align: center;
  min-height: 100vh;
  margin: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 20px;
}

h1 {
  font-size: 3rem;
  font-weight: 700;
  margin-bottom: 40px;
  background: linear-gradient(to right, #60a5fa, #c084fc);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  letter-spacing: 2px;
}

.dashboard-container {
  display: flex;
  gap: 20px;
  flex-wrap: wrap;
  justify-content: center;
  max-width: 900px;
}

.card {
  background: var(--card-bg);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  border: 1px solid rgba(255, 255, 255, 0.1);
  padding: 30px;
  border-radius: 20px;
  min-width: 250px;
  box-shadow: 0 10px 30px -10px rgba(0, 0, 0, 0.5);
  transition: transform 0.3s ease, box-shadow 0.3s ease;
  position: relative;
  overflow: hidden;
}

.card:hover {
  transform: translateY(-5px);
  box-shadow: 0 20px 40px -10px rgba(0, 0, 0, 0.6);
  border: 1px solid rgba(255, 255, 255, 0.2);
}

.card::before {
  content: '';
  position: absolute;
  top: 0; left: 0; right: 0; height: 3px;
  background: linear-gradient(to right, transparent, var(--accent), transparent);
  opacity: 0.5;
}

.card-title {
  font-size: 1.1rem;
  color: var(--text-muted);
  margin-bottom: 15px;
  text-transform: uppercase;
  letter-spacing: 1px;
}

.card-value {
  font-size: 2.5rem;
  font-weight: 600;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
}

.good { 
  color: var(--success); 
  text-shadow: 0 0 15px var(--glow-success);
}
.bad { 
  color: var(--danger); 
  text-shadow: 0 0 15px var(--glow-danger);
}
.unknown { color: var(--text-muted); }

/* Ping Animation for Status */
.status-indicator {
  display: inline-block;
  width: 15px; height: 15px;
  border-radius: 50%;
  position: relative;
}
.status-indicator.good { background-color: var(--success); }
.status-indicator.bad { background-color: var(--danger); }
.status-indicator.good::after {
  content: '';
  position: absolute; width: 100%; height: 100%; top: 0; left: 0;
  border-radius: 50%; background-color: var(--success);
  animation: ping 2s cubic-bezier(0, 0, 0.2, 1) infinite;
}

@keyframes ping {
  75%, 100% { transform: scale(2.5); opacity: 0; }
}
,ˑsx| 40000 dashboard -ZbzdD0-n100644 deploy_instructions.md dvUBrDIve%)r100644 monitor.py 5=aUqA1Tx& 100644 index.html a4Bk˵mcYcxێ=_1aREJkn-j'Qot(@FH7W5h;5	})_7pݠ"E?)]h^hos=NS2Sa0`H@Р >CC#F>)Jq3kG	9#b頙gZyA3yOF>#%	|r+I,+xR5&\^6=)[АSӠ7/߆ߛs$C9AT3J	("aH峀	;b%2Ҋ8V;~,k<푏0fzT="cZsnqn_T\.kA0U?:llwepy,B؟tA'%#L֤{ӽ閩c㱖逈c;8/JO=b2DHZ	><ޣ<XAJV
G>	}i;9ict@GsXSy\xT'DpFfh J*		,?4%	mрOANt%2ρ60S_^S<',=,``	FS[<
y'9'^&̚ ޹5羚rI4=ac엤u;)VqAnz$ciSP=DB|n9J%s?AH8
%X`
"89{ћgL`xsTtW5@5å2A2mKbPC+XX<]QvEesi Ɓn	=iShN[P蜰8D)8mL%݈n)\2e}Zbmi'BrH^5Ѭӝ+	*:FoE*eCHcZ;jO-**KSUd%xn;gz=E.xǱw
:IgVpɴmkL)
"Jf:VZL޿:ej@ߐ
fg̻;Z>Y>[Y"˧o/VfHψP){cӊPQqV/;dxxBXq'>hb)T+[G4%4ZaV<9*Q/TZXY>G|''FT^aJSO_^{~JCz6𪉼JdQzVr'RKI|EЮ]w⯋C|:dZ2U9JΨJ
 3]F>R:͈NfV^cӿ*WH/1(I,nd`k+Ne+i{/ߌ|g Gi_7>_'tˡ_x7'		D,v0T +6Pzq	n7 .jLYHឯv`P,^fmh"++)]7p&9GħD|ƑnV1!3$&yڜ8SF\,I{4.&ia{ME~]^jH@,dH<j!%DlN4kŇU`ͧH
(SN-?9tSQvYG;q*$  fτ<l*>QФ(lVYgٓ F?'v 7eI/	RAg	l|YlK#.
onpJ:?mip~,VvǷ\-߬"Ay>k/>E^ _n{Fgvn-*V0._{˛+T['pM Y9u>dG#1j t"All? BY=f+=إenܥDe5Ph
Cp+^Ew$ѪIbsyVj	SV}͂cw .n68)*L} ! S}\mFxH.*`fIԉ#Ysdk=𲘅P]9/0euúTݲU*3[jƍ]oץc^gUc񇗺ɨ^zT|+hZmu|iyWѝ{`H4K5Π5L0L\4cQx# Deployment Instructions: Mithal Monitoring Dashboard

To serve the HTML dashboard and the collected `metrics.json` data, we will deploy a simple Nginx container to ghaymah.systems.

## 1. Directory Structure Setup
Move the dashboard HTML and the `metrics.json` file into a single directory to be served:
```bash
mkdir -p /Users/mac/a1/mithal_monitor/deploy/public
cp /Users/mac/a1/mithal_monitor/dashboard/index.html /Users/mac/a1/mithal_monitor/deploy/public/
# Note: The monitor.py script should be configured to write metrics.json to this 'public' folder.
```

## 2. Nginx Dockerfile
Create a `Dockerfile` in `/Users/mac/a1/mithal_monitor/deploy/`:
```dockerfile
FROM nginx:alpine
COPY public/ /usr/share/nginx/html/
EXPOSE 80
```

## 3. Deployment Steps
Using the `ghaymah` CLI:

```bash
cd /Users/mac/a1/mithal_monitor/deploy

# Build and Push
docker build -t registry.ghaymah.systems/my-org/mithal-dashboard:latest .
docker push registry.ghaymah.systems/my-org/mithal-dashboard:latest

# Deploy
ghaymah deploy \
  --name mithal-dashboard \
  --image registry.ghaymah.systems/my-org/mithal-dashboard:latest \
  --port 80 \
  --env production
```

The dashboard will now be accessible via the URL provided by ghaymah.systems, and it will serve `index.html` as well as `metrics.json` over HTTP(S).
ʹxVmo6_q`D}0fƒtktHJRu }Gu>ؔJ*
?֨%k-4;]˿Z`d	7h?o[LD'TAZrn]1Fen6HtS[׋7m|X-W4ըO<+ȍT#*J4*Oubk 5Le么gЕJa!X2%Bꄑ?ü1QMsFRD>YfC\h%[+ Go-6RK1
UYh*DeN~rRD6Ȇݝ	ik~/d0x5\K	1r5Shkλ\IFqؐ#V?xg 7hH2ph,5RR0~&q_$}uhLG	)pG^Ob'Y|XȢO1|x<;4u2Hʶ]DhsQ
gېZ*9}8"#+5Oz3 C2{)~.XFV<P~8> $<Urn~7pq_ۃ':QM\^־.}fc7I{i|IV{5i3Tdj	;7ntX?)'[WzGxmr`:SqO5MKX:5ADֺӋè*C9tb |#'ܐGet>dlfЎo?aNJYtD늛MB7v6/&+UcSǆHHݻZBWrPt4pՙ;#c~!$YX8ۛۛzj=,	K7

Lq34D/5%#is6rx{Ա!*PCX!
3'58cv9}\1f+ccmj4(q%$Ԧx& 100755 monitor.sh ^ڙM6:I كYexUON0+LHLdTI
LZD.UR&UnHP'g???O.x79^xEfX=7ْWV\֚&X7km?)!ȌBhn|:Ȉ#錒V;հ\w -(yVn=D@Hz-amdɞRx(~ɊȢCbK<pȏ@IUxv
MUA3arm->b
1o&)5bs"Akx) 100644 postmortem.md nJRPKV?֖{<+xmU]O#G|h,llD@],Cn;f>9>ճ\#.Fzp!Nj#WtpG_utSTh>TGV;z5_ǝ#WQ;+o/Tk"nTT]՝
T1)YQ+ôv΅SnH[R4>{^/ftJvjOg]ʞ@OL^pb<i[4\[B٨eO5ô=]Yׂ
1?{1ָTE!'FBKr#{X$ƕ+R^vP*09f8I&=]ftKg5j	!eН@͆=:+VzS\bebBliþB+Z%RX#d%\~~ɹ =/=Tn^bF+sN
8׈ԡM)\44:]qYF.{BX5+Q6A^Y}-?kjZϗ7ry3KA%+m?\NߒZJ^KQb/&G/98F@=r\T3Pt9[*:~X>|8ac<Scq?7}0UmQ`|}8y.lnntIĽc,*_2w䄂@ttqNX6^9j Z  !ƸB4u}?=?.SNEuPb׆	Y'Щtڶ>	cg@z]l%a*
3W,\xӕNU*!f=*E7	Xơ~ǕVls}x>3`\(b
^F*u۰w:/~b"˾l*;<,vRѐLƸyƻTcq";eMZ8'qWbK?ҧǓ{	9(V'%Z.l6 XZE%5	Wwʷ=ib|c_E+]󛳛Cvл\- _9Ϡx` 100644 auto_scaling_policy.md 宁.!^87P_ٰ100644 early_detection.md kӦ Z&qN^u^,&7Lx7# Auto-Scaling Policy for ghaymah.systems

To prevent repeating the OOMKilled outage, the platform's auto-scaling group (ASG) must be configured to respond to memory pressure as well as CPU load.

## 1. Scale-Out Policy (Adding Instances)
- **Metric:** Average Container Memory Utilization
- **Threshold:** > 70%
- **Evaluation Period:** 2 minutes (2 consecutive data points of 1 minute each)
- **Action:** Add 1 container instance (Step scaling) or scale by 20% of current capacity.
- **Cooldown Period:** 3 minutes (allows the new container to boot and start serving traffic before evaluating again).

## 2. Scale-In Policy (Removing Instances)
- **Metric:** Average Container Memory Utilization
- **Threshold:** < 40%
- **Evaluation Period:** 5 minutes
- **Action:** Remove 1 container instance.
- **Cooldown Period:** 5 minutes (prevents aggressive scale-in which might cause immediate resource pressure).

## 3. CPU Backup Policy
*Maintain existing CPU policies as a secondary trigger:*
- Scale out if Average CPU > 75% for 2 minutes.

## 4. Minimum / Maximum Capacity
- **Min Containers:** 2 (for high availability across zones)
- **Max Containers:** 20 (to control billing, can be adjusted based on anticipated load)
-Wxv# Early Detection of Memory Issues

Waiting for an application to crash (OOMKilled) is a reactive approach. To proactively detect memory issues, we must configure our monitoring tools (Prometheus, Datadog, or ghaymah metrics).

## 1. High-Watermark Alerting
Configure alerts on the metric `container_memory_usage_bytes` (or equivalent).

- **Warning Alert (Slack/Teams):**
  - Trigger: Container Memory > 80% of limit
  - Duration: Sustained for > 3 minutes.
  - Action: Alerts the engineering team during business hours to investigate potential memory leaks.

- **Critical Alert (PagerDuty/Phone Call):**
  - Trigger: Container Memory > 90% of limit
  - Duration: Sustained for > 2 minutes.
  - Action: Wakes up the on-call engineer to apply mitigations (e.g., manual scaling, restarting pods) before the crash happens.

## 2. Rate of Change Alerting (Anomaly Detection)
Sometimes memory doesn't hit a static threshold, but it grows unusually fast.
- Monitor the *derivative* (rate of change) of memory usage.
- If memory grows by more than 20% within 5 minutes (without a corresponding 20% spike in traffic), trigger an anomaly alert.

## 3. APM Profiling
- Integrate APM (Application Performance Monitoring) to track Garbage Collection (GC) pauses in languages like Java/Node.js, or memory footprint per request in Python/Go.
- A sudden increase in GC time is often a precursor to an OOM event.
 Jj_x
 Hmizb{{hroǿv5v