Building for Imperfect Systems
Why systems that accept failure build more resilient software than those designed to prevent it.
Contents
Contents
Contents
Contents
Every distributed system fails. The network partitions. The database goes down. The third-party API returns garbage. The question isn't whether your system will encounter failure — it's whether your system was designed to handle it.
The Myth of Prevention
Most engineering teams spend enormous effort trying to prevent failures. They add redundancy, write exhaustive tests, implement circuit breakers, and build monitoring dashboards. All of this is good. None of it is sufficient.
The fundamental problem with prevention-only thinking is that it assumes you can enumerate all failure modes in advance. You can't. The failures that take down production are almost never the ones you planned for.
Designing for Graceful Degradation
The alternative is to design systems that degrade gracefully. Instead of asking "how do we prevent this from failing?" ask "what should happen when this fails?"
Here are some principles I've found useful:
- Default to safe states. When a service is unreachable, return cached data rather than an error page.
- Make failures visible. Log everything. Alert on anomalies. Make it easy to understand what went wrong after the fact.
- Isolate blast radius. A failure in the recommendation engine shouldn't take down the checkout flow.
- Practice failure. Run chaos engineering experiments. Break things on purpose in staging.
The Human Element
Systems don't exist in isolation — they're operated by humans. The most resilient systems I've worked on were the ones where the team had practiced responding to incidents. They had runbooks. They had clear escalation paths. They had blameless postmortems.
Resilience isn't a property of software. It's a property of the team that builds and operates the software.
Embracing Imperfection
There's a philosophical dimension to this. When you accept that your system will fail, you free yourself from the paralysis of trying to make it perfect. You ship faster. You learn faster. You build something that's genuinely robust because it's been tested by reality, not just by your imagination.
The best systems I've seen aren't the ones with the fewest bugs. They're the ones that recover the fastest.
This is the first in a series on resilient architecture. Next up: circuit breakers, bulkheads, and the patterns that actually work in production.
More to read
engineering
I Built a CLI to Show Me What My AI-Generated Infrastructure Actually Costs
AI tools generate working infrastructure fast, but cost stays invisible until the bill arrives. I built Slate to fix that — a CLI that reads your CDK output and shows real prices before you deploy.
design
The Art of Less: Why Minimalism in Design Actually Works
Minimalism isn't about removing things. It's about making room for the things that matter.
notes
On Shipping Early and Often
The gap between 'almost done' and 'shipped' is where most projects go to die. Here's how to close it.