These are architectural principles stated as laws. They are design advice that applies in well-defined circumstances — not always, not never.
The Observation: Organisations which design systems are constrained to produce designs which are copies of the communication structures of those organisations.
The practical version: Teams own modules. Module dependencies follow team communication patterns. If you want a clean service boundary between payments and orders, you need a clean team boundary between the payments team and the orders team.
The inverse Conway maneuver: Design the team structure you want first. The architecture will follow. This is the most actionable application of Conway’s Law.
The Observation: A complex system that works invariably evolved from a simple system that worked. A complex system designed from scratch never works.
The engineering implication: Start with the simplest system that could possibly work. Add complexity only when a simpler approach demonstrably fails. Big-bang rewrites of working systems to a more elegant architecture fail at high rates.
The mitigation: Strangler Fig pattern for system replacement: wrap the existing system in a new interface; incrementally replace implementations behind it; never do a big-bang cutover.
The Observation: Be conservative in what you send; be liberal in what you accept.
The engineering application: Parse inputs
permissively — handle multiple date formats, accept both
user_id and userId as field names. Produce
outputs conservatively — always send a single canonical format. This
makes systems more robust to the variations that appear in
production.
The critique: Postel’s Law can be taken too far. A system that accepts too wide a range of inputs silently may never surface encoding errors until they become Silent Data Corruption (FM9). Apply it with judgment: be liberal in accepting variation that does not affect correctness; be strict about variations that do.
The Observation: All non-trivial abstractions, to some degree, are leaky.
The engineering implication: Every abstraction will eventually require its users to understand the implementation it was supposed to hide. The JPEG compression codec is an abstraction over image encoding — until you notice image artefacts and need to understand why. The TCP socket is an abstraction over packet routing — until you need to tune kernel buffer sizes. The ORM is an abstraction over SQL — until you need to write a query the ORM cannot express efficiently.
The design consequence: Knowing the layer below your abstraction is always valuable, even if you are not required to use it routinely. The depth of knowledge required is inversely proportional to the quality of the abstraction.
The Observation: With a sufficient number of users of an API, all observable behaviours of your system will be depended upon by somebody, regardless of what the spec says.
The engineering implication: Every observable behaviour of a public API is a contract — including behaviours you consider implementation details. The order of fields in a JSON response. The range of values a counter returns. The encoding of an error message. Once enough clients exist, someone depends on each of these.
The mitigation: Before publishing an API, decide explicitly what you want callers to depend on. Make that visible and stable. Make everything else invisible (not in the response, not in the headers, not in the error messages). Once behaviour is published, treat it as a contract.