Full course · No. 03
A course for the engineer who already writes code but wants to learn how to make architectural decisions, explain them to the team and the business, and see the system whole.
24 modules · 52 concepts · a diagram for each · cheat sheet at the end
- 01. Who the architect is
- 02. Trade-offs
- 03. Technical debt
- 04. Cognitive load
- 05. Decomposition
- 06. Layers and dependencies
- 07. APIs and contracts
- 08. Data model
- 09. State
- 10. Distributed systems
- 11. Monolith and microservices
- 12. Sync and async
- 13. Performance
- 14. Scalability
- 15. Reliability
- 16. Security
- 17. Observability
- 18. Documentation
- 19. Communication
- 20. Leadership without authority
- 21. Business and product
- 22. AI-native architect
- 23. Anti-patterns
- 24. Continuous growth
An architect differs from a senior engineer not because they know more technologies. They own the consequences of decisions over time.
Course map — 24 modules in six parts
A subway map: first you see all the lines at once, then you ride station by station.
The course goes from mindset to practice. First, how an architect thinks (mindset). Then how a system is built inside (structure) and what changes when it spreads across a network (distribution). After that come the quality properties (quality attributes), working with people (people), and where the profession is heading (future).
How to read it: every concept gets its English term (the one you'll search docs for and hear in interviews), an everyday image, a diagram, and a card with "what it is / example / cost / related" fields. At the end of the course there's a cheat sheet with every concept on one page.
Long-term thinking — the architect thinks in years
An engineer builds a bridge that a car will drive across tomorrow. The architect asks what happens when trucks start using it, when a new district goes up next door, and when repairs cost more than the bridge itself.
An engineer usually solves the problem as posed. The architect first checks whether the problem was posed correctly. That isn't snobbery or a wish to "talk about the deep stuff." An architectural decision is just usually more expensive to change than a line of code.
The main shift in the head: you stop asking only "how do I do X" and start asking "why do we need X, what are the alternatives, what will we lose, and what will this look like in three years".
- What it is
Judging a decision not only by "works tomorrow" but by how it behaves in one to three years.
- How it works
Before "how do I build X" — "why X", what the alternatives are, what we lose.
- Example
The bridge: will it carry trucks, a new district next door, repairs that cost more than the bridge?
- Catch
It's not a licence to build "for growth" — just a question you must ask.
- Related
- Reversible decisions, trade-offs, technical debt.
Reversible vs irreversible decisions — owning the shape of the system
If a carpenter hangs a shelf wrong, you can move it. If the designer puts a load-bearing wall in the wrong place, the house lives with that mistake for decades.
The architect isn't obliged to personally make every technical decision. But they are obliged to own the decisions that set the shape of the system: service boundaries, the data model, integration protocols, the scaling strategy, security, observability, the migration path.
The useful distinction here is between reversible decisions and irreversible decisions. A reversible decision can be changed in a day or a week: a logging library, a button colour, the internal structure of a small module. An irreversible or expensive-to-reverse decision changes the trajectory of the system: the database, the tenancy model, an API contract, the way events are stored, service boundaries.
- What it is
Sorting decisions by the cost of undoing them: days or weeks vs months or years.
- How it works
Reversible ones: decide fast, don't argue long. Irreversible ones: slowly, with alternatives and a written record.
- Example
A logging library is reversible. The tenancy model or an API contract nearly isn't.
- Catch
A week of debate over a reversible detail is as bad as deciding an irreversible one in an hour.
- Related
- Data model, API contract, service boundaries.
- What problem are we actually solving?
- What changes if load grows 10x?
- Which decisions here are reversible, and which are nearly not?
- Who's going to be maintaining this a year from now?
The architect doesn't build "the most correct system" — they build a system that survives reality.
There are no free decisions in architecture. Every choice buys one property at the cost of another.
Trade-off — best practice without context is bad advice
An SUV beats a sedan on a muddy road. The sedan beats the SUV in the city. A bicycle beats both if you need to go three blocks and there's nowhere to park.
You can't evaluate an architectural decision outside its context. REST, GraphQL, Kafka, PostgreSQL, Kubernetes, microservices, monolith — all of these are tools with a price. A trade-off is a deliberate exchange: latency vs. throughput, consistency vs. availability, time-to-market vs. maintainability, simplicity vs. flexibility.
The architect doesn't say "Kafka is better than RabbitMQ." They say: "we need per-key event ordering, high throughput, replay, and a durable log; in exchange we pay the operational complexity of Kafka." That's what professional language sounds like.
- What it is
A choice that buys one property at the cost of another — made out loud.
- How it works
Name what you gain, what you lose, and why that price is acceptable now.
- Example
"Per-key ordering, throughput, replay, a durable log — paid for with Kafka's operational complexity."
- Catch
- "X is better than Y" without context isn't an argument, it's taste.
- Related
- CAP / PACELC, over-engineering, sync vs async.
Over-engineering vs under-engineering — complexity is a tax
Every new abstraction is like another room in the house. The room can be useful, but it has to be cleaned, heated, repaired, and explained to guests.
Complexity is useful when it buys an important property: failure isolation, independent release, security, scaling, testability. But complexity "for the future" usually becomes a permanent tax.
The terms over-engineering and under-engineering are only useful together. Over-engineering: complexity showed up before the real pain. Under-engineering: the system has already hit limits, and the architecture left no room to grow. The architect's job isn't to pick an extreme — it's to hold the middle.
- What it is
Over: complexity before the real pain. Under: the system hit its limits with no path to grow.
- How it works
- Every new layer or service has to name the property it buys.
- Example
Microservices and Kafka at launch for 200 users — over. One table with no indexes when load grows 10x — under.
- Catch
- Complexity "for the future" doesn't go away — you pay for it every day.
- Related
- Trade-off, technical debt, cognitive load.
- Architecture: The Hard Parts — Ford, Richards, Sadalage, Dehghani
- Software Architecture in Practice — Bass, Clements, Kazman
- Martin Fowler: Is Design Dead?
Technical debt isn't always bad. What's bad is debt taken on by accident, not written down, and never meant to be repaid.
Technical debt — a loan, not garbage
A loan on equipment can accelerate a business. A loan for a party just leaves a hangover and interest.
Technical debt is a decision that speeds us up now but creates a future cost of change. Sometimes that's right: you need to test the market, hit a deadline, keep a customer. The problem starts when the team labels everything as debt: bad code, missing tests, chaotic dependencies, outdated libraries.
A useful model is Martin Fowler's Technical Debt Quadrant: deliberate / inadvertent and prudent / reckless. Deliberate-prudent debt: "we're skipping multi-region for now because we have 200 users and one market." Inadvertent-reckless debt: "we didn't know we needed transactions."
- What it is
A decision that speeds us up now but creates a future cost of change.
- How it works
Take it on deliberately, write down what and why, set a trigger for revisiting.
- Example
"No multi-region yet: 200 users, one market" — deliberate and prudent.
- Catch
If everything is called debt — bad code, no tests, old libraries — the word stops meaning anything.
- Related
- Debt interest, ADR (recording the decision), trade-off.
Debt interest — debt charges interest
If the road is broken, every trip takes five minutes longer. A month later it's no longer a pothole — it's a tax on the whole city.
The interest on technical debt is the slowdown of every next change. The more often the team touches an area, the more expensive the debt. That's why debt in the hot domain is more dangerous than debt in a rarely-used admin panel.
The architect negotiates a repayment strategy: what exactly counts as debt, what risk it creates, when we revisit the decision, what signal says "time to pay." Without that, "technical debt" becomes an emotional argument, not a managed instrument.
- What it is
- The slowdown of every next change in code that carries debt.
- How it works
- Interest ≈ slowdown × how often the team touches that area.
- Example
Debt in payments, changed weekly, costs more than debt in an admin panel opened once a quarter.
- Catch
Without a repayment strategy, "tech debt" becomes an emotional argument.
- Related
- Technical debt, cognitive load.
- Where is it written down why we took this compromise?
- What interest are we paying each sprint?
- What would have to happen for this debt to become a blocker?
- Is there a repayment plan, or at least a trigger for revisiting?
A system nobody can hold in their head will break even with strong engineers.
Cognitive load — architecture has to fit in a human head
A subway map is useful not because it shows every bolt in the tunnel. It shows lines, transfers, and direction of travel. That's enough to make a decision.
Cognitive load is the mental effort a system demands from an engineer. There's intrinsic load: the complexity of the domain itself. There's extraneous load: extra complexity from bad architecture, non-obvious links, accidental exceptions, and magic. The architect can't remove business complexity, but they're obliged to reduce accidental complexity.
A good module can be understood on its own. A good bounded context has its own language and its own invariants. A good team owns an area that fits in its head.
- What it is
How much context an engineer has to hold in their head to change something safely.
- How it works
Intrinsic is the domain's own complexity — it stays. Extraneous is accidental — cut it.
- Example
A module you can understand on its own vs one where nothing makes sense without the "magic" and exceptions.
- Catch
- Strong engineers can't save a system that doesn't fit in a head.
- Related
- Bounded context, Conway's Law, decomposition.
Conway's Law — team structure becomes system structure
If three departments don't talk to each other, their product almost always looks like three products glued together in one menu.
Conway's Law says: an organisation designs systems that mirror the structure of communication inside the organisation. If architectural boundaries don't match team boundaries, the team will keep crossing someone else's turf.
Team Topologies introduces useful labels: stream-aligned team, platform team, enabling team, complicated-subsystem team. That isn't HR fashion — it's an architectural tool. Sometimes the right decomposition of the system starts with the right decomposition of responsibility.
- What it is
A system mirrors the communication structure of the organisation that builds it.
- How it works
Align team boundaries with system boundaries: each team owns its own area.
- Example
- Three departments that don't talk ship "three products in one menu".
- Catch
If the boundaries don't match, teams keep stepping on each other's turf.
- Related
Team Topologies (stream-aligned, platform, enabling, complicated-subsystem), bounded context.
A big system becomes manageable only when you can cut it along the right boundaries.
Cohesion & coupling — cut by layers, by domains, or by data flow
A butcher doesn't cut a carcass at random — they cut at the joints. Good decomposition also looks for natural break points.
Decomposition isn't "sort into folders." It's choosing where responsibility ends. High cohesion means everything inside a component is about one thing. Low coupling means the component knows little about other components.
A horizontal cut gives you layers: UI, application, domain, infrastructure. A vertical cut gives you features or bounded contexts: billing, identity, catalog, comments. Real systems need both, but mixing one for the other is dangerous.
- What it is
Everything inside a component is about one thing (cohesion); it knows little about others (coupling).
- How it works
Cut horizontally (layers) and vertically (features / contexts) — and don't confuse the two.
- Example
A
billingmodule with its own UI → application → domain → infra layers.- Catch
- "Sorting into folders" isn't decomposition yet.
- Related
- Bounded context, layers, modular monolith.
Bounded context — a bad boundary gives itself away through change
If replacing the kitchen tap means tearing the bedroom apart, the problem isn't the tap.
A sign of bad decomposition: a small change ripples across five modules. Another sign: one module changes for different reasons — today because of product, tomorrow because of the database, the day after because of an integration.
The DDD term bounded context is useful precisely here. It's a boundary inside which words have a single meaning. "Customer" in billing and "Customer" in support can be different models. Forcing them into one often creates a brittle "universal" model.
- Problem
A small change ripples across five modules; one module changes for different reasons.
- Idea
- A boundary inside which every word has one meaning and one model.
- Example
- "Customer" in billing and "Customer" in support are different models.
- Cost
Models have to be mapped at the boundaries; translation between contexts.
- When to use
When one concept means different things to different parts of the business.
- Related
- Cohesion / coupling, Conway's Law, microservices.
Business logic should depend on business rules, not on the framework, the database, or HTTP.
Dependency Rule and DIP — dependencies flow toward the centre
The foundation shouldn't depend on the colour of the curtains. If it does, the house was designed backwards.
Clean Architecture, Hexagonal Architecture, and Onion Architecture all say the same thing: the important logic belongs at the centre, the details on the outside. HTTP, SQLAlchemy, Next.js, Kafka, Redis, Stripe — these are details. They matter, but they shouldn't define business rules.
The Dependency Inversion Principle says: high-level logic depends on abstractions, and implementations get plugged in from outside. In code that looks like ports and adapters: the service receives a PaymentGatewayProtocol, it doesn't construct a StripeClient inside itself.
- Problem
Business rules have grown into the framework and the database — you can't test or replace them.
- Idea
High-level logic depends on abstractions; implementations plug in from outside.
- Example
The service receives a
PaymentGatewayProtocolinstead of constructing aStripeClient.- Cost
- More interfaces and files.
- When to use
There are real business rules that must outlive technology changes.
- Related
- Clean / Hexagonal / Onion Architecture, ports and adapters.
Abstraction — it exists to absorb change, not to look nice
An adapter belongs where the plugs are actually different. If you put an adapter in every socket just because you like adapters, the house gets less safe.
Not every class needs an interface. But anything touching the outside world, time, randomness, the network, the file system, or the database should be replaceable in tests. Otherwise you're not testing business logic — you're booting a small production system inside a unit test.
The price of a layer is more files and more words. The payoff is testability, infrastructure that can be swapped, clean boundaries. If there's no payoff, the layer is dead weight.
- What it is
An interface goes where the implementation really changes or blocks tests.
- How it works
Time, randomness, network, files, database → behind a port; a fake in tests, the real adapter in production.
- Example
A business rule is tested without a database, HTTP, or real time — in milliseconds.
- Catch
- A layer with no payoff is extra files and words, not architecture.
- Related
- DIP, testability, over-engineering.
An API is a promise. Breaking a promise is easy; rebuilding client trust is hard.
API contract — the contract matters more than the transport
Passport control doesn't care about the brand of the door. What matters is which documents are accepted, which rules apply, and what happens when something is wrong.
REST, GraphQL, gRPC, and WebSocket are different ways to talk. REST suits resource-oriented APIs and simple caching. GraphQL helps when different clients need different shapes of read. gRPC is good for typed service-to-service communication. WebSocket is for real-time two-way events.
The transport choice is secondary. The API contract is what matters: schema, errors, idempotency, versioning, backward compatibility, deprecation policy.
- What it is
A promise: schema, errors, idempotency, versions, compatibility, rules for retiring the old.
- How it works
Agree on the contract first, then pick the transport for the job.
- Example
REST for resources and caching; GraphQL for varied reads; gRPC for typed service-to-service; WebSocket for real time.
- Catch
- Breaking a promise is easy; rebuilding client trust is hard.
- Related
- Idempotency, versioning, reversible vs irreversible.
Idempotency — it saves you from the real world
If you press the elevator button ten times, the elevator shouldn't arrive and leave ten times. It should understand the intent is one.
Idempotency means a repeated operation produces the same final effect. In networked systems, retries are inevitable: timeouts, retries, duplicate webhooks, worker restarts. If creating a payment, order, or message isn't idempotent, the system will eventually do something extra.
The architect designs idempotency at the contract level: idempotency key, unique constraints, safe retries, clear statuses.
- What it is
Repeating an operation gives the same final effect as the first call.
- How it works
An idempotency key in the request + a unique constraint in the database + clear statuses.
- Example
A payment times out → the client repeats
POST /paymentswith the same key → charged once.- Catch
Without it, repeats (retries, duplicate webhooks, worker restarts) eventually do something extra.
- Related
- At-least-once delivery, API contract, retries.
Code gets rewritten. Data migrates for years. That's why the data model is one of the most expensive architectural decisions.
Data model — data lives longer than applications
You can repaint a facade in a week. A foundation poured wrong reminds you of itself for the lifetime of the building.
The language, the framework, the UI may change several times. But tables, events, keys, relations, and historical records stay. A mistake in the data model often becomes a mistake in every future version of the product.
Normalization reduces duplication and the risk of drift. Denormalization speeds up reads and simplifies the read model. OLTP systems are optimised for transactions, OLAP for analytics. You can't design one model as if it will perfectly serve both classes of work.
- What it is
Tables, events, keys, relations, and history — what survives every rewrite of the code.
- How it works
Normalization means fewer duplicates and less drift; denormalization means faster reads.
- Example
- An OLTP database for orders and a separate OLAP store for reports.
- Catch
A mistake in the data model becomes a mistake in every future version of the product.
- Related
- Irreversible decisions, event sourcing, CQRS.
Event sourcing and CQRS — a strong tool, not a religion
A bank statement doesn't just store the current balance — it stores the history of operations. That's what lets you explain where the balance came from.
Event sourcing stores changes as a sequence of events and reconstructs current state from them. It's useful when history, audit, state recovery, and replay matter. The price is high: event schema evolution, query complexity, eventual consistency, demanding tooling.
CQRS separates the write model from the read model. It can dramatically simplify complex read systems, but it adds synchronisation and lag. Introducing CQRS just because "it sounds architectural" is an expensive way to turn one problem into two.
- Problem
- Current state doesn't explain how we got there.
- Idea
- Store changes as an event log; state = replaying them.
- Example
- A bank statement: the balance is the sum of operations.
- Cost
Event schema evolution, harder queries, eventual consistency, demanding tooling.
- When to use
- History, audit, state recovery, and replay matter.
- Related
- Often paired with CQRS.
- Problem
- One model serves both writes and complex reads badly.
- Idea
- Split the write model from the read model.
- Example
Orders are written to a normalized model; the reports screen reads a ready-made view.
- Cost
- Synchronisation and lag between the models.
- When to use
When reads are genuinely complex — not because "it sounds architectural".
- Related
- Event sourcing, denormalization, eventual consistency.
State is complexity that lives somewhere. The more copies of the truth, the more ways to be wrong.
Single source of truth — doesn't mean single database
A company can have many reports, but there has to be one official payroll register. Otherwise payday turns into theatre.
Single source of truth means that for every important fact, you know where the authoritative version lives. A cache, a search index, a read replica, a materialized view — these are derived copies. They can be useful, but they shouldn't pretend to be the primary truth.
Stateful components hold state and demand care: transactions, locking, recovery, backup. Stateless components are easier to scale and replace, but they still depend on state living somewhere else.
- What it is
For every important fact, it's clear where its authoritative version lives.
- How it works
One primary record; the cache, index, replica, and view are derived copies.
- Example
- Many reports, but one official payroll register.
- Catch
It doesn't mean "one database for everything" — it means "one owner per fact".
- Related
- Stateful / stateless, cache, CQRS.
Cache and locking — a second truth that sometimes lies
The schedule on the fridge is convenient, until someone moves the meeting in the phone calendar.
A cache buys speed at the cost of freshness. The hardest cache question isn't "how to put things in," it's "when to invalidate." TTL, explicit invalidation, write-through, write-behind, cache-aside — these are different compromises between complexity, freshness, and load.
A race condition appears when two operations compete for state. Optimistic locking says: "conflicts are rare, we'll check the version at write time." Pessimistic locking says: "conflicts are dangerous, we'll lock up front." Both are right under different conditions.
- What it is
A copy of data closer to the reader: speed in exchange for freshness.
- How it works
TTL, explicit invalidation, write-through, write-behind, cache-aside — different compromises.
- Example
- The schedule on the fridge vs the calendar on the phone.
- Catch
- The main question isn't "how to put it in" but "when to throw it out".
- Related
- Single source of truth, eventual consistency.
- What it is
Two ways to stop two operations from corrupting shared state (a race condition).
- How it works
Optimistic: check the version at write time. Pessimistic: lock up front.
- Example
Two managers edit the same record: the second one gets a conflict and re-reads the data.
- Catch
Optimistic struggles with frequent conflicts; pessimistic struggles with heavy lock contention.
- Related
- Transactions, stateful components.
Distribution solves problems of scale, but creates problems of time, order, and trust in the network.
CAP and PACELC — the network is a source of uncertainty
A monolith is a conversation in one room. A distributed system is correspondence between people in different time zones — letters sometimes get lost, arrive twice, or run late.
In a distributed system, you can't just "call a function." Between services there's a network, timeouts, retries, partial failure, different clocks, different versions of code. What was a local transaction in the monolith becomes a coordination protocol.
The CAP theorem is often summarised badly. The practically useful version: during a network partition, you choose between consistency and availability. PACELC adds: even without a partition, you still choose between latency and consistency.
- What it is
- During a partition: C or A (CAP). Without one: L or C (PACELC).
- How it works
- Each store and each scenario states explicitly what it gives up.
- Example
A node cut off from its peer: refuse (C) or answer, possibly stale (A).
- Catch
"We chose CA" doesn't exist on a network: partitions happen; the only question is what you do then.
- Related
- Consistency models, trade-off, partial failure.
Consistency models and Saga — consistency comes in flavours
Two people looking at the same Google Doc see the same thing almost instantly. Two people looking at a bank transfer can't settle for "almost."
Strong consistency gives you fresh truth, but costs latency and availability. Eventual consistency tolerates temporary drift, but often scales better. Causal consistency preserves cause-and-effect: if event B depends on A, B shouldn't become visible before A.
The saga pattern breaks a long business transaction into steps with compensating actions. Two-phase commit gives atomicity across resources, but is expensive and fragile in real distributed systems. The architect picks not "the strictest" model but the one sufficient for the risk.
- What it is
- How fast, and in what order, everyone sees the same truth.
- How it works
Strong: always fresh. Causal: keeps cause-and-effect order. Eventual: catches up later.
- Example
- A shared doc: "almost instantly" is fine. A bank transfer: it isn't.
- Catch
Strong pays in latency and availability; eventual pays in temporary drift.
- Related
- CAP / PACELC, cache, CQRS.
- Problem
A business operation spans several services; there's no shared transaction.
- Idea
- A chain of steps; if one fails, compensating actions undo what was done.
- Example
Reserve stock → charge → shipping fails → refund → release the reservation.
- Cost
- Every step needs a compensation; intermediate states are visible.
- When to use
Instead of two-phase commit, which is costly and fragile across a network.
- Related
- Eventual consistency, idempotency, microservices.
Microservices don't fix bad design. They turn local problems into distributed ones.
Modular monolith — an often underrated start
One well-organised warehouse is faster than ten small ones if the same courier is driving between them anyway.
A monolith isn't an insult. A bad monolith is a tangle of dirty dependencies. A good modular monolith has strict internal boundaries, separate domains, explicit interfaces, and a single deployment unit. For a small team, it's often the best starting point.
Microservices help when you need independent releases, autonomous teams, different scaling profiles, failure isolation, or different technology stacks. The price: network calls, observability, distributed transactions, DevOps overhead, versioning, security between services.
- Problem
- The monolith turns into a tangle of dirty dependencies.
- Idea
Strict internal boundaries and explicit interfaces — but one deployment unit.
- Example
Billing, identity, and catalog modules in one app, talking through module APIs.
- Cost
- Needs boundary discipline; scales and releases as a whole.
- When to use
A small team, an early product. Microservices — when you need independent releases, autonomous teams, different load profiles, failure isolation.
- Related
- Bounded context, microservices, Strangler Fig.
Distributed monolith and Strangler Fig — the worst of both worlds, and the way out
It's like living in separate apartments but walking next door for every spoon.
A distributed monolith looks like microservices, but the services aren't autonomous: shared database schema, synchronous call chains, releases that only ship together, changes that require touching everyone. The team pays the cost of distribution without getting the independence.
The Strangler Fig pattern lets you migrate carefully: wrap the old system, gradually extract capabilities, cut along real business boundaries, not along tables.
- Signs
Shared database schema, synchronous call chains, releases only together, every change touches everyone.
- Why it hurts
- You pay for distribution and get no independence.
- Example
- Separate apartments, but next door for every spoon.
- Way out
Own data per service, async links, boundaries by business meaning — or back to a modular monolith.
- Related
- Modular monolith, bounded context, sync vs async.
- Problem
- The old system can't be rewritten in one go.
- Idea
Wrap it in a facade and gradually move capabilities out into new services.
- Example
- Extract billing first, then catalog — the facade routes the requests.
- Cost
- Two systems live side by side for a long time.
- When to use
- Migrating a live system without a "big rewrite".
- Related
- Cut along bounded contexts, not along tables.
Sync couples systems in time. Async breaks that coupling, but brings delays, duplicates, and ordering complexity.
A phone call requires both sides to be free now. A letter can be read later — but it can get lost, run late, or demand a reply.
A synchronous (sync) call is easy to reason about: send, get an answer. But if the receiver is slow or unavailable, the sender suffers. Async via a queue or pub/sub lets you ride out failures and load spikes, but it demands a different mental model.
A queue usually distributes work across consumers. Pub/sub broadcasts an event to many subscribers. Kafka, RabbitMQ, SQS, Redis Streams — different tools with different ordering, durability, replay, and operational models.
- Problem
A sync call couples systems in time: the receiver goes down, the sender suffers.
- Idea
A queue splits work across consumers; pub/sub sends an event to every subscriber.
- Example
Kafka, RabbitMQ, SQS, Redis Streams — different ordering, durability, replay.
- Cost
- Delays, duplicates, ordering complexity.
- When to use
The sender doesn't need the result right now; you must ride out failures and spikes.
- Related
- At-least-once delivery, backpressure, idempotency.
At-least-once delivery — exactly-once is almost always marketing
If a letter is sent twice, decent accounting shouldn't pay the salary twice.
In practice you design for at-least-once delivery plus an idempotent consumer. A message can arrive twice; the handler has to survive it. A dead letter queue is for messages that couldn't be processed after a reasonable number of attempts.
Backpressure is the signal "the receiver can't keep up." Without it, the system gracefully accepts everything and then dies on the inside.
- What it is
- A message is guaranteed to arrive, but maybe more than once.
- How it works
An idempotent consumer drops duplicates; a dead letter queue collects messages after N failures; backpressure says "I can't keep up".
- Example
- A duplicate "pay the salary" message doesn't pay it twice.
- Catch
"Exactly-once" is almost always marketing; without backpressure the system accepts everything and dies inside.
- Related
- Idempotency, queue / pub/sub, reliability.
"Make it fast" isn't a requirement. A requirement sounds like latency, throughput, percentiles, and a load profile.
Tail Latency — average response time almost always lies
If nine people got their food in a minute and the tenth waited an hour, the average looks tolerable. The tenth disagrees.
This is the concept of tail latency. First, three words. Latency is the delay of a single operation. Throughput is how many operations the system handles per unit of time. Percentiles show the distribution: p50 is the median, p95 means 95% of requests are faster than that value, p99 is the tail.
The user doesn't feel the average — they feel the tail. Tail latency matters especially in systems where one screen depends on several backend calls: the probability of a slow response stacks up.
- Problem
The average response time looks fine while some users wait a very long time.
- Idea
- Look at percentiles: p50 is the median, p95 and p99 are the tail.
- Example
A screen is built from five backend calls: if any one of them lands in the tail, the whole screen is slow.
- Cost
You collect a distribution, not one number; you need histograms in your metrics.
- When to use
- Every time you turn "fast" into a requirement or build an SLO.
- Related
The basis for SLOs; grows during a retry storm; visible through observability.
Profiling — profile before you optimise
Fixing performance without a profile is like treating a patient from a photo of their shoes.
This is the practice of profiling: measure first, optimise second. N+1 queries, extra round trips, a bad index, serialisation, lock contention, GC pause, cold cache — they all look like "slow," but they're cured differently.
Amdahl's Law reminds you: speedup is bounded by the part of the system you actually optimise. Little's Law helps you think about queues: more latency at the same throughput means more work-in-progress sitting inside the system.
- Problem
The team "speeds up" the wrong place: a week spent, and the system is no faster.
- Idea
- A profile shows where the time really goes. Fix only the hotspot.
- Example
The "slow page" turns out to be an N+1 query, not a slow language — fixed with one query and a join.
- Cost
- Time for measuring and tooling; you need a reproducible load profile.
- When to use
- Before any optimisation. No profile, no optimisation.
- Related
Amdahl's Law is the speedup ceiling; Little's Law links latency, throughput, and queues.
Scalability is the ability to grow in load and in features without rebuilding the system from scratch.
Vertical vs Horizontal Scaling — they buy different things
You can buy one big truck. You can buy ten small ones. The first is simpler, the second is more flexible — but requires a dispatcher.
Vertical scaling (scale up) means making one machine stronger. Simple, while there's headroom. Horizontal scaling (scale out) means adding more instances. More flexible, but requires a stateless application layer, load balancing, a shared state strategy, and observability.
Databases scale harder than applications. Read replicas help reads, not writes. Sharding splits data but forces you to pick a shard key. A bad shard key turns scaling into a load imbalance.
- Problem
- Load is growing, and one machine will soon not be enough.
- Idea
Vertical: make the machine stronger. Horizontal: put more machines behind a load balancer.
- Example
A stateless app is easy to multiply; the database is harder: read replicas for reads, sharding by a shard key for writes.
- Cost
Vertical hits a ceiling. Horizontal needs a stateless layer, load balancing, a shared state strategy, and observability.
- When to use
Vertical while there's headroom. Horizontal when you need to grow past it.
- Related
The X-axis of the Scale Cube; stateless components from the state module; Single Source of Truth.
Scale Cube — scaling features matters as much as scaling load
A city doesn't grow only by population. It grows by schools, hospitals, roads, and rules.
The system has to absorb not just more traffic but more product surface. If every new feature requires rewriting a shared God-service, the system doesn't scale organisationally.
The useful model here is the scaling cube: X-axis is cloning, Y-axis is splitting by function, Z-axis is partitioning by data or tenants.
- Problem
People only think about traffic, but the system breaks from feature growth: everything lives in one God-service.
- Idea
Grow along three axes: X — clone, Y — split by function, Z — split by data or tenants.
- Example
X: three copies of the app. Y: billing, catalog, identity apart. Z: tenants A–H on one shard, I–P on another.
- Cost
- Every axis adds boundaries you have to hold and observe.
- When to use
- When you ask "what breaks first" — and the answer isn't only CPU.
- Related
The Y-axis is Bounded Context and microservices; the Z-axis is sharding; mind Conway's Law.
A reliable system isn't one where nothing breaks. A reliable system knows what to do when it does.
Retry, Circuit Breaker, Bulkhead — retry without a strategy is an attack on yourself
If a door doesn't open, knocking once is reasonable. Knocking a thousand times a second is now a problem for the door and the neighbours.
Retry is for transient failures. But retries need a limit, a timeout, exponential backoff, and jitter. Otherwise a partial outage turns into a retry storm.
A circuit breaker temporarily stops calls to a stuck dependency. The bulkhead pattern isolates resources: if one downstream dies, it doesn't take all your worker threads and connection pools with it.
- Problem
A dependency slows down or dies; mindless retries finish it off and eat all of the service's resources.
- Idea
Retry with a limit, timeout, backoff, and jitter. Circuit breaker: stop calling the dead. Bulkhead: separate pools so a failure doesn't spread.
- Example
The payments API hangs: the breaker opens and fails fast, while the search pool keeps working.
- Cost
More settings and states; you have to decide how the system degrades when a dependency is down.
- When to use
- Any network call to something that can hang.
- Related
Retries are only safe with Idempotency; linked to at-least-once and backpressure.
SLI / SLO / SLA — SLOs turn reliability into a contract
"We'll try our best" isn't a train schedule. A schedule says what counts as normal and what counts as a failure.
SLI is what you measure: success rate, latency, freshness. SLO is the target: 99.9% successful requests over 30 days. SLA is a promise to the customer with consequences attached.
The error budget tells you how much unreliability you're allowed to spend. If the budget is burned, the team stops chasing features and fixes reliability. That's the business-language version of engineering quality.
- Problem
Nobody measured "reliable," so the features-vs-quality argument never ends.
- Idea
Measure (SLI), agree on a target (SLO), keep the customer promise separate (SLA). The gap to 100% is the error budget.
- Example
SLO: 99.9% successful requests over 30 days. Budget burned — features pause.
- Cost
You must honestly pick what to measure and keep the rule when the budget runs out.
- When to use
When reliability has to be discussed with the business in one language.
- Related
SLIs are often built on Tail Latency; alerts fire on symptoms; it's an NFR in numbers.
You can't add security right before release. It has to be built into the access model, the data, the infrastructure, and the processes.
Authentication vs Authorization — different things
A passport proves who you are. A ticket proves where you're allowed to go. One doesn't replace the other.
Authentication (AuthN) answers "who is this?". Authorization (AuthZ) answers "what are they allowed to do?". Confusing them is dangerous: a user can be correctly logged in and still have no right to read someone else's invoice.
RBAC grants permissions through roles. ABAC considers attributes: resource owner, tenant, region, object state. Session-based auth is easier to revoke; JWT is easier to verify without a database, but harder to revoke. The choice depends on threats and lifecycle.
- Problem
"The user is logged in" gets confused with "the user is allowed" — and they read someone else's data.
- Idea
Two separate steps: AuthN establishes identity, AuthZ checks the right to a specific resource.
- Example
A logged-in customer requests another customer's invoice #42 — AuthZ must answer 403.
- Cost
Choosing a model: RBAC is simpler, ABAC more precise; sessions are easy to revoke, JWTs easy to verify but hard to revoke.
- When to use
- In any system where data has an owner.
- Related
One layer of defense in depth; the spoofing and elevation-of-privilege threats from STRIDE.
Threat Modeling — professional paranoia
A good architect thinks like an attacker not because they distrust people, but because they trust reality.
Threat modeling is a systematic search for threats before an attack. STRIDE helps you look for them: spoofing, tampering, repudiation, information disclosure, denial of service, elevation of privilege. Defense in depth means several layers of protection: input validation, authz, encryption, audit log, rate limiting, least privilege.
Secrets management isn't "put the key in env and forget." You need to understand rotation, access, audit, blast radius, and what happens during a leak.
- Problem
Security gets remembered right before release, when the access model is too late to change.
- Idea
Walk the component through STRIDE and put up several layers of protection, not one "main" lock.
- Example
A leaked key: what it opens (blast radius), how fast you can rotate it, where it shows up in the audit.
- Cost
- Time for the review and discipline in secrets management.
- When to use
- At design time for every new component and integration.
- Related
AuthN vs AuthZ is a layer of protection; observability and the audit log let you spot an attack.
You can't fix what you can't see. The system has to explain its own state without archaeology in the code.
Observability — monitoring tells you what's wrong, observability helps you understand why
A "check engine" light is useful, but the mechanic still needs gauges, history, and diagnostic tools.
Monitoring answers "something is wrong." Observability answers "why." The three pillars of observability: logs, metrics, traces. Structured logging makes logs queryable. Metrics show aggregates. Distributed tracing follows a request's path through services.
A correlation ID is a small thing that saves nights: one request ID flows through gateway, service, queue, worker, and downstream.
- Problem
Something broke at night, and the cause is hunted by archaeology in the code.
- Idea
The system explains its own state: structured logs, aggregate metrics, traces of the request path.
- Example
With request id
req-7f3ayou find the request in the gateway, the queue, and the worker — and see where it got stuck.- Cost
- Tooling, data storage, and the discipline to pass the ID everywhere.
- When to use
- From day one, especially in a distributed system with queues.
- Related
The data source for SLIs and Symptom-based Alerting; without it, Profiling is blind.
Symptom-based Alerting — alert on symptoms
The user doesn't care that CPU is at 92%. They care that checkout doesn't work.
A good alert speaks user pain — this is symptom-based alerting: error rate, latency, failed payments, stale data. A bad alert speaks of a cause that can be perfectly normal. If alerts are noisy, the team stops trusting them.
A runbook answers "what to do at 3 a.m." A post-mortem answers "how do we make sure this doesn't happen again." Blameless; the goal is to improve the system, not to find the guilty party.
- Problem
Alerts fire on causes, the team gets used to the noise and misses a real outage.
- Idea
- Wake a human only for user pain; every alert gets a runbook.
- Example
Not "CPU 92%," but "failed payments went up" — plus a runbook: what to check first.
- Cost
- You need to know your symptoms and keep runbooks up to date.
- When to use
- For everything the on-call engineer has to fix at night.
- Related
Symptoms are SLIs; the post-mortem is the same written culture as ADRs and RFCs.
An unrecorded architectural decision disappears together with the context of its author.
ADR — an Architecture Decision Record beats memory
An oral agreement is good until the first vacation, the first resignation, or the first argument six months later.
An Architecture Decision Record captures context, decision, alternatives, and consequences. An ADR doesn't have to be a novel. A good ADR answers: what problem were we solving, what did we choose, why didn't we choose the alternatives, when do we revisit.
Documentation isn't there for the audit — it's there for the next change. A new engineer has to understand not just "how" but "why."
- Problem
The decision lived in the author's head; the author left, and nobody knows why it was done this way.
- Idea
A short record per decision: context, decision, alternatives, consequences.
- Example
"We take PostgreSQL, not MongoDB: we need transactions; revisit if document-style workloads appear."
- Cost
- Half an hour to write. Cheaper than the argument six months later.
- When to use
- For decisions that are expensive to reverse.
- Related
Records Trade-offs and debt; sits next to the RFC; part of Learning in Public.
C4 Model — a diagram is a working tool, not a decoration
A subway map doesn't show the wires or the bolts. It shows lines and transfers. That's enough not to get lost.
The C4 model gives you four levels: Context, Container, Component, Code. The first three are usually enough. A sequence diagram is useful when the order of interactions matters. Full UML is rarely needed; individual diagrams, yes.
Living documentation lives next to the code, updates in the PR, and gets reviewed. A document in a forgotten wiki quickly turns into historical fiction.
- Problem
Diagrams are drawn for looks: everything on one picture, and a month later it lies.
- Idea
- Draw by zoom level: Context → Container → Component (→ Code, rarely).
- Example
Context: the system, users, external services. Container: web, API, database, queue.
- Cost
- Diagrams have to be updated in the same PR as the code.
- When to use
When the system has to be explained to a new person or another team.
- Related
Shows Bounded Contexts and boundaries; a sequence diagram covers the order of calls.
The architect talks to engineers, product, business, security, and legal. Each audience hears a different language.
Risk Translation — translate risk into the audience's language
A doctor doesn't only use Latin names with the patient. They explain what will hurt, how long the treatment is, and what to avoid.
This is the practice of risk translation. You can say to an engineer: "we have no idempotency on the payment callback." The business needs to hear: "if the webhook retries, we may charge twice or ship the product twice; that's a financial and reputational risk."
Stakeholder mapping helps you see who cares about what: product wants time-to-market, security wants risk reduction, finance wants predictable cost, support wants understandable behaviour, engineering wants maintainability.
- Problem
A technical risk sounds like jargon, and the business doesn't hear it.
- Idea
Translate the risk into consequences that matter to this particular audience.
- Example
"No idempotency on the callback" → "we may charge twice — a financial and reputational risk."
- Cost
You need to know what each stakeholder cares about and speak their language.
- When to use
- Every time a decision depends on people outside engineering.
- Related
The example is Idempotency; the business side is NFRs and cost of delay.
RFC — a written proposal lowers the temperature of an argument
An argument at the whiteboard is often won by the loudest voice. A written proposal forces the arguments to stand apart from the voice.
An RFC (Request for Comments) describes the problem, the constraints, the options, the chosen solution, the risks, and the rollout plan. A good RFC invites criticism before the decision becomes policy.
Disagree and commit works only after an honest discussion. If the team wasn't heard, that isn't commit — that's suppression.
- Problem
- The whiteboard argument is won by the loudest, not the most right.
- Idea
In writing: problem, constraints, options, decision, risks, rollout. Criticism comes before the decision.
- Example
Before moving to a new queue: an RFC, a week of comments, then a decision and an ADR.
- Cost
Slower than "deciding on a call"; needs an owner who drives it to a decision.
- When to use
For decisions that touch several teams or are expensive to reverse.
- Related
The outcome goes into an ADR; a tool of Influence without Authority.
The architect is often still an individual contributor. Their authority comes from clarity of thinking, trust, and the ability to make the team stronger.
Influence without Authority
A conductor doesn't play every instrument, but without one the orchestra quickly becomes a set of talented people playing different pieces.
This is the concept of influence without authority. The architect shouldn't become a bottleneck on every decision. Their job is to set principles, explain boundaries, grow people, and step in where the cost of a mistake is high.
Architect mentoring isn't "do as I do." It's teaching the questions: what alternatives have you seen, what did you give up, how will you test the risk, where does the responsibility end.
- Problem
The architect decides everything personally and becomes a queue for every team.
- Idea
- Influence through principles, boundaries, and questions, not orders.
- Example
Instead of "do it this way": "what alternatives did you see, and how will you test the risk?"
- Cost
- Slower in the moment; it needs trust that takes years to build.
- When to use
Whenever you have no direct reports but decisions still need to happen.
- Related
Works through RFCs and ADRs; the opposite is the Ivory Tower Architect.
Delegation with Guardrails — delegating doesn't mean transferring ownership
A captain can hand off the wheel, but they can't say the course of the ship is no longer their problem.
Part of architectural decisions should be made by the teams. Otherwise the architect becomes a queue. But there have to be guardrails: principles, review, ADRs, platform constraints, quality gates.
The architect steps in when a decision is irreversible, breaks system invariants, creates security risk, or affects several teams.
- Problem
Either everything goes through the architect (a queue), or nobody owns the course.
- Idea
Teams decide on their own inside guardrails; the architect owns the course and steps in on clear signals.
- Example
The team picks its logging library itself; changing the tenancy model happens only with the architect.
- Cost
Guardrails have to be formulated, written down, and checked automatically where possible.
- When to use
- When there's more than one team and one architect.
- Related
The "irreversible" signal comes from Reversible vs Irreversible; guardrails are ADRs and quality gates.
Architecture only makes sense in the context of a business goal. Otherwise it's expensive engineering aesthetics.
Non-functional Requirements — business requirements too
For a shop, "checkout works on Black Friday" isn't a technical detail — it's money.
Non-functional requirements (NFRs) — performance, availability, security, compliance, operability — aren't "technical wants." They're product properties. The architect translates them into business impact: lost revenue, regulatory risk, support cost, speed of market launches.
Cost of delay helps you discuss not just the cost of doing the work, but the cost of waiting. Sometimes an architectural investment without immediate ROI is needed, because without it the next features start getting more expensive.
- Problem
System quality is treated as a "technical want" and keeps being postponed.
- Idea
- NFRs are product properties; talk about them in revenue, risk, and cost.
- Example
- "Checkout survives Black Friday" is money, not a detail.
- Cost
- You need to estimate the impact in numbers, at least roughly.
- When to use
- When architectural work competes with features for time.
- Related
In numbers: SLOs; postponed work: Technical Debt; the language: Risk Translation.
Build vs Buy — not a matter of pride
Not every company should build its own power station just to turn the lights on.
Building gives you control and differentiation. Buying gives you speed and lowers operational load. Vendor lock-in is a real risk, but on its own it isn't an argument against buying. The question: how expensive is the exit if the vendor changes price, API, or quality?
The architect helps product see the capability map: which capabilities are the core of the business, and which are better bought.
- Problem
People build their own out of pride, or buy everything with no exit plan.
- Idea
Build what differentiates the business; buy the commodity. For anything bought, estimate the exit cost.
- Example
Your own domain engine — build; email delivery or payments — usually buy.
- Cost
Build: time and maintenance forever. Buy: dependence on the vendor's price, API, and quality.
- When to use
- Before every "let's write our own."
- Related
The trap is NIH syndrome; Dependency Inversion helps isolate the vendor.
When code is written by agents, the architect's value moves into specification, architectural thinking, and quality control.
Specification-driven Development — spec quality becomes the bottleneck
If the construction crew gets ten times faster, the binding constraint stops being the speed of bricks. It becomes the quality of the blueprints.
AI agents speed up implementation, but they don't remove architecture. A poorly framed task just turns into bad code faster. Specification-driven development means the primary artifact is the specification of behaviour, boundaries, invariants, tests, and acceptance criteria.
In an AI-native process, the architect writes less low-level code and more precise prose. They review the diff, the tests, the architectural boundaries, and the alignment with the spec.
- Problem
An agent writes code ten times faster — and builds the wrong thing just as fast.
- Idea
The main artifact is the spec: behaviour, boundaries, invariants, tests, acceptance criteria.
- Example
Instead of "build payments": scenarios, errors, the invariant "one payment per order," and tests for it.
- Cost
- The architect writes more precise prose and less code.
- When to use
- Whenever an AI agent does the implementation.
- Related
Checked by Agent Output Review; invariants come from the API Contract and the Bounded Context.
Agent Output Review — agent code deserves the same discipline as a human PR
A fast junior who writes a thousand lines an hour still needs review. Speed doesn't make code correct.
You can't accept agent code because it compiles. You need tests, evals, import boundaries, type checks, security review. Scenario evaluations matter especially: the system has to pass real cases, not just the happy path.
An AI-native organisation wins not where "everyone is vibe-coding," but where there are strong specifications, small iterations, automated checks, and architectural ownership.
- Problem
- Agent code gets accepted because it compiles and looks confident.
- Idea
- The same automated quality gates and the same review as for a human.
- Example
Scenario evals catch that the agent handled only the happy path and forgot the repeated payment.
- Cost
- The automated checks and import boundaries have to be built in advance.
- When to use
- Every PR from an agent, no exceptions.
- Related
Checks alignment with Specification-driven Development; boundaries come from Dependency Inversion.
The architect can be dangerous precisely because they sound convincing. Knowing the traps saves years.
Ivory Tower Architect
Someone draws a perfect city up on the hill but never walks down to see where people actually go.
This is the ivory tower architect anti-pattern: decisions made far from the code, the operations, and the team. The diagrams are beautiful, but the implementation suffers. The cure is simple: read PRs, watch incidents, talk to engineers, walk the change path yourself.
- Symptom
- Beautiful diagrams the team can't implement.
- Why it hurts
- Decisions ignore the real code, operations, and people.
- Cure
Read PRs, watch incidents, talk to engineers, walk the change path yourself.
- Related
The opposite of Influence without Authority; form over reality is also Cargo Cult.
Resume-driven Development and Cargo Cult
Buying a fire truck because it impresses the neighbours is strange if you don't have water or firefighters.
Resume-driven development picks technologies for a line on the CV. Cargo cult engineering copies the shape of someone else's decision without the reason. NIH syndrome (Not Invented Here) forces you to write your own where a mature external tool would do better.
Another trap is technical perfectionism. The perfect architecture that never reached the user loses to a good-enough system that ships and can evolve.
- Symptom
The decision is justified by fashion, someone else's example, or beauty — not by a problem.
- Why it hurts
You pay the price of a complex technology without its benefit, or never reach the user.
- Example
Kubernetes and microservices for a team of three, "because Netflix does it."
- Cure
- Start from the problem and honestly name the price of every option.
- Related
Cured by Trade-offs and Build vs Buy; often produces a Distributed Monolith.
Architecture is an infinite game. Technologies change, but the ability to ask the right questions only gets stronger.
T-shaped / M-shaped Skills — learn from systems, not from hype
A cook grows not from watching knife ads, but from understanding ingredients, heat, time, and taste.
New technologies are worth studying through questions: what problem do they solve, what price do they introduce, where have they already failed, what are the alternatives, what has to be true for them to become useful.
T-shaped skills give you depth in one area and breadth across the neighbours. M-shaped skills appear in a mature architect: several deep pillars — data, distribution, security, product, AI tools.
- Problem
- People learn every trendy technology, yet gain no depth or judgement.
- Idea
Study technologies through questions about problem and price; grow several deep pillars.
- Example
A new database: what problem it solves, where it has already failed, what must be true for it to help us.
- Cost
- Slower than reading announcements; depth takes years.
- When to use
- With every new technology on the radar.
- Related
A guard against Resume-driven Development; the pillars are this course's topics.
Learning in Public — accelerates maturity
When you explain a decision in writing, the gaps in your thinking show up before production finds them.
Learning in public means learning openly, in writing. Write ADRs, RFCs, engineering notes, post-mortems, short breakdowns of decisions. Learn from architects stronger than you — not just what they chose, but how they reasoned.
The architect people imitate usually isn't the one who knows the most terms. It's the person next to whom the team starts asking better questions.
- Problem
Production finds the flaws in your reasoning before your colleagues do.
- Idea
Write down decisions and breakdowns, share them, learn from the feedback.
- Example
ADRs, RFCs, engineering notes, post-mortems, short decision breakdowns.
- Cost
- Time to write, and the nerve to show unfinished thinking.
- When to use
- All the time — this is how an architect grows.
- Related
Uses ADRs, RFCs, and post-mortems; makes the team stronger, like Influence without Authority.
- I can name the trade-offs of a decision without ego defence.
- I understand where the source of truth lives in the system.
- I tell reversible decisions from irreversible ones.
- I can explain the architecture to engineering, product, and business in different words.
- I write decisions so they can still be understood a year from now.
- I don't hide complexity behind the words "best practice."
The course map: how it all connects
A subway map at the end of the trip: now you see where the lines cross.
Mindset shapes the structure, the data, and the quality. Structure gets recorded in documents, quality gets verified by security and operations, and documents and risks convince the business. Together it all scales into AI-native work and personal growth.
Cheat sheet: all 52 concepts of the course
The architect's mindset (1–4)
- Long-term Thinkingthinking in years
First check whether the problem is posed right, and how the decision will live in three years.
- Reversible vs Irreversibletwo kinds of decisions
Decide fast on what's easy to undo; slowly on what changes the system's trajectory.
- Trade-offsa deliberate exchange
Every choice buys one property at the cost of another. Best practice without context is bad advice.
- Over- / Under-engineeringcomplexity is a tax
Complexity is justified only when it buys an important property. Hold the middle.
- Technical Debta loan, not garbage
A decision that speeds you up now and costs more later.
- Debt Interestthe slowdown
The slowdown of every next change. Debt in the hot zone costs the most.
- Cognitive Loadfits in a head
How much context you need to change a component safely. Remove accidental complexity.
- Conway's Laworg shape = system shape
A system mirrors the communication structure of the organisation.
System structure (5–7, 11)
- Cohesion & Couplingone thing inside, little outside
Inside a component — about one thing; outside — know as little about others as possible.
- Bounded ContextDDD boundary
A boundary inside which words have a single meaning.
- Dependency Inversiondependencies point inward
Business logic depends on abstractions; details plug in from outside (ports and adapters).
- Abstractionexists to absorb change
A layer earns its keep by absorbing change and testing without the outside world, not by looking nice.
- API Contractcontract over transport
Schema, errors, versioning, and compatibility matter more than REST vs GraphQL vs gRPC.
- Idempotencysafe to repeat
Repeating an operation gives the same final effect. Protection from retries and duplicates.
- Modular Monolithone deploy, strong walls
One application with strict internal boundaries. Often the best start.
- Distributed Monolithworst of both worlds
Services that only ship together. The cost of distribution without the independence.
- Strangler Figmigrate piece by piece
Grow the new system around the old one and move traffic over gradually, instead of a big-bang rewrite.
Data and distribution (8–10, 12)
- Data Modeldata outlives code
The most expensive decision: normalisation, OLTP vs OLAP.
- Event Sourcingthe log of events is the truth
State is rebuilt from events: full history and audit, but expensive to run and evolve.
- CQRSseparate write and read models
Commands and queries get their own models; useful when reads and writes differ a lot.
- Single Source of Truthone authoritative version
For every fact you know where the primary version lives; the rest are derived copies.
- Cache Invalidationa second truth that lies
Speed at the cost of freshness; the hard question is when to invalidate.
- Optimistic vs Pessimistic Lockingcheck on write vs lock first
Two ways to stop concurrent edits from overwriting each other.
- CAP / PACELCthe network is uncertainty
During a partition: consistency or availability; otherwise: latency or consistency.
- Consistency Modelsstrong, eventual, causal
Not the strictest model — the one sufficient for the risk.
- Sagaa chain of steps with compensations
A long transaction across services, where each step has an undo instead of a global lock.
- Queue vs Pub/Sub
Async decouples in time, but brings delays, duplicates, and ordering.
- At-least-once Deliveryexactly-once is marketing
A message can arrive twice; the consumer must be idempotent. DLQ, backpressure.
System quality (13–15)
- Tail Latencyp95 / p99
Users feel the tail, not the average.
- Profilingmeasure first
Optimise only the hotspot you found; Amdahl and Little set the limits.
- Vertical vs Horizontal Scalingscale up / scale out
One big machine, or many identical ones behind a load balancer.
- Scale CubeX / Y / Z
Clone, split by function, split by data.
- Retry + Circuit Breaker + Bulkheadresilience
Retries with backoff and jitter, a breaker for dead dependencies, isolated pools.
- SLI / SLO / SLAerror budget
Measurement, target, and promise; the error budget decides features vs reliability.
Security and operations (16–17)
- Authentication vs AuthorizationAuthN / AuthZ
"Who are you?" and "what may you do?" are two different steps.
- Threat ModelingSTRIDE, defense in depth
Find threats before the attack and defend in layers.
- Observabilitylogs · metrics · traces
The system explains "why"; a correlation ID ties the whole path together.
- Symptom-based Alertingrunbook, post-mortem
Alert on user pain; a runbook says what to do; post-mortems are blameless.
Documents and communication (18–19)
- ADRArchitecture Decision Record
Context, decision, alternatives, consequences — one per decision.
- C4 Modelliving documentation
Diagrams by zoom level that live next to the code.
- Risk Translationstakeholder mapping
One risk, different words for engineers and for the business.
- RFCdisagree and commit
A written proposal, with criticism before the decision.
Leadership and business (20–21)
- Influence without Authoritymentoring
Principles, boundaries, and questions instead of orders.
- Delegation with Guardrailsownership stays
Teams decide; the architect steps in on irreversibility, invariants, security, and multi-team impact.
- Non-functional RequirementsNFRs, cost of delay
Product properties expressed in revenue, risk, and cost.
- Build vs Buycapability map
Build the core, buy the commodity, know the exit cost.
AI-native, traps, and growth (22–24)
- Specification-driven Developmentthe spec as artifact
The faster the executor, the more the spec's precision matters.
- Agent Output Reviewquality gates
Agent code passes the same checks as a human PR.
- Ivory Tower Architectarchitecture from the hill
Decisions made far from the code, operations, and team.
- Resume-driven Developmentcargo cult, NIH, perfectionism
Tech for the CV, copying the form, building what you should buy, endless polishing.
- T-shaped / M-shaped Skillslearn from systems
Depth plus breadth; a mature architect has several deep pillars.
- Learning in Publiclearning in writing
Write decisions down and see the gaps in your thinking before production does.
An architect is an engineer who learned to see the consequences before they became an incident.