Course contents

Availability and the nines

Availability and the nines for system design interviews: turn 99.9% or 99.99% into minutes of downtime, compute availability for serial chains and redundant replicas, spot correlated failures, pick a target per user journey and stay up through a zone loss with static stability.

FreeMust know for interviewsLesson12 min readBeginner → SeniorReviewed Oct 2026
On this page
  1. Picture it first: nines are a downtime budget
  2. Under the hood: serial and parallel math
  3. Where the math lies: independence
  4. Pick a target on purpose
  5. Static stability: stay up without doing anything
  6. How it shows up in design problems
  7. How to say it in the interview

🟢 What is availability?

Availability is the share of the time, or the share of requests, in which your system does its job when someone asks. It's usually written as a percentage with a lot of nines: 99.9% ("three nines") means the service may be unusable for about 8.76 hours a year. Think of a shop: availability is whether the door is open when a customer walks up, not whether the shelves are perfectly stocked.

For this lesson, we'll turn nines into minutes, do the two pieces of math every design round needs (boxes in a chain, boxes side by side), and look at the assumption that quietly breaks that math. Then we'll pick a target on purpose and keep it when a zone disappears. Interviewers like this topic because "highly available" is the most hand-waved phrase in system design, and a candidate who says "99.95% for writes, here's the chain, here's what degrades" stands out in under a minute.

Below the line (out of scope)

The 30-second answer

Availability is uptime as a ratio: good time over total time, or successful requests over valid requests. Each extra nine cuts the allowed downtime by ten: 99.9% is about 8.8 hours a year, 99.99% about 53 minutes. Boxes in series multiply, so a chain is always less available than its weakest link. Redundant boxes in parallel fail only if all of them fail, so two independent 99.9% replicas give about 99.9999%, but only if their failures really are independent. I pick a target per user journey rather than 100%, spread replicas across zones with spare capacity already running, and decide up front what degrades instead of failing.

What you’ll learn

  • Convert any number of nines into downtime per year, month and day with (1 - A) x period
  • Compute availability for a serial chain (multiply) and redundant replicas (1 - (1 - A)^n)
  • Explain why the parallel math depends on independent failures, and name what makes replicas fail together
  • Pick an availability target per user journey instead of chasing 100%
  • Describe static stability: spare capacity across zones so losing one needs no action

01Picture it first: nines are a downtime budget

A percentage feels abstract. Minutes don't. Here's the table I keep in my head, computed with a 365-day year (525,600 minutes), a 30-day month (43,200 minutes) and a 24-hour day.

Availability Down per year Down per 30-day month Down per day
99% ("two nines") 3.65 days (87.6 h) 7.2 hours 14.4 minutes
99.5% 1.83 days (43.8 h) 3.6 hours 7.2 minutes
99.9% ("three nines") 8.76 hours 43.2 minutes 86.4 seconds
99.95% 4.38 hours 21.6 minutes 43.2 seconds
99.99% ("four nines") 52.56 minutes 4.32 minutes 8.64 seconds
99.999% ("five nines") 5.26 minutes 25.9 seconds 0.86 seconds

The rule behind every row is one multiplication: downtime = (1 - availability) x period. For 99.99% over a year that's 0.0001 x 525,600 minutes = 52.56 minutes. The yearly column matches the availability table in Google's SRE book, which is the one to quote if anyone asks where your numbers come from.

Two things to notice. Each extra nine is ten times less downtime, and usually far more than ten times the effort. And at four nines the daily budget is 8.6 seconds: no human can respond that fast, so detection and repair have to be automated.

There are two ways to count:

  • Time-based: minutes up divided by total minutes. Easy to explain, but crude for a service that's half broken.
  • Request-based: successful requests divided by valid requests. Google's SRE book prefers this for global services, because they're almost never fully up or fully down. Its example: a service handling 2.5 million requests a day with a 99.99% daily target can fail up to 250 of them.

I default to request-based in interviews, because it handles partial outages naturally.

02Under the hood: serial and parallel math

Almost every availability question reduces to two rules.

Serial (hard dependencies) multiply. If a request needs the load balancer AND the app AND the database, all three must be up, so you multiply their availabilities. AWS's reliability pillar uses this exact example: a 99.99% service with hard dependencies on two other 99.99% services can reach about 99.97%.

Parallel (redundant copies) multiply the failures. If either of two replicas will do, the tier is down only when both are down at once. So you multiply the unavailabilities and subtract from one: availability = 1 - (1 - a)^n. Two independent 99.9% replicas: 1 - (0.001 x 0.001) = 99.9999%.

Try it yourself first

Before reading on, try it. A request goes through a load balancer (99.99%), one app server (99.9%) and one database (99.95%). What's the end-to-end availability, and roughly how many hours of downtime a year is that? Then add a second app server in parallel. How much do you gain, and which box should you fix next?

