Part 9 · 2 chapters · ~12 min

The Lab

Seven deliberate pathologies in one zero-dependency service (a memory leak, a blocked event loop, N+1 queries, pool exhaustion, threadpool starvation, GC pressure and lock contention), the numbers measured on this machine, and a worksheet for diagnosing each with the course's tools.

16

Run it and break it

code
node --inspect modules/bdiag/lab/server.mjs        # http://localhost:8930, inspector on 9229
curl localhost:8930/stats                          # pool, RSS, heap, event loop delay p99
curl localhost:8930/fixes                          # the answer key (try first, read later)

routes:  /leak  /block  /n1  /pool-leak  /hash  /dns  /gc  /contention  /healthz  /stats  /fixes
THE LAB, MEASURED
numbers from running modules/bdiag/lab/server.mjs on this machine
/healthz4 ms/block (sync CPU)300 ms, and it blocks everyone/dns during 4 × /hash316 ms lookup/n1 (51 queries)1,066 ms/pool-leak after 8 callspool 5/5 in use: next callers hang
swipe the figure sideways, or tap expand for full screen
1/5
baseline
A health check returns in about 4 ms: the process and the network are fine.
healthy baseline: 4 mscurl -w %{time_total}
17

Worksheet

routesymptom to reproducetool to useevidence you should see
/leakRSS grows 1 MB per callthree heap snapshots (Node part 1)Buffers retained by a module-level array
/blockall routes slow while it runs--cpu-prof, ELU, event loop delaya wide frame in the route handler
/n11 s responses with idle CPUtraces (or log query counts)51 sequential query spans
/pool-leakafter errors, everything hangs/stats pool metrics, a heap snapshot of waitersinUse = size, waiting grows
/hash then /dnsunrelated route slowtiming of dns.lookup, UV_THREADPOOL_SIZE experimentlookup time drops with a bigger pool
/gcCPU high, many short pauses--trace-gcfrequent scavenges per request
/contentionlatency rises with concurrency, CPU flatload test at increasing concurrencyp99 ≈ 50 ms × queue depth