If it depends is the honest answer to most architecture questions, then one of the biggest things it depends on is rarely said out loud: can you change your mind later? A decision you can reverse in an afternoon and one you’ll be living with for five years are not the same kind of decision, and they don’t deserve the same amount of agonising — yet we routinely give them the same meeting.
Two kinds of door
I’ve found no framing more useful than the one Amazon made famous: some decisions are two-way doors and some are one-way doors. A two-way door you can walk back through. Try it, and if the room on the other side is wrong, you return and pick another. A one-way door locks behind you. You’re committed, and getting back costs real money, real downtime, or real trust.
Most decisions are two-way doors, and we treat far too many of them as one-way. We convene the review board to choose a logging library. We debate folder structure as if it were load-bearing. Meanwhile the genuinely irreversible calls — the ones that should get the scrutiny — often slip through on a Friday afternoon because they didn’t look scary at the time.
What actually makes a door one-way
The weight isn’t about how important the thing feels. It’s about how expensive it is to undo once other things start depending on it. The reliably one-way ones, in my experience:
- Data you’ve already written. Schemas and migrations are the classic trap — once production rows exist in a shape, changing that shape is a careful, reversible-if-you-planned-it dance and a one-way cliff if you didn’t.
- Contracts other people build on. A public API, an event schema, a message format. The moment a second team or an external partner depends on it, you no longer own the timetable for changing it.
- A move from in-process to over-the-network. Splitting a system across a boundary you can’t easily un-split — distributed state, distributed failure, distributed debugging. Easy to do, expensive to walk back.
- Anything customers can see and come to rely on. URLs, identifiers, prices, the shape of an export. Behaviour people depend on becomes a contract whether you meant it to or not.
Almost everything else — how you’ve structured the code inside a boundary, which library sits behind an interface you own, how a feature is rolled out — is a two-way door wearing a serious expression.
The architect’s actual job: fitting more two-way doors
Here’s the part that took me longest to learn. The reversibility of a decision is not fixed by nature — a good chunk of architecture is deliberately turning one-way doors into two-way ones so you can afford to be wrong.
- That risky schema change becomes reversible if you do it expand/contract: add the new shape, write to both, migrate, then drop the old — each step independently safe to roll back, instead of one big-bang ALTER you pray over at 2am.
- A vendor you’re “certain you’ll never change” becomes replaceable the moment its model sits behind a boundary you own. I’ve swapped payment providers more than once at the same company and watched a finance function go from external to in-house and back — survivable every time, because the rest of the system only ever talked to our interface, never the vendor’s.
- A public contract becomes safe to evolve when you version it and support both sides through a transition, rather than flipping every caller at once.
- A release becomes reversible when you decouple deploy from release with a feature flag — the code ships dark, you turn it on for a sliver of traffic, and “undo” is a toggle, not a rollback deploy.
Every one of those is the same move: pay a small, deliberate cost up front to keep a door swinging both ways. It’s the same discipline that makes systems easy to delete — replaceability and reversibility are two names for the same virtue.
Let reversibility set the deliberation
Once you’re sorting decisions into the two kinds, a nice consequence falls out: how reversible a decision is should set how much you deliberate over it.
For a two-way door, the cost of deciding slowly usually exceeds the cost of deciding wrong. So decide fast, with whoever’s in the room, and let doing it teach you what a week of meetings wouldn’t. Reversibility is permission to move quickly.
For a one-way door, the asymmetry flips. Slow down, get more eyes on it, and — this is the bit people skip — write down why, because the reasoning is what the next person needs when they inherit the result and wonder what you were thinking. (That’s a post in its own right, on architecture decision records; another time.)
The expensive mistake is doing it backwards: agonising over the reversible decisions because they’re in front of you today, and rushing the irreversible ones because they didn’t announce themselves.
The honest caveat
Reversibility isn’t free. The expand/contract dance is more work than a straight migration. A boundary is real code to write and maintain. Versioning two API shapes at once is a tax you pay for a while. You can’t afford to make everything a two-way door, and trying to is its own kind of over-engineering — flexibility nobody ever cashes in.
So spend it where it counts. Ask of a decision: which kind of door is this, and can I cheaply make it the other kind? Most of the time the answer is “two-way, decide and move on.” Now and then it’s “one-way — and worth a real boundary to make it less so.” The skill isn’t having a strong opinion on every door. It’s noticing, before you walk through, which ones lock behind you.