Skip to content
Preptima

Architecture and tech leadership fundamentals

Architecture as a practice rather than a diagram: which decisions are expensive to reverse, how to elicit an attribute nobody stated, where a boundary belongs, and how a migration is sequenced. Fifty-six items, thirteen worked through with an ADR, a table or a diagram.

56 questions

Go deeper on Architecture & Tech Leadership
Standard Sheet View

What an architect actually does

What is architecture, if it is not the diagram?

The set of decisions that are expensive to reverse. Which language a single handler is written in is not architecture, because you can rewrite it on a Tuesday; how services are partitioned, what the data model of the core entity is, whether communication is synchronous, and which vendor holds your identity are architecture, because undoing any of them means coordinated change across teams and a data migration. The diagram is an output, and often a stale one. The useful test on any decision is to ask what it would cost to change your mind in eighteen months, and to spend design effort in proportion to that answer rather than in proportion to how interesting the decision is.

What does an architect do that a senior engineer does not?

Work at the seams. A senior engineer is accountable for a component being correct, fast and maintainable; an architect is accountable for the properties that no single component owns — how the system behaves when a dependency is slow, whether two teams can deploy independently, whether the whole thing still makes sense after the next three features. That means most of the work is elicitation, negotiation and writing rather than code. The failure mode of the role is producing decisions nobody implements, which is why the good version stays close enough to the code to be corrected by it.

Show me an ADR written out in full.

Candidates describe ADRs in the abstract constantly and rarely produce one, so the shape is worth having ready.

ADR 014 — Use an outbox table for order events

Status:   Accepted
Date:     2026-04-18
Deciders: Payments team, platform architecture
Supersedes: none

Context
  Order state changes must reach fulfilment and analytics. Today the service
  writes the order, commits, then publishes to the broker. Over the last
  quarter we have found 37 orders with no corresponding event, all after
  instance restarts. Fulfilment reconciles nightly, so the business impact is
  a delay of up to 20 hours on affected orders.

Decision
  Write the event into an `order_outbox` table in the same transaction as the
  order. A relay process polls the table, publishes, and marks rows sent.
  Consumers deduplicate on the event id.

Consequences
  + One durable decision point; the lost-event class of bug is eliminated.
  + No new infrastructure; the table lives in the existing database.
  - Delivery becomes at-least-once, so every consumer must be idempotent.
    Fulfilment already is; analytics needs a change, tracked as PAY-2210.
  - The outbox table needs pruning; added to the existing retention job.
  - The relay is a new operational component with its own lag metric.

Alternatives considered
  Change data capture on the orders table — rejected for now: it removes the
  relay but couples consumers to our schema, and we would still need an
  event-shape translation layer.
  Publish first, then write — rejected: produces the mirror bug, an event for
  an order that does not exist.

Four things make this an ADR rather than a design document. The context contains a number, so a reader in two years can tell whether the pressure that forced the decision still exists. The consequences include the ones we dislike, because an ADR listing only benefits is advocacy and will be distrusted the first time a cost surfaces. The rejected alternatives are recorded with reasons, which is what stops the same argument being had quarterly by whoever joins next. And it has a status, so superseding it later is an act of authorship rather than a contradiction.

What does not belong: the class diagram, the sprint plan, or the rationale for anything cheap to reverse. An ADR is for the decisions you will be asked to justify after the people who made them have left.

What is the difference between a functional and a quality-attribute requirement?

A functional requirement says what the system does — a user can cancel an order. A quality-attribute requirement says how well it must do it — the cancellation is reflected in the warehouse within thirty seconds for the 99th percentile, and survives one availability-zone failure. Functional requirements are usually written down because someone wanted the feature; quality attributes are usually assumed, and they are what actually drives architecture. Two systems with identical feature lists and different availability and latency targets are different architectures. That asymmetry is why an architect's first job on any brief is to extract the second list, which nobody has written.

Why is an architect who does not read code a warning sign?

Because the decisions are validated in the code, and without that feedback loop the architecture drifts into fiction. The specific failure is prescribing something the codebase cannot absorb — a boundary that cuts through a class every feature touches, a caching layer whose invalidation the existing write paths make impossible — and never learning, because the team quietly works around it and the diagram still says otherwise. Reading code is also how you find out what the real architecture is, which is frequently not the documented one. The point is not that the architect should be the fastest coder; it is that decisions need to be falsifiable by contact with the system.

What makes a decision reversible, and why does that change the process?

A decision is reversible when undoing it touches one deployable unit and no persisted data, and irreversible when it has been written into a schema, a public API, an external contract or another team's code. The consequence is that process should scale with reversibility rather than with visibility. Choosing an internal library needs a conversation; choosing the identity provider or the partition key of your largest table needs a written decision, alternatives and a named owner. Teams get this backwards constantly, running heavyweight review over easily reversed choices while irreversible ones happen in a pull request nobody senior read.

Who owns an architectural decision?

Whoever will operate the consequence, with the architect accountable for the decision having been made properly rather than for making it. That distinction is what separates an architecture function that scales from a bottleneck: the architect's deliverable is often the framing — here are the three options, here is what each costs, here is the attribute we are optimising — and the owning team chooses. Decisions that cross team boundaries or bind the organisation are the exception and are genuinely the architect's to make. Ownership must be recorded, because an unowned decision decays into an unwritten convention and then into an argument.