Galls' law
A complex system that works is invariably found to have evolved from a simple system that worked. — John Gall
Software engineering as a discipline is primarily about managing complexity. And often we are own worst enemies.
Let me give you a tale of two startups.
They’re making nearly identical products start their new companies. Let’s call them Banana and Orange.
They both get $1M in seed money. They’re in a hot space. Everyone is moving fast.
Banana sets off to make the entire thing as complete as possible. They’re worried about customer load, so they ensure they have a microservices architecture on kubernetes. Additionally, their API has all the things: REST, GraphQL, and MCP. There’s even some Websockets and SSE needed too. They are making developer kits in Typescript, Python, Golang, Rust, and Zig.
Orange makes a landing page with a sign up form. It’s a Squarespace, Caard, or even Wordpress. And they manually onboard people to their MVP, which they made over the weekend which is in Rails.
At the end of the week, Orange lets in their first traunch of users, and it falls over with the first 100 people, and they refactor some dumb loops in the frontend that caused the outage. Meanwhile Banana hasn’t launched yet but they promise it’ll be amazing when it does in probably the end of the month.
Many would want to work at Banana because they give you time and space to figure out the “right way” to do things. They’re using cool tech, and they have lots of different ambitious things.
Orange feels a bit yucky to software engineers. It chose tech that as of this moment is a bit passe. They looked foolish for something so “ancient”. And yet they’re the one with users.
In practice:
Gall’s Law aligns with modern software development approaches, which emphasize delivering working software early and evolving it based on feedback.
These concepts stands in contrast to waterfall approaches that attempt to specify complex systems completely before implementation begins.
Implications for system design:
- Start with simple, working systems and evolve them
- Embrace iterative approaches to system development
- Recognize the limits of human ability to design complex systems a priori
- Value working simplicity over non-working sophistication
- Understand that evolution requires both variation and selection
Tactical things to do to accomplish this:
- Prototype-driven development to test assumptions early
- Minimum viable products as starting points for evolution
- Incremental architecture that grows with validated needs
- Feature flagging to manage controlled evolution
- A/B testing as a mechanism for evolutionary selection
History: John Gall, General Systemantics: An Essay on How Systems Work, and Especially How They Fail, Quadrangle/NYT Book Co., 1975; republished as The Systems Bible, 1986.