OBEY Release It! by Michael T. Nygard
Purpose
This repository follows Release It! in the sense of Michael Nygard:
design and implement software that survives production reality - failures, overload, latency, partial outages, bad data, hostile traffic, and operational mistakes.
All code generation, edits, and reviews must optimize for:
- production readiness
- failure isolation
- graceful degradation
- back pressure and overload protection
- timeouts and retries with discipline
- observability
- survivability over ideal-path elegance
This file is a binding engineering policy: MUST is binding, SHOULD is a strong default, and MUST NOT is forbidden.
Primary Directive
Assume production will be messy.
When uncertain, prefer the design that:
- fails visibly instead of hanging silently
- limits blast radius instead of maximizing coupling
- sheds load instead of collapsing
- preserves core service under stress
- makes diagnosis possible
Do not design only for the happy path.
Stability Mindset Rules
- Every dependency can be slow, unavailable, or wrong.
- Every queue can fill.
- Every cache can miss or stampede.
- Every timeout can cascade.
- Every caller can retry badly.
- Every “temporary” degraded state can become normal for hours.
The code must assume these conditions, not merely tolerate them by accident.
Production Readiness and Release Risk Rules
- Do not treat QA success or feature completion as proof of production readiness.
- Design deployment, operations, security, observability, and rollback as part of the system.
- Reduce release risk through small exposure steps, compatibility discipline, and reversible changes.
- Make version, build, configuration, dependency, and runtime state visible enough to diagnose a live instance.
- Validate critical configuration at startup and make configuration changes auditable and reversible.
Dependency Protection Rules
Timeouts Are Mandatory
- Outbound calls must have explicit time limits.
- Timeouts must be chosen intentionally, not left to library defaults.
- Different dependencies may need different timeout budgets.
- Infinite waits are forbidden.
Retries Must Be Disciplined
- Retry only where repeated attempts are safe for the caller and provider.
- Bound retry count and total retry time.
- Add jitter/backoff to avoid synchronized retry storms.
- Do not retry validation errors or permanent failures.
Circuit Breakers and Fast Failure
- Protect unstable dependencies with fast-fail mechanisms when appropriate.
- When a dependency is clearly unhealthy, stop flooding it.
- Surface fallback or degraded mode explicitly.
Bulkheads and Isolation
- Separate resource pools for unrelated workloads where failure isolation matters.
- One failing integration must not consume all threads, connections, or worker capacity.
- Isolate slow or risky work from core request paths.
Anti-patterns (MUST NOT):
- nested retries at multiple layers
- no timeout around remote calls
- one shared pool for all outbound work
- treating all failures as transient
Load and Capacity Rules
Back Pressure
- The system must have a strategy for overload.
- Reject, defer, queue, or degrade intentionally.
- Unbounded acceptance of work is forbidden.
Queues
- Queues are buffers, not infinite storage.
- Monitor queue length, age, throughput, and failure rate.
- Know what happens when producers outpace consumers.
- Define dead-letter or poison-message handling explicitly.
Demand Control
- Protect scarce resources with limits.
- Prefer early rejection over total collapse.
- Reserve capacity for critical traffic when appropriate.
Load Shedding
- Define which work is optional under stress.
- Shed low-value work first.
- Preserve core functions whenever possible.
Additional Stability Patterns
- USE Steady State design so routine operation does not require manual cleanup, unbounded growth, or periodic rescue.
- USE Fail Fast when continuing would hold scarce resources or hide an unrecoverable dependency problem.
- USE Let It Crash only when supervisors, isolation, and restart behavior make crashing safer than limping.
- USE Handshaking between instances, load balancers, and dependencies so traffic reaches only ready components.
- USE Decoupling Middleware when it reduces direct failure propagation; monitor the middleware as a dependency.
- USE Governors to cap expensive behavior before it harms the rest of the system.
Anti-patterns (MUST NOT):
- unbounded queues
- accepting work with no plan to finish it
- letting best-effort tasks crowd out critical work
Runtime State and Restart Safety Rules
- Make runtime state visible through logs, metrics, health endpoints, administrative interfaces, and diagnostic data.
- Validate external responses by status, content type, shape, and semantics before trusting them.
- Make deployment and operational automation idempotent or restartable where practical.
- Avoid partial deployment or migration steps without a rollback or roll-forward path.
- Validate operational assumptions at system boundaries.
Restartable Automation
Required when:
- deployments touch many machines
- scripts may be rerun after partial failure
- migrations run while old and new application versions coexist
- operational procedures must be repeatable under release pressure
Anti-patterns (MUST NOT):
- one-shot deployment scripts that cannot safely resume
- manual repair steps with no recorded state
- side effects before a durable release checkpoint with no recovery plan
Resource Management Rules
- Explicitly budget scarce resources:
- threads
- DB connections
- sockets
- file descriptors
- memory
- CPU-intensive worker slots
- Release resources deterministically.
- Do not hold locks or expensive connections across slow remote calls.
- Use streaming or pagination for large payloads where appropriate.
- Guard memory-heavy operations.
Anti-patterns (MUST NOT):
- one huge in-memory batch by default
- blocking worker threads on slow I/O when a better model exists
- connection pools sized by guess and then ignored
Data Boundary Rules
- Treat all external input as untrusted.
- Validate syntax, shape, and business plausibility separately where needed.
- Avoid letting malformed data poison caches, queues, or downstream systems.
- Normalize and sanitize data once at the right boundary.
- Keep parsing errors and domain rule violations distinct.
Operational Visibility Rules
Observability Is Part of the Design
- Emit meaningful logs at boundaries and failure points.
- Include identifiers needed for correlation and diagnosis.
- Measure latency, throughput, error rate, saturation, queue depth, and retry behavior.
- Expose health information that reflects real dependency state.
Logging
- Log structured context, not just prose.
- Log failures with the dependency, operation, and outcome.
- Do not log secrets.
- Avoid log spam loops under retry storms.
Metrics
At minimum, capture:
- request rate
- success/failure counts
- dependency latency
- timeout counts
- queue depth
- retry counts
- circuit-breaker state
- saturation signals
Anti-patterns (MUST NOT):
- only logging stack traces without context
- no metrics for slow dependencies
- health checks that always return green despite broken downstreams
Incidents, Capacity, and Runtime Control
- After incidents, identify the failure chain, missing defenses, detection gaps, and design changes.
- For performance or capacity incidents, inspect demand, saturation, latency distribution, queue age, dependency behavior, and traffic concentration.
- Provide administrative interfaces or operational controls only with authorization, auditability, safe defaults, and clear stop mechanisms.
- Keep process code, scripts, and automation observable enough that operators can see what changed and why.
- Treat control planes and delivery tooling as production systems when they can affect production.
Deployment and Startup Rules
- Startup must fail fast on missing critical configuration.
- Health checks must reflect actual ability to serve.
- Health checks must not mask deadlocks or stuck subsystems.
- Avoid expensive or destructive startup work in request-serving processes when possible.
- Migrations and one-time jobs must be deliberate, observable, and recoverable.
Interconnect, Routing, Security, and Chaos Rules
- Keep DNS, service discovery, routing, and load balancing health-aware and current.
- Design interconnects to avoid concentrated demand, hidden single points of failure, and uncontrolled fan-out.
- Treat hostile traffic, abusive users, and malformed requests as production load cases.
- Include security in production readiness: secrets, permissions, administrative access, dependency trust, and input handling.
- Use production tests, launch checks, capacity tests, and game days to validate operational assumptions.
- Run chaos or disaster simulations only with a hypothesis, limited blast radius, observability, stop condition, and recovery path.
- Feed findings from chaos and disaster work back into design, operations, and tests.
API and Contract Rules
- Make failure modes explicit in API contracts where they matter.
- Return clear retryable vs non-retryable outcomes.
- Prefer coarse-grained, resilient interactions over fragile chattiness.
- Use versioning and compatibility discipline for long-lived contracts.
- Document retry, timeout, version, and compatibility expectations clearly.
Cache Rules
- Cache is an optimization, not a source of truth unless explicitly designed that way.
- Plan for cache miss storms, stale data, and cache outages.
- Avoid dogpiles with request coalescing or appropriate expiry strategies.
- Define what happens when the cache is unavailable.
Anti-patterns (MUST NOT):
- assuming cache hit rate is always high
- rebuilding the whole cache synchronously on miss
- hiding correctness assumptions inside cache behavior
Scheduled and Background Work Rules
- Spread scheduled work so demand does not concentrate at the same instant.
- Do not set all periodic jobs to run on the same obvious clock boundary.
- Failure and retry policy must be explicit.
- Retried work must use increasing backoff where synchronized retry pulses would create load.
- Long-running work needs bounded waits, progress visibility, timeout, and cancellation strategy.
Review Rules
When reviewing code, actively look for:
- outbound calls with no timeout
- retries without backoff, limits, or a clear failure policy
- no backoff or jitter
- unbounded queues or buffers
- shared resource pools with no isolation
- no overload strategy
- no failure visibility
- health checks that say nothing meaningful
- scheduled jobs concentrating load at the same instant
- caches treated as always available
Forbidden Patterns
Happy-Path Design
- code that assumes dependencies are fast and correct
- no timeout, no retry discipline, no degradation path
Retry Storms
- retries at every layer
- retries with no increasing backoff or limits
- synchronized retries without jitter
Collapse by Queue
- unbounded queue growth
- taking work forever even while falling behind
- no poison-message handling
Silent Failure
- swallowed exceptions
- generic “something went wrong” without context
- missing correlation information
Blast-Radius Amplification
- one dependency outage consuming all worker threads or DB connections
- shared pools for all risk classes with no isolation
Code Generation Rules
When generating code, default to:
- explicit timeout for every remote dependency
- explicit retry policy only where safe
- restartable deployment and operational automation where practical
- bounded resources and queues
- clear failure paths
- useful diagnostic hooks
- graceful degradation or fast failure where appropriate
Avoid by default:
- infinite waits
- implicit library retries
- unbounded buffering
- best-effort logging with no metrics
- fragile startup sequences
- one-shot release automation with no restart path
Testing Rules
- Test timeout behavior.
- Test retry, backoff, and failure boundaries.
- Test degraded dependency scenarios.
- Test overload and queue saturation behavior where practical.
- Test restartable deployment or operational automation where practical.
- Test startup and health-check failure modes.
Review Checklist
Before finalizing any change, verify:
- Does every remote call have an explicit timeout?
- Are retries bounded and safe?
- Are deployment and operational scripts restartable or idempotent where practical?
- Is there an overload strategy?
- Are queues and resource pools bounded?
- Is failure isolated from unrelated work?
- Are there enough diagnostics to investigate issues?
- Are health signals meaningful?
- Are scheduled and background workloads bounded and paced safely?
- Did we preserve the core service under likely failure scenarios?
If any answer is no, revise before shipping.
Final Instruction
When uncertain, prefer the design that:
- survives partial failure
- limits blast radius
- fails fast or degrades gracefully
- exposes enough information to operate
- prevents overload from becoming collapse
Production reality outranks happy-path elegance.
1---2name: book-release-it-full3description: Release It! (Michael Nygard) — Full rules — comprehensive mandatory coding standards. Use when asked to apply Release It! principles or review code against Release It! standards.4license: MIT5---6
7# OBEY Release It! by Michael T. Nygard
8
9## Purpose
10
11This repository follows **Release It!** in the sense of Michael Nygard:
12design and implement software that survives production reality - failures, overload, latency, partial outages, bad data, hostile traffic, and operational mistakes.
13
14All code generation, edits, and reviews must optimize for:
15- production readiness
16- failure isolation
17- graceful degradation
18- back pressure and overload protection
19- timeouts and retries with discipline
20- observability
21- survivability over ideal-path elegance
22
23This file is a binding engineering policy: `MUST` is binding, `SHOULD` is a strong default, and `MUST NOT` is forbidden.
24
25---
26
27## Primary Directive
28
29Assume production will be messy.
30
31When uncertain, prefer the design that:
321. fails visibly instead of hanging silently
332. limits blast radius instead of maximizing coupling
343. sheds load instead of collapsing
354. preserves core service under stress
365. makes diagnosis possible
37
38Do not design only for the happy path.
39
40---
41
42## Stability Mindset Rules
43
441. Every dependency can be slow, unavailable, or wrong.
452. Every queue can fill.
463. Every cache can miss or stampede.
474. Every timeout can cascade.
485. Every caller can retry badly.
496. Every “temporary” degraded state can become normal for hours.
50
51The code must assume these conditions, not merely tolerate them by accident.
52
53---
54
55## Production Readiness and Release Risk Rules
56
571. Do not treat QA success or feature completion as proof of production readiness.
582. Design deployment, operations, security, observability, and rollback as part of the system.
593. Reduce release risk through small exposure steps, compatibility discipline, and reversible changes.
604. Make version, build, configuration, dependency, and runtime state visible enough to diagnose a live instance.
615. Validate critical configuration at startup and make configuration changes auditable and reversible.
62
63---
64
65## Dependency Protection Rules
66
67### Timeouts Are Mandatory
681. Outbound calls must have explicit time limits.
692. Timeouts must be chosen intentionally, not left to library defaults.
703. Different dependencies may need different timeout budgets.
714. Infinite waits are forbidden.
72
73### Retries Must Be Disciplined
741. Retry only where repeated attempts are safe for the caller and provider.
752. Bound retry count and total retry time.
763. Add jitter/backoff to avoid synchronized retry storms.
774. Do not retry validation errors or permanent failures.
78
79### Circuit Breakers and Fast Failure
801. Protect unstable dependencies with fast-fail mechanisms when appropriate.
812. When a dependency is clearly unhealthy, stop flooding it.
823. Surface fallback or degraded mode explicitly.
83
84### Bulkheads and Isolation
851. Separate resource pools for unrelated workloads where failure isolation matters.
862. One failing integration must not consume all threads, connections, or worker capacity.
873. Isolate slow or risky work from core request paths.
88
89Anti-patterns (MUST NOT):
90- nested retries at multiple layers
91- no timeout around remote calls
92- one shared pool for all outbound work
93- treating all failures as transient
94
95---
96
97## Load and Capacity Rules
98
99### Back Pressure
1001. The system must have a strategy for overload.
1012. Reject, defer, queue, or degrade intentionally.
1023. Unbounded acceptance of work is forbidden.
103
104### Queues
1051. Queues are buffers, not infinite storage.
1062. Monitor queue length, age, throughput, and failure rate.
1073. Know what happens when producers outpace consumers.
1084. Define dead-letter or poison-message handling explicitly.
109
110### Demand Control
1111. Protect scarce resources with limits.
1122. Prefer early rejection over total collapse.
1133. Reserve capacity for critical traffic when appropriate.
114
115### Load Shedding
1161. Define which work is optional under stress.
1172. Shed low-value work first.
1183. Preserve core functions whenever possible.
119
120### Additional Stability Patterns
121- USE Steady State design so routine operation does not require manual cleanup, unbounded growth, or periodic rescue.
122- USE Fail Fast when continuing would hold scarce resources or hide an unrecoverable dependency problem.
123- USE Let It Crash only when supervisors, isolation, and restart behavior make crashing safer than limping.
124- USE Handshaking between instances, load balancers, and dependencies so traffic reaches only ready components.
125- USE Decoupling Middleware when it reduces direct failure propagation; monitor the middleware as a dependency.
126- USE Governors to cap expensive behavior before it harms the rest of the system.
127
128Anti-patterns (MUST NOT):
129- unbounded queues
130- accepting work with no plan to finish it
131- letting best-effort tasks crowd out critical work
132
133---
134
135## Runtime State and Restart Safety Rules
136
1371. Make runtime state visible through logs, metrics, health endpoints, administrative interfaces, and diagnostic data.
1382. Validate external responses by status, content type, shape, and semantics before trusting them.
1393. Make deployment and operational automation idempotent or restartable where practical.
1404. Avoid partial deployment or migration steps without a rollback or roll-forward path.
1415. Validate operational assumptions at system boundaries.
142
143### Restartable Automation
144Required when:
145- deployments touch many machines
146- scripts may be rerun after partial failure
147- migrations run while old and new application versions coexist
148- operational procedures must be repeatable under release pressure
149
150Anti-patterns (MUST NOT):
151- one-shot deployment scripts that cannot safely resume
152- manual repair steps with no recorded state
153- side effects before a durable release checkpoint with no recovery plan
154
155---
156
157## Resource Management Rules
158
1591. Explicitly budget scarce resources:
160 - threads
161 - DB connections
162 - sockets
163 - file descriptors
164 - memory
165 - CPU-intensive worker slots
1662. Release resources deterministically.
1673. Do not hold locks or expensive connections across slow remote calls.
1684. Use streaming or pagination for large payloads where appropriate.
1695. Guard memory-heavy operations.
170
171Anti-patterns (MUST NOT):
172- one huge in-memory batch by default
173- blocking worker threads on slow I/O when a better model exists
174- connection pools sized by guess and then ignored
175
176---
177
178## Data Boundary Rules
179
1801. Treat all external input as untrusted.
1812. Validate syntax, shape, and business plausibility separately where needed.
1823. Avoid letting malformed data poison caches, queues, or downstream systems.
1834. Normalize and sanitize data once at the right boundary.
1845. Keep parsing errors and domain rule violations distinct.
185
186---
187
188## Operational Visibility Rules
189
190### Observability Is Part of the Design
1911. Emit meaningful logs at boundaries and failure points.
1922. Include identifiers needed for correlation and diagnosis.
1933. Measure latency, throughput, error rate, saturation, queue depth, and retry behavior.
1944. Expose health information that reflects real dependency state.
195
196### Logging
1971. Log structured context, not just prose.
1982. Log failures with the dependency, operation, and outcome.
1993. Do not log secrets.
2004. Avoid log spam loops under retry storms.
201
202### Metrics
203At minimum, capture:
204- request rate
205- success/failure counts
206- dependency latency
207- timeout counts
208- queue depth
209- retry counts
210- circuit-breaker state
211- saturation signals
212
213Anti-patterns (MUST NOT):
214- only logging stack traces without context
215- no metrics for slow dependencies
216- health checks that always return green despite broken downstreams
217
218---
219
220## Incidents, Capacity, and Runtime Control
221
2221. After incidents, identify the failure chain, missing defenses, detection gaps, and design changes.
2232. For performance or capacity incidents, inspect demand, saturation, latency distribution, queue age, dependency behavior, and traffic concentration.
2243. Provide administrative interfaces or operational controls only with authorization, auditability, safe defaults, and clear stop mechanisms.
2254. Keep process code, scripts, and automation observable enough that operators can see what changed and why.
2265. Treat control planes and delivery tooling as production systems when they can affect production.
227
228---
229
230## Deployment and Startup Rules
231
2321. Startup must fail fast on missing critical configuration.
2332. Health checks must reflect actual ability to serve.
2343. Health checks must not mask deadlocks or stuck subsystems.
2354. Avoid expensive or destructive startup work in request-serving processes when possible.
2365. Migrations and one-time jobs must be deliberate, observable, and recoverable.
237
238---
239
240## Interconnect, Routing, Security, and Chaos Rules
241
2421. Keep DNS, service discovery, routing, and load balancing health-aware and current.
2432. Design interconnects to avoid concentrated demand, hidden single points of failure, and uncontrolled fan-out.
2443. Treat hostile traffic, abusive users, and malformed requests as production load cases.
2454. Include security in production readiness: secrets, permissions, administrative access, dependency trust, and input handling.
2465. Use production tests, launch checks, capacity tests, and game days to validate operational assumptions.
2476. Run chaos or disaster simulations only with a hypothesis, limited blast radius, observability, stop condition, and recovery path.
2487. Feed findings from chaos and disaster work back into design, operations, and tests.
249
250---
251
252## API and Contract Rules
253
2541. Make failure modes explicit in API contracts where they matter.
2552. Return clear retryable vs non-retryable outcomes.
2563. Prefer coarse-grained, resilient interactions over fragile chattiness.
2574. Use versioning and compatibility discipline for long-lived contracts.
2585. Document retry, timeout, version, and compatibility expectations clearly.
259
260---
261
262## Cache Rules
263
2641. Cache is an optimization, not a source of truth unless explicitly designed that way.
2652. Plan for cache miss storms, stale data, and cache outages.
2663. Avoid dogpiles with request coalescing or appropriate expiry strategies.
2674. Define what happens when the cache is unavailable.
268
269Anti-patterns (MUST NOT):
270- assuming cache hit rate is always high
271- rebuilding the whole cache synchronously on miss
272- hiding correctness assumptions inside cache behavior
273
274---
275
276## Scheduled and Background Work Rules
277
2781. Spread scheduled work so demand does not concentrate at the same instant.
2792. Do not set all periodic jobs to run on the same obvious clock boundary.
2803. Failure and retry policy must be explicit.
2814. Retried work must use increasing backoff where synchronized retry pulses would create load.
2825. Long-running work needs bounded waits, progress visibility, timeout, and cancellation strategy.
283
284---
285
286## Review Rules
287
288When reviewing code, actively look for:
289- outbound calls with no timeout
290- retries without backoff, limits, or a clear failure policy
291- no backoff or jitter
292- unbounded queues or buffers
293- shared resource pools with no isolation
294- no overload strategy
295- no failure visibility
296- health checks that say nothing meaningful
297- scheduled jobs concentrating load at the same instant
298- caches treated as always available
299
300---
301
302## Forbidden Patterns
303
304### Happy-Path Design
305- code that assumes dependencies are fast and correct
306- no timeout, no retry discipline, no degradation path
307
308### Retry Storms
309- retries at every layer
310- retries with no increasing backoff or limits
311- synchronized retries without jitter
312
313### Collapse by Queue
314- unbounded queue growth
315- taking work forever even while falling behind
316- no poison-message handling
317
318### Silent Failure
319- swallowed exceptions
320- generic “something went wrong” without context
321- missing correlation information
322
323### Blast-Radius Amplification
324- one dependency outage consuming all worker threads or DB connections
325- shared pools for all risk classes with no isolation
326
327---
328
329## Code Generation Rules
330
331When generating code, default to:
3321. explicit timeout for every remote dependency
3332. explicit retry policy only where safe
3343. restartable deployment and operational automation where practical
3354. bounded resources and queues
3365. clear failure paths
3376. useful diagnostic hooks
3387. graceful degradation or fast failure where appropriate
339
340Avoid by default:
341- infinite waits
342- implicit library retries
343- unbounded buffering
344- best-effort logging with no metrics
345- fragile startup sequences
346- one-shot release automation with no restart path
347
348---
349
350## Testing Rules
351
3521. Test timeout behavior.
3532. Test retry, backoff, and failure boundaries.
3543. Test degraded dependency scenarios.
3554. Test overload and queue saturation behavior where practical.
3565. Test restartable deployment or operational automation where practical.
3576. Test startup and health-check failure modes.
358
359---
360
361## Review Checklist
362
363Before finalizing any change, verify:
364- Does every remote call have an explicit timeout?
365- Are retries bounded and safe?
366- Are deployment and operational scripts restartable or idempotent where practical?
367- Is there an overload strategy?
368- Are queues and resource pools bounded?
369- Is failure isolated from unrelated work?
370- Are there enough diagnostics to investigate issues?
371- Are health signals meaningful?
372- Are scheduled and background workloads bounded and paced safely?
373- Did we preserve the core service under likely failure scenarios?
374
375If any answer is no, revise before shipping.
376
377---
378
379## Final Instruction
380
381When uncertain, prefer the design that:
3821. survives partial failure
3832. limits blast radius
3843. fails fast or degrades gracefully
3854. exposes enough information to operate
3865. prevents overload from becoming collapse
387
388Production reality outranks happy-path elegance.