Skip to content
All writing Part 07 of 11 · From 19 Goroutines to Exit 137
Engineering · 4 min read

Shared Resource Blast Radius: When One Dies, Everyone Dies

Centralization saves resources but concentrates risk. When one shared browser dies, every in-flight request dies with it. The bulkhead was removed.

Centralization saves resources but concentrates risk. The wall you need to add back is called a semaphore.

Blast Radius Flips

BEFORE per-request (isolated browser) req1 req2 req3 Browser₁ Browser₂ Browser₃ AFTER shared (one browser) req1 req2 req3 1 Browser blast radius: 1 request blast radius: ALL in-flight dies → req1 only → OOM exit 137 ALL fail

Backpressure Doesn’t Cross Process Boundaries Automatically

Go runtime G1 G2 ... G19 scheduler sees backpressure ✗ Browser 2Gi ceiling invisible Process boundary HTTP fix: semaphore + 429 HERE (at boundary)
  • An in-process scheduler only sees resources inside its own process. An out-of-process bottleneck is invisible: no automatic backpressure (GMP scheduler, GOMAXPROCS).
  • Bulkhead pattern = deliberately partition capacity so one compartment can’t sink the rest. A shared pool is the anti-bulkhead (it removes the isolation that kept failures contained).
  • Rule: when you centralize for efficiency, add back the cap that per-request isolation gave you for free.

Fan-In Math

per-pod cap = 6 Pod₁ (cap 6) Pod₂ (cap 6) Pod₃ (cap 6) shared proxy (1 replica) max load = 6 × 3 = 18

A per-pod cap only bounds the local sidecar. If the downstream is a shared singleton, N replicas’ caps sum to the actual load. Bound a shared resource with: global limiter (Redis / Envoy), per-replica resource (sidecar), or pull-based queue (busy worker stops pulling).

Role in This OOM

Switching from per-request browser to shared browser saved startup cost, but the blast radius flipped from “one request” to “all in-flight requests.” The Go runtime didn’t know the browser was nearing its limit; no backpressure, goroutines kept opening tabs. Fix: semaphore + 429 at the Go side (the process boundary) (load shedding with TryAcquire).

A shared resource without a cap means the whole system has no cap.

References:

Related: see load shedding with TryAcquire, keep-alive pins retries, and the wrong fix, or go back to the series overview.

Tags #go #concurrency #reliability
// connect

Be brave | Be wise | Be grateful

21 BreakinCode

// elsewhere
LinkedInMedium (lang: en)Life RecordYoutube
wh:~$William Hung· © 2026 Taipei · GMT+8 · Available for collaboration