Architecture Is About Change¶
Architecture is one of the most overloaded words in software. It is used to mean diagrams, deployment topology, package structure, technology choices, and an unspecified mix of all of these. Most discussions about it are really discussions about something else: tooling preferences, team boundaries, or the layout of a particular codebase at a particular moment.
The framing that actually pays off is much simpler. Architecture is the set of design decisions that determine how expensive future change becomes. Everything else, including the diagrams, is downstream of that.
The Real Architectural Question¶
Most architectural decisions seem to be about which technology, which pattern, or which structure to choose at the moment of decision. They are really about a question that will not be asked for years: when this needs to change, how hard will it be?
The change in question is rarely the change anyone was planning for. It is the change nobody anticipated: a new regulatory requirement, a tenfold increase in traffic, a new product line, a new compliance regime, a vendor that has been acquired, a hiring market that no longer produces engineers for the chosen stack. Architecture is the work of leaving room for the changes that have not been named yet.1
This is why architecture is a business concern rather than a purely technical one. Change is a business concern. The cost of change is what determines whether a system can adapt to its market, or has to be rebuilt to meet it.
Properties That Make Change Cheaper¶
A few characteristics consistently lower the cost of future change, and the most useful definition of "good architecture" is the one that produces these characteristics:5
- Clear seams between components. Where one part of the system meets another should be a deliberate boundary, not an accident. Boundaries that match the way the business thinks about the work are usually right.2
- Stable interfaces, replaceable implementations. Code that depends on what something does, not how it does it, is code that can survive changes in the how. The interfaces become the long-lived asset; the implementations become disposable.
- Modularity at the right grain. Too coarse and changes ripple through unrelated code. Too fine and changes require updating many small pieces in lockstep. The grain that matches the rate of change in different parts of the system is the grain that pays off.
- Testability. Components that can be exercised in isolation can be changed with confidence. Components that can only be tested by running the whole system are components that no one will want to change.
- Observability. Systems whose behavior is visible from outside can be diagnosed, understood, and improved. Systems that hide their behavior accumulate fear; fear accumulates as friction on every change.
- Locality of change. When a typical change requires editing one or two files in one or two places, the architecture is paying for itself. When a typical change requires touching ten files in five components, the architecture is charging interest.
- Reversibility. Architectures that allow decisions to be undone cheaply support continuous learning. Architectures that bake in irreversible commitments force more decisions to be correct on the first try.
A useful test is to ask: "if our most important assumption about this system turned out to be wrong, how expensive would it be to change?" The answer is the architecture's grade.
Why "Best Architecture" Is Context-Dependent¶
There is no universal best architecture. Different systems have different rates of change, different scaling profiles, different team structures, and different operational requirements. An architecture that is well-suited to one of these is usually poorly-suited to another.
- A throwaway prototype's best architecture is whatever ships fastest. Investing in long-term flexibility is investing in flexibility that will not be exercised.
- A high-scale, low-change platform's best architecture optimizes for operational stability. Most changes will be operational, not structural; the architecture should make operational changes cheap.
- A high-change product's best architecture optimizes for the cost of structural change. Modularity, clear seams, and replaceable implementations carry their weight here.
- A small team's best architecture is a monolith for as long as possible.3 Distributed systems carry operational and coordination costs that small teams cannot absorb cheaply.
- A large team's best architecture often respects team boundaries.4 Conway's Law applies: communication structure shapes system structure. Architectures that fight team boundaries reliably lose.
The honest answer to "what is the best architecture for this system" is almost always "it depends on what is going to change about it, and how often, and at what cost."
Common Anti-Patterns¶
A few patterns reliably indicate that architecture is not earning its keep:
- Big design up front. A detailed architecture produced before the team has built anything, defended as the canonical truth, and slowly rendered obsolete by the work as it actually happens. The cost is paid in the gap between what was planned and what is needed.
- Architecture as a poster. A diagram on a wall that nobody updates and nobody trusts. The system's actual structure has moved on; the diagram is fiction; the team works around it rather than from it.
- Architecture as gatekeeping. A "no major change without architecture review" policy that quietly drives all the actually-major changes underground, where they happen without the structure the policy was meant to protect.
- Universal patterns applied uniformly. Every service should be a microservice. Every data model should be an event stream. Every interaction should be a REST endpoint. Pattern uniformity is appealing; pattern appropriateness is what produces good systems.
- Reactive architecture. The architecture is whatever shape the system happens to have taken on, with no deliberate decisions ever made. Sometimes this is fine. Sometimes it is the system charging architectural interest with no one tracking the bill.
What This Looks Like in Practice¶
A few habits keep architecture about change rather than about diagrams:
- Decide which changes you are optimizing for. A team that knows what it expects to change can architect for those changes. A team that does not is making assumptions about the future without examining them.
- Make architectural decisions explicit. Architecture Decision Records (ADRs) or equivalent lightweight documents capture not just what was decided but why, which is the only part that helps later when the decision needs to be revisited.
- Build fitness functions for the properties that matter. If "the system should be deployable independently" is a real architectural goal, then verifying it should be automated, not aspirational. Evolutionary architecture treats these checks as first-class artifacts.1
- Refactor architecture in small steps, not in rewrites. Architecture that needs to be wholly replaced was usually wholly replaced once already, and once before that. Incremental change is almost always cheaper, even when slower.
- Watch the cost of typical changes. If similar small changes are taking longer over time, the architecture is the likely cause. The metric is the team's reported friction, not any specific diagram.
- Resist architecture as a deliverable. Architecture is not a document or a phase. It is the cumulative effect of design decisions made over the life of the system. Treating it as a one-time output produces documents that age and systems that diverge from them.
Key principle
Architecture is a business concern because change is a business concern. The cost of every change you will ever make to this system is paid against the architecture you chose. Good architecture is not the one with the cleanest diagram. It is the one that makes the changes you have not yet thought of cheap to perform.
See also: Maintainability, Technical Debt, Monolith First, Trunk-Based Development, Systems Thinking, Software Is Economics.
-
Neal Ford, Rebecca Parsons, and Patrick Kua, Building Evolutionary Architectures: Support Constant Change (O'Reilly, 2017; 2nd edition with Pramod Sadalage, 2023). The canonical articulation of architecture as a property that supports continuous change rather than resists it, including the formal concept of "fitness functions" as automated verification of architectural characteristics. ↩↩
-
Eric Evans, Domain-Driven Design: Tackling Complexity in the Heart of Software (Addison-Wesley, 2003). The originating argument that software structure should mirror the structure of the business domain it serves, and that the bounded-context concept gives teams a principled way to draw seams between components. ↩
-
See Monolith First for the longer argument. The short version: most successful microservice architectures started as monoliths and were decomposed as the team learned where the seams actually were. ↩
-
Melvin E. Conway, "How Do Committees Invent?" (Datamation, April 1968). The originating paper for "Conway's Law": the observation that a system's architecture tends to mirror the communication structure of the organization that built it. ↩
-
Mark Richards and Neal Ford, Fundamentals of Software Architecture: An Engineering Approach (O'Reilly, 2020), and the follow-up Software Architecture: The Hard Parts (O'Reilly, 2021). The most thorough modern treatment of "architecture characteristics" (the operational "ilities" like scalability, observability, deployability, and modularity) as first-class properties that architectural decisions trade against each other, and the discipline of making those trade-offs explicit rather than implicit. ↩