Postel's Law and the Three Ring Circus
Postel’s Law famously states that “implementations should follow a general principle of robustness: be conservative in what you do, be liberal in what you accept from others.” For many years, this was considered a bedrock design principle for internet ecosystems, but in recent years it has fallen out of favor. In this post I will explain the deterioration that ecosystems which endeavor to follow Postel’s Law frequently experience, and why it produces particularly pernicious results in the context of open source software.
Postel’s Law is the general proposition that software that produces (or sends, or serializes) data should be conservative, that is to say it should strictly follow the relevant specification; and software that consumes (or receives, or parses) data should be liberal, that is to say it should permit deviations from the relevant specification. This was considered to promote robustness, because it allowed data-consuming systems to continue to function and accept data, even in the face of some degree of bugs in data producing systems.
This is a key observation: if everyone followed Postel’s Law, there would be no need for anyone to be liberal in what they accept, because everyone would be conservative in what they produce. But, because people are in fact not conservative in what they produce, consumers must be liberal in what they accept. In practice, this means there are asymmetric obligations: because we know that producers will not follow Postel’s Law, consumers must follow it. Ecosystems that adhere to Postel’s Law therefore experience a one way ratchet: consumers must accept more and more deviations from the specifications, and because consumers accept the deviations, producers are never forced (or incentivized) to themselves become stricter in following the specifications. Over time, deviance normalizes.
An ecosystem attempting to follow this principle, after several turns of the evolutionary crank, will find itself in a state that has a number of problems. First, it will be difficult to characterize what the precise behavior of the system is, because while most consumers accept various deviations from the written specification, there’s no guarantee they all have the same behaviors and nowhere is it documented which deviations are required in practice. Second, it will become impossible for new implementations to be created by reading the specification (or indeed, any written document), new implementations will need to either build corpuses of real world data to test against, or iteratively make themselves more lax as users attempt to use them in real world scenarios. Finally, it will be more difficult to make changes to the written specification, because it will be difficult to know if they are incompatible with the de facto behavior of implementations used in the wild.
I want to focus on the second of those problems for a moment: that the need to be liberal in accepting undocumented deviations from the specification make it difficult to create new implementations of the specification. This acts as a barrier to entry for new implementations, and thus reduces the number of implementations in the ecosystem. Fewer implementations, means less competition. Competing to produce the best implementation is one of the best ways we have of driving improvements to things like security, performance, and readability (or best of all, pareto optimal improvements along multiple axes). For this reason, the maladaptive pressures of ecosystems following Postel’s Law can produce evolutionary dead ends, where improvements in any direction are rare. Indeed, the strongest competitive pressure in such an ecosystem will be: any malformed data that some other implementation accepts must be accepted by all implementations.
These pressures are particularly pernicious in the context of open source. Imagine a situation with three participants: 1) a closed source product that produces data, 2) an open source project that consumes data, 3) a user attempting to use the open source software to parse data from the closed source product (I call this group a three ring circus). We already know the basic dynamics of the asymmetric nature of Postel’s Law: if the producers deviates from the specification, there’s a strong tendency to say its the consumers responsibility to be more liberal and accept the (in principle) malformed data. But when one of the participants is an open source project and the other is commercial, there’s an additional distorting effect: open source projects are way easier to complain to. Effectively all open source projects have public bug trackers where anyone can file an issue, and issues are directly received by developers of the software. In contrast, commercial projects do not offer direct access to their bug tracker, bugs are instead mediated by support systems which are only available to paying customers, and which must be triaged by support staff before they make their way to developers. Simply put, a developer encountering a situation where an open source project is strict in rejecting data produced by a closed source product, it will be dramatically easier for them to complain to the open source project, no matter how unreasonable the deviation from the specification is. Thus, people will complain to volunteer maintainers who are correctly implementing a specification instead of to large commercial software vendors who are not.
For these reasons, I encourage software engineers, and particularly open source maintainers, to be rigorous in following specifications and rejecting deviations from it to the maximum extent practical while still having a useful piece of software. And in particular, I encourage maintainers to reject user feedback that is much more properly directed to some commercial software vendor who has not implemented the specification correctly. If you’re the author of a standard that really does want lax parsing behavior, the correct solution is to document the behavior you’d like in all circumstances, as was done by the HTML5 specification. But for all other specifications, we need to reject the endless spiral of becoming more and more liberal, and more and more detached from the specification.