Abstract
AI-assisted development has compressed feature work from hours to minutes, but production systems do not run under ideal conditions. Databases become unavailable, networks time out, clients repeat requests, deployments stop halfway, and operators make mistakes. That is why so many AI-generated systems share the same contradiction: they look complete as software and naive as operations.
Reliability is not an infrastructure layer to add after launch. It is a set of behaviors that must be defined with the product: how failure is detected, how far it can spread, what the service does while degraded, how data remains recoverable, and how people intervene safely. AI can implement many of these mechanisms—but only after we make failure part of the assignment.
Functional requirements say what the system should do when things go right. Reliability requirements say what the system must still protect when they do not.
Part I · Put failure back into the design
01Functionally complete, operationally naive
Over the past two years, AI-assisted development has changed the pace of software construction. APIs, data models, frontend components, and test scaffolds that once took hours can now appear in minutes. The danger is not that this code never works. It is that the code usually proves only one thing: it works along the happy path we arranged for it.
Production does not remain on that path. A database becomes briefly unavailable. A third-party API slows down during peak traffic. A client repeats an order because the first response never arrived. Half the fleet accepts a release while the other half fails to start. A harmless-looking configuration change bypasses every test written for the application code.
For an order-creation API, the questions that separate a demo from a production service are therefore different:
- If a client retries after an ambiguous timeout, can it create two orders?
- If inventory is reserved and the payment call times out, what state is the order in?
- If a dependency stays slow, can it exhaust threads, connections, or queues upstream?
- During a partial rollout, can old and new versions safely share the same data?
- How will the on-call engineer locate the failure and restore service without making it worse?
These are not advanced optimizations. They are the other half of the feature. A system that defines only success has not yet been fully specified.
02Reliability is more than a string of nines
Availability is the most familiar expression of reliability, but it is not the whole of it. A 99.9% figure describes an allowed amount of failure over a window. On its own, it does not tell us whether that failure harmed the most important customers, corrupted data, remained invisible for hours, or required the one engineer who understands the system to recover it.
A more useful view asks four connected questions:
| View | Question | Typical evidence |
|---|---|---|
| Availability | Can users access the service at the promised time and quality? | SLIs, SLOs, error budgets |
| Resilience | Can the system continue, or degrade deliberately, during a local fault? | Isolation, load shedding, redundancy, degradation tests |
| Recoverability | Can it return to a known-good state after resilience is exhausted? | MTTR, RTO, RPO, recovery drills |
| Maintainability | Can the team understand, change, and operate it safely? | Change failure rate, rollback, runbooks |
In a simplified repairable-system model, availability is often expressed as:
Availability ≈ MTBF ÷ (MTBF + MTTR) — MTBF focuses on the interval between failures; MTTR focuses on recovery speed. The value of this approximation is not the tidy number. It is the reminder that preventing failure and accelerating recovery both matter.
Google’s SRE practice also makes a more important point: reliability is not a race to 100%. Different user journeys carry different costs of failure, so investment should follow risk and user experience rather than an abstract contest for more nines. In partially available distributed systems, request success rate can also describe user experience better than whole-site downtime alone. [1]
03Failure is an input, not an exception
Murphy’s Law endures in engineering because it forces us to reason about scale. An event can be unlikely per operation and still become routine when enough components run for long enough.
Disks fail. Processes crash. Certificates expire. Networks become unstable. Cloud services suffer outages. External APIs change behavior. Human operations cannot be perfect either. Reliability design does not attempt to remove these facts from the world. It decides what the system will do after they arrive.
A mature system is not one without failure. It is one in which failure still produces a designed outcome.
That changes the question from “How do we prevent every failure?” to: What must keep working? What can pause? How far can an error spread? Which state can be rebuilt? Who owns the recovery decision? The Azure Well-Architected Framework similarly places business requirements, resilience, recovery, operations, and simplicity in one reliability model. It explicitly distinguishes critical paths from degradable components and asks teams to analyze blast radius instead of protecting every component equally. [2]
Part II · Spend reliability where it matters
04Find the promises the business cannot lose
Not every component deserves the same protection. Product recommendations can disappear temporarily while customers continue to place orders. An order submitted twice can trigger duplicate charges, inventory errors, and support work. A report may be ten minutes late; a settlement record may create financial and compliance exposure if it vanishes.
The 80/20 rule of reliability is not about finding exactly 20% of the code. It is about identifying a small set of business promises that cannot be violated:
Only then do redundancy, audit trails, reconciliation, compensating workflows, multi-zone deployment, and enhanced monitoring have a cost model. Google SRE uses different classes of data to make the same point: privacy-critical data and optional experience-enhancing data should not receive identical storage guarantees. [1]