Here's the worked version, all on a 365-day year:

Design Math Availability Down per year
One of each 0.9999 x 0.999 x 0.9995 ≈ 99.84% ≈ 14 hours
Two app servers 0.9999 x (1 - 0.001²) x 0.9995 ≈ 99.94% ≈ 5.3 hours
Two app servers, DB with standby 0.9999 x (1 - 0.001²) x (1 - 0.0005²) ≈ 99.99% ≈ 53 minutes
Fig. 1

Serial boxes multiply, parallel boxes protect each other

Serial boxes multiply, parallel boxes protect each otherTop row: users reach a load balancer at 99.99%, one app server at 99.9% and one database at 99.95% in series. Multiplied together that is about 99.84%, roughly 14 hours of downtime a year. Bottom row: the same chain with two app servers in parallel. The app tier becomes 99.9999% and the whole chain about 99.94%, roughly 5.3 hours a year, and the database is now the weakest link.Serial: one of each, all must be upParallel app tier: either server will doUsersLoad balancer99.99%App server99.9%Database99.95%UsersLoad balancer99.99%App server AApp server BDatabase99.95%0.9999 x 0.999 x 0.9995 ≈ 99.84% · about 14 hours down a yearnow the weakest linkApp pair: 1 - (0.001 x 0.001) = 99.9999% · chain ≈ 99.94%, about 5.3 hours a year
Redundancy only helps where you add it. Doubling the app tier lifts the chain from about 14 hours to about 5.3 hours down a year, and the database becomes the weakest link.

Notice three things.

  • The chain is always below its weakest link. 99.84% is worse than every single box in it.
  • Redundancy pays where the failures are. Doubling the app tier removed most of its contribution, and the database now owns most of the remaining downtime. Fix the next weakest link, not the one you already fixed.
  • Small numbers compound. Ten hard dependencies at 99.99% each come to about 99.90%. That's how a microservice graph of individually "four nines" services ends up at three.
The shortcut

When every component is all nines, parallel copies add their nines: two independent three-nines replicas give six nines. AWS's reliability pillar gives the same shortcut. It's handy on a whiteboard, as long as you say "if they fail independently" out loud.

03Where the math lies: independence

That last row says 99.99%, and I'd still not promise it. The parallel formula assumes the replicas fail independently and that switching between them is instant. Neither is free.

Things that make replicas fail together:

  • Shared infrastructure. Same rack, same power feed, same zone, same region. That's why cloud zones are built not to share power and are physically separated.
  • Shared change. A bad config push or deploy goes to every replica within minutes. Redundant boxes running the same broken config are one box.
  • Shared dependency. Both app servers call one auth service, one secrets store, one DNS provider. Your redundancy ends at their availability.
  • The same bug. A poison request or a leap-second edge case crashes every replica that sees it.

And switching isn't instant. A database standby that takes two minutes to promote costs you two minutes every time the primary dies. At 99.99% (52.56 minutes a year) you can afford about 26 of those; at 99.999% (5.26 minutes), two. We cover realistic switch times in Failover.

Where candidates slip

