Skip to content

Building calm infrastructure

Reliable systems should reduce cognitive load, not move it from machines to people. Calm infrastructure makes its state visible, limits the number of ways a change can surprise you, and leaves a clear recovery path.

Prefer boring interfaces

The most valuable interface is often the one an operator can understand at 03:00 without opening six dashboards. Give components narrow responsibilities, make failure states explicit, and keep operational commands predictable.

service.yml
service:
  healthcheck: /healthz
  timeout: 5s
  retries: 3

The details matter less than the contract. An operator should be able to answer three questions quickly: is the service ready, what does it depend on, and what happens when a dependency becomes unavailable? If those answers require reading the implementation, the operational interface is incomplete.

Boring also means consistent. Similar services should use the same names for health checks, logs, metrics, timeouts, and shutdown behavior. Consistency turns experience with one system into useful intuition for the next.

Design alerts for decisions

An alert should ask a human to make a decision. If nobody needs to act, the event belongs in a log, metric, or dashboard—not in the paging channel.

Good alerts describe user-visible symptoms and include enough context to begin an investigation:

  • what is failing and for whom;
  • when the failure started;
  • which recent change may be related;
  • where to find the relevant logs and metrics;
  • which safe actions are available.

CPU usage by itself is rarely a useful page. A sustained increase in request latency combined with exhausted worker capacity is much closer to an actionable signal. The goal is not to observe every internal movement; it is to notice when the system can no longer keep its promises.

Alert quality also needs maintenance. Review noisy alerts after incidents, remove ones that never lead to action, and test the routes that deliver them. A perfect alert sent to an abandoned channel is still a failed alert.

Put limits around failure

Calm systems fail inside boundaries. Set explicit timeouts so work cannot wait forever, cap retries so a struggling dependency is not flooded, and apply resource limits so one workload cannot consume the entire host.

Retries deserve particular care. Immediate retries can multiply load during an outage and make recovery harder. Use a limited number of attempts with exponential backoff and jitter, then return a clear error or move the work to a queue. Every retry policy should have an end.

The same principle applies to dependencies. A service should know which dependencies are required for startup, which can be temporarily unavailable, and how degraded operation is reported. Partial failure is easier to manage when it was considered before deployment.

Make changes small and reversible

Large changes create large search spaces. When an incident follows a deployment, the team must determine which part of the change affected the system. Small, frequent changes make that question easier to answer.

A calm change process usually has a few properties:

  1. The intended outcome and validation check are written down.
  2. Configuration is reviewed and stored in version control.
  3. Deployment happens in stages rather than everywhere at once.
  4. Health is checked after each stage.
  5. A rollback or roll-forward path is known before the change begins.

Automation should make these steps repeatable, but it should not hide them. A deployment pipeline is safer when an operator can see what it is changing and can stop it between stages.

Make recovery part of the design

A backup is only a theory until restoration is practiced. Treat rollbacks, restore drills, and documented failure modes as product features.

A useful default

Automate the common recovery path, then document the manual path beside it.

A useful restore drill starts with a specific question: can this service be rebuilt on an empty host using only the backup, configuration repository, and runbook? Testing in an isolated environment exposes missing credentials, undocumented dependencies, incompatible versions, and recovery steps that exist only in someone's memory.

Recovery objectives should be concrete. The recovery point objective describes how much data loss is acceptable; the recovery time objective describes how long restoration may take. Those two limits determine backup frequency, retention, replication, and how much recovery automation is worth building.

Keep the runbook close to reality

A runbook should be short enough to use under pressure. Start with checks that distinguish common failure modes, then list safe mitigations and the conditions for escalation. Commands should state what success looks like and warn about destructive effects.

Documentation drifts unless it participates in operations. Update the runbook after an incident, use it during maintenance, and periodically ask someone who did not write it to follow it. Confusing steps found during a drill are defects, not editorial details.

Calm is an engineering outcome

Calm infrastructure is not infrastructure that never fails. It is infrastructure that communicates clearly when it fails, contains the damage, and gives people a practiced route back to a healthy state.

The work is mostly unglamorous: consistent interfaces, useful alerts, bounded retries, small changes, tested backups, and current runbooks. Together, those choices replace improvisation with evidence. That is what allows an operator to respond carefully—even at 03:00.