Notes
Cascading failure
Watch a cascading failure. The recommendations service gets slow, answering in thirty seconds. The product service's threads each wait for it, until all two hundred are stuck. Now it can't serve any request at all, even ones that never needed recommendations, and its own callers start piling up. A slow dependency is worse than a dead one.
- recommendations responds in 30 s
- product service threads wait
- for it, one by one
- 200 threads, all stuck waiting
- → no thread left for ANY request
- → product page down
- → callers of product pile up too
- slow is worse than dead
Timeouts
Rule one: every network call needs a timeout, and many client libraries default to none. Set it a bit above the dependency's p ninety-nine: if it normally answers within a hundred and twenty milliseconds, give up after two hundred. Better still, pass a deadline along, so downstream calls know how much time is left. Retries stay few, with backoff and jitter.
- no timeout = infinite wait
- (many clients default to none!)
- set from the dependency's p99:
- p99 120 ms → timeout ~200 ms
- deadline propagation:
- request has 1 s total; pass the
- remaining time downstream
- retries: few, backoff + jitter
Circuit breaker
A circuit breaker sits around a dependency. While closed, calls pass and failures are counted. When too many fail, it opens: calls fail instantly without even trying, giving the sick service room to recover and freeing your threads. After a pause it goes half-open and lets a few test calls through. If they succeed, it closes again.
- CLOSED: calls go through,
- failures are counted
- 50% failing → OPEN:
- fail fast, no calls at all,
- for 30 seconds
- HALF-OPEN: let a few test
- calls through
- succeed → CLOSED
- fail → OPEN again
Fallbacks
When a call fails or the breaker is open, return something useful. Recommendations down? Show cached popular items. Reviews slow? Load them after the page. But pricing is essential: without a price you can't sell, so that one fails clearly. Decide in advance which features are optional and what each one falls back to.
- recommendations down →
- show "popular items" (cached)
- reviews slow → load them later
- pricing down → can't sell:
- this one must fail clearly
- decide in advance which
- features are optional and
- what each falls back to
Bulkheads
Bulkheads come from ships, which are split into compartments so one leak doesn't sink everything. Give each dependency its own thread or connection pool: fifty for pricing, fifty for inventory, twenty for recommendations. Now a slow recommendations service can only exhaust its own twenty threads, and the rest of the page keeps working.
- ships have compartments so one
- leak does not sink the ship
- separate thread / connection
- pools per dependency:
- pricing: 50 threads
- inventory: 50 threads
- recommendations: 20 threads
- slow recs can only exhaust
- its own 20
Overload
When overloaded, shed load: reject excess requests quickly with a four twenty-nine or five oh three and a retry-after, starting with low-priority work. Inside the system, use backpressure: bounded queues, so when a consumer falls behind, producers are slowed or told no instead of filling memory until everything crashes. Serving eighty percent beats serving nobody.
- overloaded? reject early:
- 429 / 503 with Retry-After
- drop low-priority work first
- backpressure: a slow consumer
- tells producers to slow down
- bounded queues, not infinite
- queue full → producer waits
- or is told no
- serving 80% beats serving 0%
Chaos testing
None of this counts until it's tested. Chaos engineering means breaking things on purpose, carefully: kill instances, inject latency, take away a whole zone, and watch whether timeouts, breakers and fallbacks really work. Practise incidents in game days, and load-test above your expected peak.
- chaos engineering: kill pods,
- add latency, drop a zone,
- on purpose, in a controlled way
- game days: practise incidents
- load tests above peak
- find the cascade before
- your users do
Say it like this
In an interview, for every dependency ask: what if it's slow or down? Then answer with timeouts based on p ninety-nine and propagated deadlines, a few idempotent retries with backoff and jitter, a circuit breaker per dependency, bulkhead pools, a cached or partial fallback, and load shedding with bounded queues.
- "What if X is slow or down?"
- timeouts from p99 + deadlines
- retries: few, backoff, jitter,
- idempotent
- circuit breaker per dependency
- bulkhead pools
- fallback: cached / partial data
- load shedding + bounded queues