Many candidates multiply nines across replicas and announce "six nines" without asking what the replicas share. Interviewers hear that as textbook recall. The stronger answer is "two replicas in separate zones, so the math says about six nines for that tier, but in practice a shared config push or a slow failover will dominate, so I'll plan around those." Two other traps: excluding planned maintenance from downtime (AWS advises against it, because users don't stop clicking during your window), and calling a system available when it's answering quickly with wrong data. That's a reliability failure, and it's worse.

04Pick a target on purpose

The tempting target is 100%. It's the wrong one, for two reasons from Google's SRE book. Past a point users can't tell the difference, because their own phone and network fail more often than your service. And each extra nine can cost far more than the last, in hardware, slower releases and engineers working on risk instead of features.

The book also shows how to price a nine. For a service earning $1M, moving from 99.9% to 99.99% recovers 0.09% of revenue, about $900. If that extra nine costs more than $900 to build and run, it isn't worth it. That's the shape of argument I want to hear.

So I set targets per user journey, not per system:

Journey Target I'd propose Why
Read a product page or feed 99.99% High traffic, and a stale cached copy still counts as "up"
Place an order or pay 99.95% Must be correct first; a short "try again" is better than a double charge
Admin dashboard, reports 99.9% Internal users, can wait
Nightly batch job 99% Can rerun; measure by records processed

These are a starting proposal, not industry constants. AWS's reliability pillar has a similar table that pairs 99.95% with online commerce and 99.99% with video delivery. Once you've set a target, the gap between it and 100% is your error budget; how teams spend and alert on it lives in Reliability.

05Static stability: stay up without doing anything

The usual plan for losing a zone is reactive: "auto scaling will launch replacements in the other zones." Amazon's Builders' Library calls this out as the weaker pattern, because recovery now depends on the control plane (launching instances, fetching config, registering with discovery) at the exact moment things are already broken.

The alternative is static stability: run enough spare capacity, all the time, that losing a zone needs no action at all. Amazon describes running stateless fleets across three zones overprovisioned by 50%, so each zone normally runs at about 66% of the load it was tested for. When one zone drops, the load balancer's health checks steer traffic to the other two, which absorb it without launching anything.

Fig. 2

Static stability: spare capacity is already running

Static stability: spare capacity is already runningUsers reach a load balancer that spreads traffic over three availability zones. Zone C is impaired and crossed out. Zones A and B each normally run at about 66% of the load they were tested for, so when zone C drops out they absorb its share and run at 100% without launching any new servers.Zone AZone BZone Cno trafficUsersLoad balancerhealth checks drop zone CApp serversnormal: ~66% busynow: 100% of testedApp serversnormal: ~66% busynow: 100% of testedApp serverszone impairedhealth checks failNothing is launched during the outage: the spare 50% was already running
The spare capacity is already running. With three zones at about 66% load, losing one pushes the other two to 100% of tested capacity, and the recovery path needs no new servers.
In the real world

In Static stability using Availability Zones, Amazon explains that the EC2 data plane keeps routing packets even when the control plane that launches instances is impaired: running hosts keep what they need locally, so they miss updates but keep working. For stateful systems the same idea means the database standby is already running in another zone, so failover promotes it instead of building a new one.

The arithmetic is worth knowing: with three zones you need 1.5x your peak capacity; with two zones each must carry the whole load, so you need 2x. That's a strong argument for three zones over two.

Static stability pairs with graceful degradation: when a non-critical dependency fails, serve something smaller instead of an error. Recommendations go blank, the feed shows cached posts, search falls back to popular items. The checkout path stays up. That's how a request-based availability number stays high during a partial outage. See Fault tolerance and the fallback pattern for the techniques.

Numbers to keep in your pocket
  • Downtime = (1 - availability) x period. A year is 525,600 minutes, a 30-day month 43,200.
  • 99.9% ≈ 8.8 h/yr · 99.95% ≈ 4.4 h/yr · 99.99% ≈ 53 min/yr · 99.999% ≈ 5 min/yr.
  • Three 99.9% hops in series ≈ 99.7%. Two 99.9% replicas in parallel ≈ 99.9999% (if independent).
  • Three zones with static stability: 1.5x capacity. Two zones: 2x.

06How it shows up in design problems

Availability shows up as a non-functional requirement in almost every round. Name a number per path and show where it comes from.

  • Design a payment system: writes favour correctness over uptime, so a payment can return "pending" and finish later rather than risk a double charge. This is where CAP and idempotent retries meet the nines.
  • Design a notification system: the accept path must be very available, so you put a durable queue in front and let delivery lag behind during an outage.
  • Design a key-value store: replicas across zones and quorum reads and writes; the availability question becomes "how many replicas can die before reads or writes stop?"
  • Design a URL shortener: redirects are read-heavy and cacheable, so the read path can target four nines even if creating links targets three.

For region-level planning, backups and recovery objectives, go to Disaster recovery. For how health checks actually notice a dead node, see Heartbeats and the health checks pattern.

07How to say it in the interview

When I ask "how available does this need to be?", I'm listening for three things: a number per path instead of one number for everything, a dependency chain with the weak link named, and a story for what degrades instead of failing. Bonus points for mentioning correlated failure without being prompted.

In the interview

"I'd target 99.99% for reads and 99.95% for writes. That's about 53 minutes and 4.4 hours of downtime a year. Reads can be served from cache and replicas, so they're easier to keep up; writes go through a single primary, and I'd rather fail a write briefly than lose or duplicate it. The read path is load balancer, stateless app tier and cache, all hard dependencies, so they multiply, and the database is my weakest link. The app tier runs across three zones with about 50% headroom, so losing a zone needs no new servers. The primary has a synchronous standby in another zone, and a failover of a minute or two fits easily inside a 4.4-hour yearly write budget. The math assumes independent failures, so I'd also stage config pushes and deploys zone by zone. If recommendations or search are down, the page still loads without them."

On the whiteboard

  • downtime = (1 - A) x period · year = 525,600 min
  • 99.9 ≈ 8.8 h · 99.95 ≈ 4.4 h · 99.99 ≈ 53 min · 99.999 ≈ 5 min (per year)
  • serial: A1 x A2 x A3 (always < weakest)
  • parallel: 1 - (1 - A)^n (only if independent)
  • correlated: zone, config push, deploy, shared dep, same bug
  • target per journey, never 100%
  • static stability: 3 zones x 66% load = survive 1 zone, no launches
  • degrade non-critical features instead of failing the page
Further reading (4)