intermediate
Restarting Every Thirty-Six Hours
Read the evidence before you read the options. The signals are presented the way a dashboard would present them — nothing is labelled with the answer.
The report
The session service gets OOM-killed roughly every day and a half. It has been happening for about three weeks. Someone doubled the memory limit two weeks ago, which changed the interval from 18 hours to 36 and was declared a fix.
Session service — 7 day windowILLUSTRATIVE
| Signal | Value | What it tells you |
|---|---|---|
| Resident memory | sawtooth: 340 MB → 2.0 GB over ~36 h | Memory climbs steadily and resets only when the process restarts. |
| Heap used | tracks resident closely, 310 MB → 1.9 GB | The growth is inside the managed heap rather than outside it. |
| Request rate | 400–620 req/s, daily cycle | Traffic follows its normal daily shape with no upward trend across the week. |
| Growth during overnight trough | +38 MB/h at 60 req/s | Memory continues to climb during the quietest hours at a tenth of peak traffic. |
| GC time | 1.1% → 9.4% of wall clock as heap grows | Collector work rises as the heap gets larger. |
| p99 latency | 120 ms after restart → 480 ms before OOM | Latency degrades progressively over the life of each process. |
| Open connections | 210, stable | Connection count is flat over the whole cycle. |
Heap comparison — two snapshots 90 minutes apart, retained size delta
delta count Δ type
+214 MB +18,442 Map { string → SessionContext } (1 instance, "activeContexts")
+31 MB +18,442 SessionContext
+12 MB +18,451 Date
+2 MB +214 Socket
-1 MB -87 Buffer
─────────
requests served in window: 18,509services/session/context.ts (excerpt)
const activeContexts = new Map<string, SessionContext>()
export function beginRequest(req: Request) {
const ctx = new SessionContext(req)
activeContexts.set(req.id, ctx) // keyed by request id
return ctx
}
export function currentContext(id: string) {
return activeContexts.get(id)
}What is the constraint?