AbstractionGENERALSIMPLIFIEDILLUSTRATIVE

Abstraction Levels

"User clicks Buy" is also a POST, a service method, a SQL transaction, a set of database pages, a filesystem write and an SSD operation. Naming the levels a problem lives on — and which one you are standing on — is how you stop mixing questions from different levels into one confused one.

The moveWorked exampleNext questions

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.

The question

When a customer clicks Buy, how many different things are happening — and which of them is the one your problem is about?

The situation

A senior engineer asked me "at what level is that bug?" and I did not understand the question. Checkout is wrong sometimes. I have a stack trace, a slow query, a network tab, and a theory about the SSD; they all seem relevant and I cannot tell which one I should be looking at.

The reflex

Look everywhere. Open the browser devtools, the server logs, the query plan and the disk metrics at once, because the bug could be in any of them and the more evidence the better. Something will stand out.

Why it stalls

Evidence from six levels arrives in one pile, and none of it can be compared to any other. A slow query and a slow SSD and a slow network request are all "slow"; without knowing which level you are asking about, "slow" has no unit.

What the reflex produces — and fails to produce
  • Evidence from six levels arrives in one pile, and none of it can be compared to any other. A slow query and a slow SSD and a slow network request are all "slow"; without knowing which level you are asking about, "slow" has no unit.
  • A question from one level is answered at another. "Why did the order total come out wrong?" is a service-level question about which price was read; a day is spent on the query planner, which is correct and irrelevant.
  • Each level has its own vocabulary and tools, and jumping between them without noticing means learning none of them. The engineer reads about B-trees, TCP and React rendering in one afternoon and ends up with a theory that uses words from all three and applies to nothing.
  • When the bug is found it is fixed at the wrong level — a database timeout raised to hide a service that holds a transaction open while calling the payment provider — and the fix is a symptom being suppressed one floor down.
ProblemUnderstandRequirementsConstraintsUnknownsDecompositionSmallest StepModelExperimentObserveDebugLearnIterate

The move

Precisely enough to apply it to a problem you have never seen — not a slogan.

  • Write the stack of levels for the action in question. For "user clicks Buy": the user's intent → an HTTP request → the router and handler → the order service's logic → a SQL transaction → the database's pages and indexes → the filesystem and OS cache → the SSD. Each is a real thing that happens, each has its own language, and each is taught somewhere else in the atlas.
  • Place the problem on one level by asking what its *words* belong to. "The total is wrong" uses the words price and order, which are service-level words. "The request took long" is a request-level word. "Many pages read" is a database word. The level whose words the problem is stated in is where the investigation starts.
  • At that level, ask what this level *promises* to the one above and *requires* from the one below. A level is a contract in both directions; a problem is either a broken promise at this level or a broken requirement from below, and only the second sends you down.
  • Keep the levels separate in your notes. Evidence gets a level label; a hypothesis is allowed to cross levels only when it says which promise is broken. That discipline is what makes "at what level is that bug?" answerable in one sentence (Going One Layer Deeper).

What "click Buy" is, at every level

The stack for one action, top to bottom. Each row is a real event with its own vocabulary and its own domain in the atlas; the middle columns are the contract — what the level promises upward and what it needs from below. A problem is stated in one row's words and is either a broken promise in that row or a broken requirement from the row beneath.

LevelWhat happensPromises upwardRequires from belowTaught in
User intentthe customer decides to buy what the cart showsa clear actiona page that says what will be chargedFrontend
HTTP requestPOST /checkout with the cart ida response within the budgeta handler that finishesBackend: request lifecycle
Router → handlerthe request reaches the checkout handler with a parsed bodyvalidated input to the servicethe service to decideBackend: layering
OrderServicereads cart, captures prices, reserves stock, creates the orderan order that obeys the invariantsa transaction that is consistentDesign: invariants; this domain
SQL transactionBEGIN; reads and writes; COMMITatomic, consistent, durablepages read and written efficientlyDatabase: transactions
Pages and indexesthe B-tree finds rows; the buffer pool holds pagesrows found in few readsthe filesystem to deliver blocksDatabase: indexes, buffer pool
Filesystem and OS cacheblocks read from cache or disk; fsync on commitdurable bytesa device that writesOS: file reads, page cache
SSDblocks written to flashbytes persistnothing — this is the bottomHardware: storage path

Placing the problem

The three worked problems, placed. The compare shows the same "wrong total" investigation done the reflex's way and the move's way; the difference is not effort but whether the evidence was ever comparable.

Look everywhere
Devtools, server logs, EXPLAIN on the checkout query, disk latency graphs, all open. A slow query is found (there is always one) and "fixed". The wrong total persists, because the total was never a query problem.
Place, then check the promise
Words: checkout, total — service level. Promise: total equals the sum of captured prices. One log line per price read at checkout shows two sources. Fixed at the service; nothing below it was opened.

The problem's words named its level, and the level's promise gave a specific check with a yes-or-no outcome. Evidence from other levels could not have said yes or no to it.

The question, sharpened by level

The question ladder shows how naming the level turns a feeling into a check. The vague form could be asked of any row in the stack; the best form names a row, its promise, and the observation that would show the promise broken.

