Fundamentals
Composing availability
A request that needs every dependency multiplies their availabilities, which lowers the ceiling. Redundancy adds nines only when the replicas fail independently.
No request touches just one component. A checkout calls auth, inventory, pricing and payments. How their availabilities combine depends on one question. Does the request need all of the components, or just one of several copies of a component?
Concept
Before you start, read nines and downtime. Availability is a fraction between 0 and 1, so 99.9% is 0.999. Two rules cover most cases. Series means every part must work, so you multiply. Parallel means one working copy is enough, so failure needs every copy to fail.
The big idea
Every hard dependency lowers your ceiling. A service can't be more available than the product of the things it can't live without. If you call five services that are each 99.9% available, your result is worse than any one of them.
Redundancy in parallel works in the opposite direction. Two replicas that are each 99% available together fail only when both fail. The catch is the word independent. Replicas on one rack, running one bad config, or depending on one DNS provider fail together. Correlated failures are why real systems spread replicas across zones and stagger deploys.
Walking through it
Series. Checkout is 99.95% on its own. It calls five dependencies, each at 99.9%: auth, inventory, pricing, payments and a fraud check.
0.999^5 = 0.99501
× 0.9995 (itself) = 0.99451 → 99.45%
Downtime: (1 − 0.99451) × 43,200 min ≈ 237 min ≈ 4 hours per monthEach piece looks like three nines. The result is barely above two.
Improving it. You have three levers. The first is the cheapest.
- Make dependencies soft. If pricing, fraud and inventory can degrade, only auth and payments stay hard:
0.999^2 × 0.9995 = 0.9975, or 99.75%, about 1.8 hours down per month. - Add redundancy to the weakest hard dependency, such as a second payment processor you can fail over to.
- Raise each dependency's availability. This is usually the most expensive option, and often outside your control.
Parallel. If a request succeeds when any one of n independent replicas works, failure needs all of them down:
A_total = 1 − (1 − A)^n
Two independent replicas at 99%:
1 − (0.01)^2 = 1 − 0.0001 = 99.99%Common mistakes
- Counting only your own service. Your availability is capped by its hard dependencies. Count them.
- Assuming replicas are independent. The 99.99% result needs failures that don't overlap. Shared racks, configs and DNS break that.
- Making every dependency hard. If a recommendation call can be skipped, it shouldn't drag your availability down.
Check yourself
- Why do five 99.9% dependencies in series give about 99.5%? Multiplying: 0.999 to the fifth power is about 0.995.
- Two 99% replicas share one rack and one config. Is the answer 99.99%? No. The math assumes independence, and shared failures break it.
Key takeaways
- Series dependencies multiply. Every hard dependency lowers your ceiling.
- Parallel replicas improve availability, but only when their failures are independent.
- Make non-critical calls soft, so they can't take the request down.
Further learning
The resilience patterns page covers how to keep hard dependencies from failing together.
Next, read about tail latency amplification, which applies the same multiplication to response times.
Related
Nines and downtime
Availability is the share of time or requests that work. Each extra nine cuts allowed downtime tenfold, and the last few nines need automation, not heroics.
Resilience patterns
The toolkit for keeping one failure from becoming an outage, from timeouts and retries to circuit breakers, bulkheads, load shedding and cells. Start here for the resilience map.
Availability, latency and the tail
Nines, percentiles and the math of composing services. Why p99 matters more than the average, how fan-out amplifies the tail, and how to design for both uptime and speed.