A single point of failure (SPOF) is a part of the system that, if it fails, stops or badly disrupts everything — because nothing takes over. Finding SPOFs is the fastest way to improve a design.
flowchart LR U["Users"] --> DNS["DNS"] DNS --> LB["One load balancer"] LB --> A1["App 1"] LB --> A2["App 2"] A1 --> DB["One database"] A2 --> DB %% step U: Every request follows the same path through the system. %% step DNS: Managed DNS is usually highly available; self-hosted DNS on one server is a SPOF. %% step LB: One load balancer instance is a SPOF even if the apps behind it are redundant. %% step A1: Two app instances behind the balancer: one can fail and traffic continues. %% step DB: A single database instance is the classic SPOF — every request depends on it.
Typical SPOFs
| Layer | SPOF | Fix |
|---|---|---|
| Network | One NAT gateway, one VPN tunnel, one zone | One per zone, two tunnels, multi-AZ |
| Compute | One VM or a Deployment with replicas: 1 |
2+ replicas spread across nodes and zones |
| Data | One database instance, one Redis | Replicas with automatic failover |
| People/process | Only one person can deploy | Runbooks, automation, shared access |
| Dependencies | One payment provider, one CDN | Fallback provider, multi-CDN |
Availability math
| Availability | Downtime per year | Per month |
|---|---|---|
| 99% | 3.65 days | 7.3 hours |
| 99.9% | 8.8 hours | 43.8 minutes |
| 99.99% | 52.6 minutes | 4.4 minutes |
In series (A needs B): multiply. LB 99.99% × app 99.9% × DB 99.9% ≈ 99.79% — the chain is weaker than its weakest link.
In parallel (either one is enough): 1 − (1 − a)². Two app instances at 99% each → 1 − 0.01² = 99.99%.
Redundancy only helps if the copies fail independently: two pods on the same node, or two VMs in the same zone, can fail together.
Spreading replicas
In Kubernetes, more replicas are not enough if they land on one node. Use topologySpreadConstraints or pod anti-affinity across nodes and zones, and a PodDisruptionBudget so maintenance never drains them all at once.
Traps: redundant apps behind a single database; two copies in one failure domain; counting a managed service as "100%" without reading its SLA; forgetting that each extra serial dependency lowers availability.