Question quality
vagueWhy is checkout broken sometimes?
betterIs the wrong total a backend bug or a database bug?
bestAt the service level, does the total the order service computes always equal the sum of the unit prices it captured from the cart at that moment — and if I log both for every checkout, in which cases do they differ?

why The best form names a level, states the promise that level makes, and proposes an observation that either breaks it or clears the level. The vague form has no level and so no observation; the middle form names two levels and asks someone else to choose, which is the senior engineer's question thrown back.

How to do it

Most important first.

  • For any problem, write the stack of levels for the action involved before touching a tool. It fits on one line and it usually has six or seven entries.
  • Underline the words in the problem statement and match each to a level. Start at the highest level whose words appear.
  • At that level, write what it promises upward and what it requires downward. Check the promise first; it is the cheaper check and it is where most bugs are.
  • Label every piece of evidence with its level before adding it to the pile. Two pieces from different levels are not comparable until you say how one level's promise depends on the other.
  • Fix at the level where the promise broke. If the fix is at a lower level than the symptom, say explicitly why the lower level is at fault (Debugging Is Problem Solving).

Worked on a concrete problem

The move has to produce something. This is what it produced.

  • "Checkout sometimes produces a wrong total." Words: checkout, total — service level. Promise at that level: the order total equals the sum of the captured unit prices. Requirement from below: the transaction reads consistent rows. Check the promise first: a log of the prices read at checkout shows the service reading Product.price for one line and CartItem.price for another. The bug is at the service level; the query plan, the network tab and the SSD were never involved (Source of Truth).
  • "Checkout is slow on Friday evenings." Words: checkout, slow — request level. Promise: the request returns within the budget. Requirement from below: the service finishes quickly. Timing the handler puts the time inside the service; timing inside the service puts it inside the transaction; the transaction's time is inside one query. Now, and only now, the level is the database, and the words become index, pages, plan — the next lesson's zoom (Zoom In, Zoom Out).
  • "Sometimes the confirmation page shows before the order exists." Words: page, order exists — two levels at once, the browser and the service, which is the clue: the promise between them is the response, and the browser is navigating on a response the service sent before committing. Fixed at the level of the contract between them, not in either one alone.

How you know it worked

What now exists that did not before, and what question you can now ask.

  • You can write the level stack for the action in one line and say which level the problem is stated at.
  • Each piece of evidence in your notes has a level, and the hypothesis says which promise between which two levels is broken.
  • The senior engineer's question has a one-sentence answer, and it names a level that the fix will be at.

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.

Next questions
  • ?What are the levels of the action this problem is about, from the user's intent to the hardware?
  • ?Which level's words is the problem stated in, and what does that level promise upward and require downward?
  • ?Is this a broken promise at this level, or a broken requirement from the level below — and what evidence distinguishes the two?
  • ?At which level will the fix be, and is that the same level as the symptom?

What can go wrong

How the move itself fails
  • The stack is written and then treated as a checklist to inspect top to bottom regardless of the problem. The stack tells you where the words point; it is not an order of investigation.
  • Every level is investigated to the same depth, because thoroughness. A total that is wrong at the service level does not need a database page count, and collecting one is motion.
  • The levels become silos: "that is a database problem, not mine". The move is to know the level so you can reason about the contract with the next one, not to stop at your team's floor.
  • The wrong stack is written — a generic "frontend, backend, database" — and the problem is placed on a level that does not exist in it. The stack is specific to the action; checkout's stack has a payment provider in it, and the product page's stack does not.
What the move costs
  • Writing the stack and labelling evidence is overhead on a bug that was obvious from the stack trace; the discipline pays on the intermittent ones.
  • Starting at the level the words point to means sometimes starting one level too high and descending; the alternative — starting from the lowest level with the most detailed tools — occasionally wins and usually drowns.
  • Knowing the levels well enough to name their contracts is a lot of learning across domains; the atlas exists because the levels are each a subject, and this lesson can only name them.
Misreads
  • "Higher levels are abstractions and lower levels are what really happens." Every level really happens. The order service really decides a total; the SSD really writes a block. "Abstraction" means each level can be reasoned about without the one below, not that it is less real.
  • "A good engineer works at the lowest level." A good engineer works at the level the problem is at, and can go down when the contract is broken. Living at the SSD makes wrong-total bugs invisible, because they have no representation there.
  • "So frontend, backend, database is the stack." That is three of seven levels, and it omits the request, the transaction, the OS and the hardware — which are exactly the levels that the hard performance bugs live on.

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 action in every system has a level stack; a chat message has one from the keystroke to the socket to the storage engine, and a model call has one from the prompt to the GPU. The move — place the problem by its words, check the promise first — is the same.
  • SIMPLIFIEDThe seven-level stack is a teaching model. A real checkout has more levels (TLS, the connection pool, the query planner, the block layer) and some of them blur; the point is that levels exist and can be named, not that there are exactly seven.
  • ILLUSTRATIVEThe three checkout problems and their investigations are invented to show placing a problem on a level; a real intermittent total bug can have several causes and the lesson picks one.

Where the depth lives

This domain asks the question and hands the answer off by name.