Laws & Disorder #2 — Hyrum's Law: In the Age of Agents, Who Pays for a Broken API?
written by Stefan Christoph
- 8 minutes readSecond in “Laws & Disorder,” the series on the software laws we half-quote. Last time it was Conway’s Law. This one is the reason your “non-breaking” change broke someone anyway.
There is a particular kind of production incident that teaches you humility. You ship a change that is, by every reasonable reading of the documentation, backward compatible. The spec is unchanged. And something downstream falls over anyway, because a consumer was quietly depending on a behavior you never promised and never knew they could see.
That is Hyrum’s Law, and once you have been on either side of it you stop trusting the phrase “non-breaking change.”
The law
Hyrum Wright, an engineer at Google, noticed around 2011 that even internal library changes that should have been invisible kept breaking some project, somewhere. Titus Winters later wrote it down in “Software Engineering at Google” [2], and it now lives at its own one-line address [1]:
With a sufficient number of users of an API, it does not matter what you promise in the contract: all observable behaviors of your system will be depended on by somebody.
The key word is observable. Not documented. Observable.
The docs are not the contract
The canonical example is a list. Your documentation says the order is unspecified. But in practice the implementation returns it sorted, and it has for years. Somewhere a consumer wrote code that assumes sorted order, because that is what they observed. The day you “fix” the implementation to truly randomize the order, per your own spec, you break them. You were right on paper and it did not matter.
It is never only ordering. It is the exact wording of an error message that someone is string-matching on. It is the retry timing that a client tuned its own backoff against. It is a field that is always null in practice so nobody handles the non-null case. xkcd captured the whole law in one strip: somewhere, someone’s workflow depends on your CPU running hot because they hold down the spacebar to keep the room warm, and the moment you optimize it you have broken their setup [3]. The joke is that this is not a joke.
Internal APIs are contracts too
Here is the part I learned the expensive way. For a stretch of my career I was responsible for API strategy at a large company, and we did what almost everyone does: external APIs got the effort. They got the documentation, the versioning discipline, the deprecation notices, the careful reviews, because customers were on the other end. Internal APIs, the ones between our own teams and services, were treated as second-class. Move fast, we own both sides, we can just fix the callers.
Except a broken internal contract caused just as much damage. When an internal API changed a behavior a sister team had come to rely on, the outage was just as real, the debugging just as painful, and the blast radius sometimes larger because internal callers had fewer guardrails. Hyrum’s Law does not check whether an interface is public before it applies. If someone can observe a behavior, someone will depend on it, and “internal” does not exempt you. All APIs are contracts. The internal ones simply have the same law applied with less of a safety net.
Why the big platforms move slowly
If you have ever been frustrated that a cloud provider takes years to deprecate anything, Hyrum’s Law is the reason, and it is a feature. When your API has enough users, you cannot know which observable behaviors have become load-bearing, so you keep them, sometimes bug-for-bug, and you deprecate on long, telegraphed timelines. That caution is not sluggishness. It is what reliability looks like from the inside.
A clean example is Amazon S3 consistency. For years S3 offered eventual consistency for certain operations, and applications built around that behavior, some depending on it in subtle ways. In December 2020 S3 moved to strong read-after-write consistency for all operations, at no additional cost and with no performance penalty [5]. The interesting thing from a Hyrum’s Law angle is that this was a strengthening: it could only remove surprises, not add them, which is exactly the kind of change a platform with a huge user base can safely make. (As of 2026 that strong-consistency behavior is the default and documented model [5].) Contrast that with a change that removes a behavior someone observed, which is the kind these platforms guard against for years.
Before: a loud break, fixed once. With agents: a quiet workaround, paid for on every call.
The AI twist: a loud failure traded for a quiet tax
Now the forward-looking part, and I want to be clear this is reasoned analysis as of 2026, not a benchmark.
The old sequence was blunt but honest. An API changes, the integration breaks loudly, a developer sees the failure, and fixes it once, usually by adopting a versioned client library. After that the behavior is deterministic and stable. The pain was visible and it was one-time.
Increasingly, APIs are abstracted behind layers like MCP and consumed not by a developer writing a client, but by an AI agent [4]. And an agent can do something a library cannot: when it hits a changed API, it can dynamically figure out its own way around the change, generating glue code on the fly. The end user often never notices the break. On the surface this looks like pure resilience, and that resilience is a genuine benefit. I am not arguing agents are bad here.
The point is what the flexibility costs. That workaround is generated, and it may be generated on every call, so you pay in latency and in spend for glue that a versioned library would have done once, for free, forever. And each of those workarounds is bespoke, non-standard, non-deterministic code, not a well-tested library with a stable contract. That raises the odds of behavior that is subtly wrong, and wrong differently from one call to the next. Agents take a hard, visible failure, the kind you fix once, and turn it into a soft, recurring, variable tax you might not even see on the invoice for a while.
Which is the opposite of “MCP and agents make versioning obsolete.” They make API discipline matter more, because the failures they paper over are the ones that used to force you to fix the root cause.
If you’re running this on AWS
- Version explicitly. Use API Gateway stages and versioned routes so a change is a new version, not a silent mutation of an existing one. Consumers opt in.
- Test the contract, not just the code. Consumer-driven contract tests catch the moment a downstream team starts depending on a behavior you consider incidental.
- Deprecate on evidence. Instrument real usage so you deprecate based on who actually calls what, not on what the docs say is safe to remove. This is exactly where usage telemetry earns its keep.
- Apply all of this to internal APIs too. They are contracts. Give them the versioning and telemetry you give the external ones, because Hyrum’s Law does not care about the org boundary.
Your API’s real surface area is not what you wrote down. It is everything a consumer can see, human or agent. So before your next “safe” change, the honest question is not “does this match the spec?” It is “what can someone observe today that they might already be leaning on?”
What behavior in your system is documented as an implementation detail, but has quietly become a contract?
More in this series
Continues from Conway’s Law and leads into Tesler’s Law (you can’t delete complexity, only choose who owns it). Sparked by the Laws of Software Engineering collection [6].
Sources
- [1] Hyrum’s Law — the canonical one-line statement.
- [2] Software Engineering at Google — Hyrum’s Law — the origin and the reasoning behind it.
- [3] xkcd 1172 — Workflow — the “spacebar heating” strip that captures the law perfectly.
- [4] Model Context Protocol — the spec behind APIs being abstracted for agent consumption.
- [5] Amazon S3 — strong read-after-write consistency — strong consistency for all operations since December 2020, at no extra cost.
- [6] Laws of Software Engineering — Hyrum’s Law — the collection that sparked this series.
About the Author
Stefan Christoph is a Principal Solutions Architect at AWS, focused on agentic AI, media & entertainment, and helping builders move from demo to production. He writes about AI architecture, developer productivity, and the future of software.
This is a personal blog. Opinions expressed here are my own and do not represent the views or positions of my employer.
❤️ Created with the support of AI (Kiro)