Hyrum’s Law

“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.” — Hyrum Wright, Google

The Claim

Every observable behaviour of your system is part of its interface — whether you documented it or not. At sufficient scale, the formal contract (specs, type signatures, OpenAPI schemas) becomes a polite fiction. Users depend on:

  • Error message text — parsed for matching, logged for monitoring.
  • Iteration order of “unordered” collections — tests rely on it.
  • Performance characteristics — “this call returns in under 10ms” becomes load-bearing.
  • Bug behaviour — users work around a bug in a way that later requires preserving the bug.
  • Memory layout — parsed from core dumps, depended on by instrumentation.
  • Error codes that aren’t in the documentation.
  • Side effects you didn’t realise were visible.

The empirical upshot: you cannot change behaviour without breaking someone, because you cannot enumerate what anyone depends on.

Why It Holds

The mechanism is combinatorial. The documented surface of an API has ~10² visible behaviours (endpoints, methods, parameters); the actual observable surface has ~10⁶ (timing, ordering, internal state leaks, error paths). Users explore the full surface incidentally, and some fraction of them couple to each observable. As the user count grows, the probability that every observable has at least one dependent approaches 1.

The Canonical Stories

  • Python 2 → 3. The language’s official spec was stable; what broke were the thousand undocumented behaviours — string vs. bytes semantics, print as statement vs. function, dict ordering, integer division. The transition took ~12 years because Hyrum’s Law bit everywhere at once.
  • Linux kernel syscall stability. Linus Torvalds’s famous policy: “we don’t break userspace.” He enforces it to the letter — including preserving bugs that applications depend on. This is Hyrum’s Law converted into a first-principle rule.
  • Google Chrome User-Agent string. A string that was meant to be cosmetic is now one of the most load-bearing strings on the internet; every attempt to simplify it breaks a non-trivial fraction of the web.
  • “Don’t parse the error message.” And yet everyone does.

In This Wiki

  • Close cousin to law-of-leaky-abstractions. All non-trivial abstractions leak; Hyrum’s Law says leaks get depended on. Together they explain why clean interfaces are an aspiration, not a reality.
  • Relates to law-of-unintended-consequences. Every change to a complex system produces surprises; Hyrum’s Law identifies the specific mechanism — undocumented-observable dependencies.
  • Connects to principle-of-least-astonishment. If users depend on observable behaviour, deviations from convention (even when the spec permits them) produce astonishment, which produces bugs, which become dependencies, which constrain future changes.
  • Inverts YAGNI. YAGNI says don’t build what you don’t need. Hyrum’s Law says you’ve already built more than you realise — your system exposes functionality you didn’t intend.

Practical Implications

  1. Versioning is cheap; breaking changes aren’t. If you might ever need to change behaviour, version the interface from day one.
  2. Test what you intend to support. Anything not tested is implicitly defined by implementation. Write tests for the contract, not the current behaviour.
  3. Randomise incidental observables. If iteration order shouldn’t be part of the contract, shuffle it in dev builds. Go’s map iteration randomises deliberately to prevent Hyrum-Law coupling. Java’s HashSet does not, and became load-bearing.
  4. Expect emergent contracts. After any large user base forms, run the question: What are they depending on that we didn’t intend? The answer is usually more than the team assumes.

The Stability/Change Trade-off

The deeper point: there is no such thing as a stable API with many users, because users expand the interface faster than the provider can spec it. The only way out is to keep the user base small (private APIs, internal interfaces) or to accept that every change is expensive (public platforms, OS kernels, programming languages). Platform engineering is, in large part, Hyrum’s Law management.

Sources

  • source—laws-of-software-engineering — in the Architecture cluster.
  • Hyrum Wright — Google Tech Talks, ~2014; the law is now standard parlance and has a dedicated page at hyrumslaw.com.