8 · Reliability & observability · Designing for failure
Designing for failure
- Timeouts
- Every network call needs one. No timeout = threads pile up = cascading failure.
- Retries with exponential backoff + jitter
- Retry transient errors, but spread retries out so you don't DDoS a recovering service. Only retry idempotent ops.
- Circuit breaker
- After N failures, stop calling the dependency for a while and fail fast/fallback.
- Bulkhead
- Isolate resources (pools per dependency) so one slow dependency can't exhaust everything.
- Graceful degradation
- Show a cached/simplified page instead of an error (e.g. hide recommendations).
- Multi-AZ / multi-region
- AZs protect against a datacenter loss; regions against a regional outage — at a big complexity cost.