Figure 1 · Protect promises, not components equally. The brick-red route is the business outcome that must survive. Buffers, isolation, and redundancy are arranged around it; peripheral capabilities are allowed to degrade deliberately.
05Simplicity, dependencies, and fault boundaries
AI-generated architecture can mistake “using more patterns” for “thinking more completely.” Event-driven design, CQRS, distributed workflows, layered caches, and a service mesh may all be justified. Every additional moving part also adds state, contracts, monitoring, and recovery work.
Simplicity does not mean forcing everything into one process. It means introducing complexity only for constraints that already exist, keeping the critical path short, and making failure modes enumerable and testable. Azure’s reliability guidance names simplicity as a design principle while correctly warning that oversimplification can create single points of failure. [2]
A dependency, meanwhile, must be treated as a fault boundary rather than merely an integration endpoint. For every database, queue, identity provider, payment gateway, or AI API, ask:
- How long will we wait before giving up?
- On failure, do we degrade, queue, serve cached data, or reject the request?
- Which layer retries, how many times, and with what backoff and jitter?
- Does repeating the operation cause side effects, and how long does an idempotency key live?
- When latency rises, what isolates connection pools, threads, queues, and upstream traffic?
- If the dependency remains unavailable, is there an alternative path or a recoverable backlog?
Retries are not free reliability. Unbounded retries, retries without backoff, and retries at multiple layers can turn a brief fault into sustained overload. Amazon’s guidance treats timeouts, bounded retries, exponential backoff, and random jitter as one design problem. Calls with side effects also need explicit idempotency semantics first. [3][4]
Stripe’s API provides a concrete example: clients attach an idempotency key to create or update operations, making it safe to retry after an ambiguous connection failure while the server returns the result of the first execution for the same key. [5] The lesson is not to copy a header. It is to turn “we do not know whether it succeeded” from an ad hoc exception into a state the protocol understands.
Redundancy must be equally specific. Two instances that share a power source, network path, or bad configuration are not independent protection. Useful redundancy states which failure it covers, how the primary failure is detected, how traffic or leadership moves, how data remains consistent, and how the system returns after the incident.
06Reliability is also about people
Severe incidents do not come only from code defects. Bad configuration, accidental deletion, oversized permissions, skipped deployment steps, and unsafe recovery commands can all expand a local problem into a business outage. Calling the operator careless usually avoids the better question: Why could an ordinary mistake cause extraordinary damage?
Good operational interfaces and release systems deliberately reduce the error surface:
- Clear names, typed configuration, and validation reject invalid states early.
- Safe defaults make risky operations require explicit elevation.
- Destructive changes show their real impact instead of a generic confirmation dialog.
- Releases enter production in stages with observable stop conditions.
- Rollback, recovery, and audit are routine paths rather than improvised incident work.
The goal is not to remove people from the system. It is to reserve human judgment for places that require judgment. Automation should eliminate error-prone repetition while preserving clear authority, evidence, and an undo path.
Part III · Move from architecture into operations
07Reliability is a loop, not a diagram
An architecture diagram can show redundancy and dependencies. It cannot prove that a team can detect and recover from failure. A mature reliability lifecycle needs at least the following loop:
- Prevent
- Identify critical paths, failure modes, and high-risk changes.
- Detect
- Observe user outcomes instead of waiting for customer reports.
- Analyze
- Establish impact, current state, and likely triggers.
- Contain
- Shed load, open a circuit, degrade, or stop a rollout before the fault spreads.
- Recover
- Roll back, fail over, replay, compensate, or restore to a known state.
- Repair
- Remove both the trigger and the conditions that amplified it.
- Learn
- Feed postmortems, drills, and verifiable action items back into the system.
Missing any link can leave reliability on paper. Without detection, recovery starts late. Without containment, a local fault expands while people investigate. Without drills, a runbook may be only an untested wish. Without action items, a postmortem preserves a story without changing the next outcome.
Google’s incident-response practice emphasizes predefined command roles, a working record of diagnosis and mitigation, and regular exercises. Its postmortem guidance asks teams to explain impact, recovery, and causes with evidence, then assign action items to clear owners with measurable end states. [6][7]

