Availability, Reliability and Fault Tolerance
Three words that get used interchangeably and mean different things. The nines table, the MTBF and MTTR formula, and why two components in series are less available than either one alone.
Concept
These three terms describe different properties, and mixing them up produces designs that miss their goal.
| Term | Question it answers | Measured as |
|---|---|---|
| Availability | Is the system usable right now? | Percentage of time it is usable |
| Reliability | Does it keep working correctly over time, without failing? | Time between failures, failure rate |
| Fault tolerance | Does it keep serving while a component is broken? | Which failures it survives with no loss of service |
A system can be highly available and unreliable: it fails often but recovers in seconds. It can be reliable but not fault tolerant: it rarely fails, and when it does, everything stops.
Availability, in numbers
A year is 8,760 hours, or 525,600 minutes. Availability targets are quoted as nines, and the allowed downtime falls fast.
| Target | Name | Downtime per year | Downtime per 30 day month |
|---|---|---|---|
| 99% | two nines | 3 days 15.6 hours | 7 hours 12 minutes |
| 99.9% | three nines | 8 hours 45.6 minutes | 43.2 minutes |
| 99.95% | 4 hours 22.8 minutes | 21.6 minutes | |
| 99.99% | four nines | 52.6 minutes | 4.32 minutes |
| 99.999% | five nines | 5.26 minutes | 25.9 seconds |
Four nines means your total budget for planned maintenance, failed deployments, provider incidents and human error is under an hour for the whole year. Every extra nine costs roughly an order of magnitude more effort.
The formula
Availability = MTBF / (MTBF + MTTR)
MTBF Mean Time Between Failures - how long it runs before breaking
MTTR Mean Time To Recovery - how long it takes to become usable again
Example: MTBF = 1000 hours, MTTR = 1 hour
1000 / 1001 = 0.999001 = 99.9 per cent
Cut MTTR to 6 minutes (0.1 h):
1000 / 1000.1 = 0.99990 = 99.99 per centRead that twice. Availability improved by a factor of ten without making anything fail less often. Recovering faster is usually cheaper than failing less. That is why automated restarts, health checks and rollbacks matter more than heroic hardware.
Combining components
IN SERIES - every part must work (a chain)
A 99.9% -> B 99.9% -> C 99.9%
0.999 x 0.999 x 0.999 = 0.997 = 99.7 per cent
More dependencies always means LESS available.
IN PARALLEL - any one part is enough (redundancy)
two independent components, each 99.9 per cent
failure requires both: 0.001 x 0.001 = 0.000001
availability = 99.9999 per cent
Redundancy multiplies the failure probability down.Two rules follow, and they explain most architecture decisions in this path: every extra dependency lowers availability, and redundancy only helps if the copies fail independently. Two servers in the same rack sharing one power feed are not independent.
Important terminology
| Term | Meaning |
|---|---|
| Single point of failure | A component whose failure stops the whole system. |
| Redundancy | More than one of something, so one can fail. |
| Failover | Switching to a standby when the primary fails. |
| Graceful degradation | Losing a feature instead of the whole service - showing cached prices when the pricing service is down. |
| Blast radius | How much is affected when one thing breaks. |
| Health check | An automated test that decides whether an instance should receive traffic. |
| Error budget | The downtime a target permits. At 99.9 per cent you may spend 43 minutes a month. |
Real world example
An online store has a web tier, an application tier and a database, each independently 99.9 per cent available. In series that is 99.7 per cent - about 26 hours of downtime a year, which nobody agreed to.
Two changes fix it without buying better hardware:
- Run two instances of the web and application tiers behind a load balancer with health checks, so a failed instance is removed automatically. Those tiers become effectively far more available.
- Give the database a standby in a second location with automatic failover, cutting its MTTR from an hour of manual work to under two minutes.
The parts still fail at the same rate. The system stopped noticing.
Commands
# How long has this machine been up, and what is the load
uptime
# When did it last boot, and list previous boots
who -b
last reboot | head -5
# Has a service been restarting? Look at its state and restart count
systemctl status YOUR_SERVICE
systemctl show YOUR_SERVICE --property=NRestarts
# Kernel and service messages around a failure, newest last
journalctl -u YOUR_SERVICE --since "-1 hour" --no-pager
# Simple external check: response code and total time, repeated
for i in 1 2 3 4 5; do curl -s -o /dev/null -w "%{http_code} %{time_total}s " https://YOUR_DOMAIN; doneCommand options worth knowing
| Option | Effect |
|---|---|
journalctl --since "-1 hour" | Only the last hour, which is usually all you need during an incident. |
journalctl --no-pager | Prints straight out instead of opening a pager - essential in scripts. |
systemctl show --property=NRestarts | Reveals a service that is crash looping while appearing active. |
last reboot | Shows unplanned reboots you were never told about. |
Hands on lab
- Calculate the monthly downtime budget for 99.9 per cent. Then for 99.99 per cent.
- A service has MTBF of 500 hours and MTTR of 2 hours. Calculate its availability.
- Now recalculate with MTTR reduced to 5 minutes. State the improvement.
- A request path crosses four components, each 99.95 per cent available and independent. Calculate the end to end availability.
- On a machine you own, run
systemctl statusagainst a service and checkNRestarts. A non zero value that keeps rising is a crash loop hiding behind an active label.
Expected output
1. 99.9% -> 43.2 minutes per 30 day month
99.99% -> 4.32 minutes per 30 day month
2. 500 / (500 + 2) = 0.99602 = 99.60 per cent
3. 500 / (500 + 0.0833) = 0.99983 = 99.98 per cent
Same failure rate. Recovery time did all the work.
4. 0.9995 ^ 4 = 0.998 = 99.80 per cent
Four "very good" components in series are worse than any one of them.
$ systemctl show nginx --property=NRestarts
NRestarts=0Common mistakes
- Quoting a nines figure with no measurement behind it. If you are not measuring, you do not know your availability.
- Adding redundancy that shares a dependency. Two instances in the same zone, or two paths through one gateway, fail together.
- Chasing MTBF and ignoring MTTR. Faster recovery is nearly always the cheaper nine.
- Health checks that only prove the process is running. A check that returns 200 while the database is unreachable keeps a broken instance in service.
- Forgetting that dependencies subtract. Every external call you add lowers the ceiling of what you can promise.
Troubleshooting
| Problem | Possible causes | Commands to diagnose | Fix | Prevention |
|---|---|---|---|---|
| Brief outages nobody can explain | Crash looping service; instance failing health checks intermittently | systemctl show --property=NRestarts, journalctl -u, load balancer target health history | Fix the crash cause; correct the health check | Alert on restart count, not just on process state |
| Failover did not happen | Standby unhealthy; automatic failover never enabled | Check standby status and replication lag | Repair the standby and enable automatic failover | Test failover on a schedule, not during an incident |
| Availability worse than each component | Long serial dependency chain | Draw the request path and multiply the figures | Remove dependencies, add caching, degrade gracefully | Review the dependency count in design review |
Security considerations
- Availability is a security property. A denial of service attack is an availability attack, so rate limiting and capacity limits are security controls.
- Health check endpoints must not leak internal detail such as versions, hostnames or connection strings.
- Recovery automation runs with real permissions. Scope those permissions tightly, because anything that can rebuild your system can also destroy it.
Best practices
- Agree a target first, then design to it. Do not design and then claim a number.
- Attack MTTR before MTBF: automated restarts, fast rollback, tested runbooks.
- Remove single points of failure one at a time, starting with the one in the path of every request.
- Make health checks test the dependency the request actually needs.
- Measure availability from where the user is, not from inside your own network.
Interview questions
- Define availability, reliability and fault tolerance, and give an example that has one but not the others.
- Write the availability formula and explain why reducing MTTR is usually cheaper than increasing MTBF.
- Three components at 99.9 per cent in series - what is the end to end availability, and why?
- How much downtime per month does 99.99 per cent allow?
- Give an example of redundancy that does not actually improve availability.
Mini assignment
Draw the request path of any application you know, listing every component a request touches. Assign each a plausible availability figure, multiply them, and state the result. Then identify the single change that would most improve the number, and say whether it works by raising MTBF or lowering MTTR.
Conclusion
Availability is time based, reliability is failure based, fault tolerance is about surviving a break while it is happening. Dependencies in series subtract, independent redundancy multiplies the failure away, and cutting recovery time is the cheapest nine you will ever buy.