1. Library
  2. Performance and Reliability
  3. High Availability

Updated 1 day ago

Every component in your system will eventually fail. Servers crash. Networks partition. Data centers lose power. Disks corrupt. Software has bugs that only manifest under specific conditions you've never tested.

High availability design starts with accepting this. Not fighting it, not hoping it won't happen—accepting it as the baseline reality and building systems that survive it.

The Fundamental Question

Traditional engineering asks "how do we prevent this from breaking?"

High availability engineering asks "what happens when this breaks?"

That single question changes everything you build. When you assume failure is inevitable, you stop trying to build components that never fail—an impossible goal—and start building systems that continue functioning when components fail.

Eliminating Single Points of Failure

A single point of failure (SPOF) is any component whose failure kills the entire system. High availability design systematically hunts and eliminates them.

One database server? SPOF. Add replication with automatic failover.

All servers in one data center? The data center is a SPOF. Distribute across availability zones.

One load balancer routing all traffic? SPOF. Deploy redundant load balancers.

The process is methodical: map every component, identify which ones are unique rather than redundant, and add redundancy to critical paths. Every "the" in your architecture description is suspicious. "The database." "The cache." "The message queue." Each suggests a SPOF waiting to cause an outage.

Detecting Failures Fast

You can't recover from failures you don't know about. Every second of detection delay is a second of recovery delay.

Health checks actively probe services to verify they're functioning—not just that processes are running, but that they can actually do their job. A database process might be running but unable to process queries. Health checks should verify actual capability.

Heartbeat monitoring has services regularly signal they're alive. Missing heartbeats indicate failure.

Anomaly detection identifies unusual behavior that suggests impending failure: CPU pinned at 100%, memory steadily climbing, response times gradually increasing. These are warnings before the crash.

The goal is detection in seconds, not minutes. A system that takes five minutes to detect failures and five minutes to recover has ten minutes of downtime per incident. A system that detects in five seconds and recovers in thirty has under a minute.

Recovering Automatically

Manual recovery is too slow. Humans take minutes to wake up, minutes to understand what's wrong, minutes to fix it. Automated systems recover in seconds.

Automatic failover switches to redundant components when primaries fail—no human intervention required.

Auto-scaling adds capacity when load increases or failures reduce available capacity.

Self-healing automatically restarts failed processes, replaces failed instances, and reroutes around failures.

Automation doesn't eliminate humans—complex failures still require judgment. But it handles routine failures without waking someone at 3 AM.

Degrading Gracefully

Not every failure requires complete unavailability. Systems can often keep running with reduced functionality.

Recommendation engine fails? Show popular items instead of personalized ones. Analytics service down? Log events for later processing. Image uploads broken? Accept text-only posts.

The key is distinguishing core functionality (must never fail) from enhanced functionality (can temporarily fail without breaking the experience).

Circuit breakers prevent cascading failures. When a downstream service fails, instead of waiting for timeout after timeout—each making things worse—the circuit breaker fails fast and returns cached data or graceful errors.

Load shedding deliberately rejects some requests when overwhelmed. This keeps the system functional for most users rather than becoming unavailable for everyone. Rejecting 10% of requests is better than failing 100%.

Architecture Patterns

Active-Active

Run multiple instances of every component, all actively serving traffic. When one fails, others continue without interruption. No failover delay because there's nothing to fail over to—traffic just stops going to the dead instance.

This provides the fastest recovery and best resource utilization, but requires careful state management.

Geographic Distribution

Place components in multiple physical locations. Different availability zones protect against rack or network failures. Different regions protect against facility-level disasters.

Multi-region architectures serve users from their nearest region for low latency while failing over to distant regions when local ones fail.

Stateless Services

Stateless services don't store session data locally. Any instance can handle any request. This makes them trivial to scale and highly resilient—losing an instance loses nothing.

State must live somewhere, so stateless services use external stores (databases, caches) that are themselves highly available.

Data Replication

Keep multiple copies of data so storage failures don't cause data loss.

Synchronous replication updates all copies before acknowledging writes. Guarantees consistency but adds latency.

Asynchronous replication updates copies in the background. Better performance but risks losing recent writes if the primary fails before replication completes.

Message Queues

Queues decouple components. If a downstream service is temporarily unavailable, requests queue up and process when it recovers. Hard failures (service down, requests lost) become soft failures (service down, requests delayed).

The Capacity Requirement

High availability requires spare capacity.

N+1 redundancy means one extra instance beyond what's needed. If normal load requires 10 servers, run 11. Losing one doesn't degrade performance.

N+2 redundancy for critical systems tolerates two simultaneous failures.

Running at 90% capacity during normal operation leaves no room for failures. Running at 60% means losing a third of capacity still leaves you operational.

This is expensive. You're paying for capacity you hope never to use. But it's the cost of availability.

Testing Availability

Untested high availability is theoretical availability. Many organizations discover their failover doesn't work precisely when they need it most.

Chaos engineering deliberately injects failures to verify recovery works. Kill servers. Partition networks. Corrupt data. Do it regularly, in production, during business hours. If your availability mechanisms only work in theory, you'll find out during an actual outage.

Failover drills regularly exercise failover mechanisms. If you've never actually failed over to your backup data center, you don't know if it works.

Load testing verifies systems handle expected peaks plus headroom for failures.

Safe Changes

Many outages come from changes—deployments, configuration updates, infrastructure modifications. High availability includes safe change practices.

Canary deployments route small traffic percentages to new versions first. Problems affect few users before wider rollout.

Blue-green deployments maintain two complete environments. Switch traffic atomically. If problems appear, switch back instantly.

Feature flags allow enabling features gradually or disabling them immediately if problems appear.

The Trade-offs

High availability isn't free.

Cost increases significantly. Redundant infrastructure, multi-region deployment, reserve capacity—all expensive.

Complexity grows with each redundancy layer. More components mean more monitoring, more procedures, more potential failure modes.

Consistency challenges arise with distributed systems. Keeping multiple data copies synchronized is hard.

The appropriate availability level depends on what you're building. A personal blog doesn't need five nines. A payment system might.

Measuring What Matters

Mean Time Between Failures (MTBF): How often do failures occur?

Mean Time to Detection (MTTD): How quickly are failures detected?

Mean Time to Recovery (MTTR): How quickly does the system recover?

Total unavailability per incident = MTTD + MTTR. Improving availability means reducing both detection and recovery time, not just preventing failures.

Beyond Technology

Technical architecture alone doesn't create high availability. Organizations need:

  • On-call rotations for 24/7 incident response
  • Runbooks documenting how to diagnose and recover from known failures
  • Post-incident reviews to learn from failures and prevent recurrence
  • Reliability investment treating it as a feature, not an afterthought

High availability is continuous. Systems evolve, scale changes, new failure modes emerge. The work is never done—just the outages get shorter.

Frequently Asked Questions About High Availability

Was this page helpful?

😔
🤨
😃
Designing for High Availability • Library • Connected