Figure 2 · The reliability loop. Detection is only the beginning. Loss is reduced by the complete path from signal to containment and from recovery to learning. AI can assist at every stage, but the team must define the control objective and the evidence of success.
08Observability and recovery are product features
Teams often fund feature implementation generously and postpone logs, metrics, alerts, recovery scripts, and drills until “after launch.” The predictable result is a system that has already failed while its operators infer customer impact from fragments. Backups may run every day without ever proving that they can restore complete data within the required window.
Reliability requirements should be testable like API behavior. For every critical user journey, write down:
Reliability acceptance for a critical path
- What user outcome defines success, failure, and degraded performance?
- Which signals reveal deviation before customers report it?
- Who receives the alert, and what is the first action they take?
- What is the maximum blast radius of one instance, zone, dependency, or bad configuration?
- What does degraded mode still guarantee, and what does it explicitly drop?
- Which data, permissions, tools, and human decisions does recovery require?
- Have RTO and RPO been demonstrated by a real exercise rather than stated in a document?
- Can a release stop and roll back safely, with old and new versions briefly coexisting?
Answering those questions is the difference between owning an operable service and possessing a deployable program.
Part IV · Teach AI to reason about failure
09Turn a feature prompt into a production contract
Coding assistants usually seek the shortest path from a requirement to a working implementation. If the input says only “build an order processing service,” then controllers, services, persistence, validation, and unit tests are natural outputs. Timeouts, idempotency, containment, and recovery may be absent not because the model has never encountered them, but because the assignment never made them part of done.
A failure contract is more effective than a vague instruction to “consider reliability”:
Implement an order processing service. Functional correctness is only part |
The value of this prompt is not the number of reliability terms. It forces every mechanism to connect to a failure scenario, a business consequence, and evidence. Otherwise, “add a circuit breaker” becomes decorative architecture and “add monitoring” becomes a pile of signals that nobody can act on.
Ask AI for evidence, not only code. Require results for duplicate requests, downstream timeouts, partial rollouts, dependency overload, and recovery exercises. A guarantee that cannot be demonstrated should be marked unknown, not filled with architecture vocabulary.
10AI cannot own the consequences of failure
AI can help enumerate failure modes, generate fault-injection tests, inspect configuration, draft runbooks, and—in tightly constrained systems—even execute parts of recovery. It is particularly good at expanding a team’s capacity to search for counterexamples and repeat verification.
The model does not know the true cost of a delayed settlement to this company. It cannot independently decide among privacy, money, and customer trust. It sees requirements, code, and available context; engineers face promises, organizational capability, and consequences.
Our role therefore moves beyond implementing every line by hand. We must build the control plane for reliability: define what cannot be lost, choose a risk budget, bound automation privileges, review fault boundaries, demand verification evidence, and ensure someone can restore the service at 3 a.m.
11Reliable from the beginning
The software industry has spent decades optimizing how code is written. AI has pushed that process to a new speed. The physical and organizational facts of production have not changed: servers fail, networks fail, people make mistakes, and dependencies change at inconvenient moments.
Building functionality is becoming rapidly automated. Anticipating failure, choosing the boundary of loss, and accepting responsibility for recovery are becoming more valuable as a result.
“Reliable by design” does not mean infinite redundancy in the first release, or a system that never breaks. It means the success path and the failure path are equally real from the first requirement. From the first deployment, detection, containment, recovery, and learning are treated as part of the product.
Reliability begins when we stop asking only, “Can the system work?” and ask instead, “When it cannot, which promises must still hold?”
References and further reading
These public engineering sources ground the discussion of reliability, retries, idempotency, and incident response. A production design still requires trade-offs based on business impact, cost, and team capability.
- Alvidrez, Marc. “Embracing Risk.” Site Reliability Engineering, Google, 2016.
- Microsoft. “Reliability Design Principles.” Azure Well-Architected Framework.
- Brooker, Marc. “Timeouts, Retries, and Backoff with Jitter.” Amazon Builders’ Library.
- Featonby, Malcolm. “Making Retries Safe with Idempotent APIs.” Amazon Builders’ Library.
- Stripe. “Idempotent Requests.” Stripe API Reference.
- Jones, Stephen, et al. “Incident Response.” The Site Reliability Workbook, Google, 2018.
- Rogers, Daniel, et al. “Postmortem Culture: Learning from Failure.” The Site Reliability Workbook, Google, 2018.