Trade-Off Thinking
"Which is better?" has no answer; "better at what, and worse at what?" does. Every engineering choice moves along simplicity, performance, reliability, cost, security, time and maintainability at once, and the move is naming which ones this decision actually touches before comparing anything.
The situation, the reflex, and why it stalls
Every lesson starts where being stuck starts: someone has a problem, and the first move that comes to mind feels like progress.
Two designs are on the table and the argument has gone round three times — how do you turn "which is better?" into a question with an answer?
Where should the cart live? One person says the browser, because it is simple and fast; another says the server, because it is reliable and the customer can switch devices. Both are right, both know it, and the meeting is on its third loop. You are supposed to decide and you cannot see what would settle it.
Look for the winner. Search "server-side vs client-side cart", read what the big stores do, ask the AI which is best practice, and hope that one option is simply correct so the argument can end. It is natural: a decision feels like it should have a right answer.
The search returns both answers with equal confidence, because both are right for the systems that wrote them up. "Best practice" turns out to be a description of somebody else's constraints.
- The search returns both answers with equal confidence, because both are right for the systems that wrote them up. "Best practice" turns out to be a description of somebody else's constraints.
- The AI picks one and gives reasons; asked again with different wording it picks the other. Neither answer names which of your requirements it was weighing, because you did not tell it, because you had not named them.
- The argument continues in the vocabulary of "better", which is why it loops: each side is scoring a different axis and calling the result "better". Simplicity and reliability are not disagreeing; the people are, about which matters.
- A decision is eventually made by fatigue or seniority and recorded as "we went with the server". Six weeks later nobody can say what it was traded against, so the same meeting happens again when the constraint changes.
The move
Precisely enough to apply it to a problem you have never seen — not a slogan.
- Refuse "better" and replace it with "better at, worse at". Every design is a position on several axes at once — the usual seven are simplicity, performance, reliability, cost, security, time to build, and maintainability — and a choice is a movement along some of them in exchange for others. The first job is not to score; it is to name which axes this particular decision moves and which it leaves alone.
- For each axis the decision touches, ask what the requirement is — not what would be nice. The cart needs to survive a refresh (reliability of one kind); it may or may not need to survive a device change (a requirement to check, not to assume); it must never charge for items that were not in it (an invariant that both designs must honour and that therefore does not distinguish them).
- Compare the options only on the axes that both the decision moves and the requirements care about. Everything else — the axis the decision does not move, the axis nobody requires — is noise, and most of the argument was about noise.
- Say the trade out loud as a sentence with both halves: "we take the server-side cart, paying a round trip on every change and a table to maintain, for a cart that survives devices and can be reasoned about on the backend." If the sentence cannot be written, the decision is not yet understood; if it can, write it down where the next meeting will find it (The Decision Journal).
"Which is better?" climbed to a question with an answer
The reflex question and its decisive form. The vague rung asks for a winner; the better rung asks for the axes; the best rung asks for the requirement that decides between them, with its source. The last is the only one that ends a meeting.
why The best form is answerable by one conversation with the founder and ends the argument, because it names the requirement that distinguishes the designs and asks whether it exists. The vague form has no answer; the better form produces a matrix that still needs weights.
The cart, on the axes it moves
The matrix shows the two options on the four axes the decision moves. The scores are relative positions, not measurements — a 4 against a 2 says "noticeably better here", nothing more — and the caveat says what the numbers cannot: which axis the requirements weight, which is the whole decision.
Security and cost are left off deliberately. Both designs validate prices at checkout and neither costs anything to speak of; putting them in the matrix would give one option points for an axis the decision does not move.
| Option | Simplicity | Performance | Reliability | Maintainability | Time | Note |
|---|---|---|---|---|---|---|
| Browser (local storage) | No table, no endpoint, no round trip. Lost when storage is cleared or the device changes; totals end up computed in two places. | |||||
| Server (cart table) | A table, endpoints, a round trip per change. Survives devices; one place for totals and stock checks. |
caveat The scores are relative, not measured, and they do not contain the decision: the decision is which axis the requirements weight, and here one sourced requirement — surviving a device change — is met by one option only. A store whose founder said device switching is rare would keep the same scores and choose the other row.
When an option arrives with a technology attached
Trade-off arguments often begin with a tool in the claim — "we need a Redis-backed cart". The ladder is how the tool is separated from the requirement so the axes can be named at all. It ends, as it must, with the case where the claim was right.
“The cart should live in Redis.”
- ↓Why Redis? Because cart updates need to be fast and the cart is temporary data.
- ↓Why do they need to be fast, and how fast? A customer changing a quantity should not wait — but there is no latency requirement beyond "not noticeably slow", and a single-row update in the main database is not noticeably slow.
- ↓Why does "temporary" matter? Because it seemed wrong to put throwaway data in the orders database. But abandoned carts are a thing the founder wants to see, so the data is not throwaway.
the claim was right when Cart writes are measured as a real load on the primary database, or the cart is expected to be dropped at scale without ever needing to be queried — a flash-sale store with millions of anonymous carts and no interest in abandonment is the case where the original claim was right.
How to do it
Most important first.
- Write the seven axes down and cross out the ones this decision does not move. For the cart, security barely moves (both designs must validate at checkout) and cost barely moves (a small table). Four remain.
- For each remaining axis write the requirement in one line, with its source — the founder, a constraint, an invariant. A requirement with no source is a preference (Assumption vs Requirement).
- Ask the why ladder of any option that arrives with a technology attached ("we need a Redis-backed cart"): what is the requirement, what is the simpler thing, when was the claim right (The Why Ladder).
- Write the trade as a sentence with a "paying" clause and a "for" clause. Read it to the other side of the argument; if they would sign it, the decision is made.
- Record what would flip it. "If the founder confirms customers rarely switch devices, the browser cart wins on simplicity and time" — so the decision carries its own revisit condition (When Assumptions Change).
Worked on a concrete problem
The move has to produce something. This is what it produced.
- The cart, named. Axes moved: simplicity (browser wins: no table, no endpoint), performance (browser wins: no round trip per change), reliability (server wins: survives devices and browser storage being cleared), maintainability (server wins: one place to reason about totals; the browser cart eventually duplicates pricing logic). Axes not moved: security (both validate at checkout; neither trusts the client for prices), cost (negligible either way). Time: browser slightly faster to build. Two axes each way — which is why the meeting looped.
- Requirements, sourced. "Survive a refresh": both do. "Survive a device change": the founder, asked, says it matters for customers who browse on a phone and buy on a laptop — a real requirement that only the server meets. "Never charge for items not in the cart": an invariant both must honour at checkout, so it does not distinguish them. The argument collapses to one sourced requirement that one design meets and the other does not.
- The sentence: "We take the server-side cart, paying a round trip per change and a cart table to maintain, for a cart that survives a device change — which the founder says matters — and one place to compute totals. Revisit if guest checkout is added and anonymous carts make the table awkward." Both sides sign it. Notice that "better" appears nowhere.
How you know it worked
What now exists that did not before, and what question you can now ask.
- The argument has moved from "which is better" to "which axis matters more here", and that question has a source you can name.
- At least one axis has been crossed out as "not moved by this decision", and the option that was winning there has stopped citing it.
- The trade can be written as one sentence with a "paying" clause and a "for" clause that both sides accept.
- The decision carries the condition under which it should be revisited.
The questions you can now ask
The field this whole domain exists for. After this lesson, these are the questions to put to an unfamiliar problem.
- ?Which axes does this decision actually move, and which does it leave where they were?
- ?For each axis it moves, what is the requirement — and who or what is the source of it?
- ?What is the sentence: we take X, paying A, for B?
- ?What change in requirements would flip this, and where is that written down?
What can go wrong
- Seven axes, every time. A one-line function rename does not need a maintainability-versus-performance analysis; the move is for decisions that actually move several axes, and most decisions move one. Match the analysis to the decision (Reversible vs Irreversible Decisions).
- Axes with no requirement behind them. "Performance" is scored because it is on the list, not because the cart has a latency requirement, and the browser option wins a point for something nobody needs.
- Naming the axes and then voting. The point of naming them is to find the one the requirements decide; if the meeting ends with a show of hands, the axes were decoration.
- Treating the seven as complete. For a team with one deploy a month, "time to first release" may be an axis; for a regulated store, "auditability" is. The list is the usual set, not the only set (Trade-Off Dimensions).
- Naming axes and sourcing requirements takes a meeting that a coin toss would not; on a decision that is cheap to reverse, the coin toss and a note are often the better trade.
- A sourced requirement can be wrong — the founder may be guessing about device switching — and a decision built on it inherits the guess. The revisit condition is the hedge, and it only works if someone reads it.
- Crossing out an axis is a claim that the decision does not move it, and that claim is occasionally false: the browser cart's "no security difference" holds only while prices are validated at checkout, which someone will one day remove for speed.
- "So every decision needs a matrix." No — every decision that is argued in the vocabulary of "better" needs its axes named. Many decisions have one axis and an obvious winner; the matrix is for the ones that loop (The Trade-Off Matrix, Without Fake Precision).
- "The axes are objective, so the decision is." The axes are objective; the *weights* are the requirements, and the requirements come from people. Trade-off thinking makes the people's choice explicit; it does not remove it.
- "Best practice would have settled this." Best practice is the sentence somebody else wrote for their trade. It is useful for seeing which axes they moved and worthless for knowing which ones your store needs.
Where this applies
Problem-solving advice is stated as universal far more often than it is. These labels say what each method is specific to — and where CONTESTED appears, the note gives the strongest form of the opposing view.
- GENERALEvery engineering decision is a position on several axes, from a variable name (readability against brevity) to a datacenter; what changes is which axes move and how much effort the naming deserves.
- DOMAIN-SPECIFICWhich axes dominate depends on what is being built: a payments system weights reliability and security so heavily that simplicity is rarely allowed to win against them, while an internal dashboard can trade reliability for time almost freely. The seven are a default list, not a ranking.
- ILLUSTRATIVEThe cart argument, the founder's answer about device switching and the six-week gap are invented; the scores in the matrix are for the shape of the argument and would change with the requirements.
Where the depth lives
This domain asks the question and hands the answer off by name.
- — The manifesto's layers route at /manifesto/layers is the same idea applied to knowledge: every abstraction is a trade, and knowing which axes it moved is what lets you go a layer down when it fails.