CHRISTOPHER YU
EMAIL ME
HOW I THINK ABOUT ARCHITECTURE

Boring architecture,chosen on purpose.

I start with where the data lives, who can access it and what happens when a service fails. Those decisions help keep an application understandable as it grows and give the next engineer a clear place to start.

SCOPE
Web applications
APPROACH
Start simple
STORE
Postgres
RULE
Add nothing early
01  THE SPINE

A small foundation, extended when needed.

These are responsibilities to consider for a web application, not six services to deploy. The interface, server logic and database form the foundation. Caching, background workers and external integrations are added when the workflow needs them. A landing page may need only a static build and a form connection.

FIG. 01 / THE SPINE
01 CLIENTtyped end to end
02 APIvalidated requests
03 POSTGRESthe only truth
04 CACHElater
05 WORKERS
06 EDGESwrapped, fallible
DASHED = OPTIONAL, ADDED WHEN THE APPLICATION NEEDS IT
02  WHERE STATE LIVES

One place, and everything else derives from it.

The first question on any project is which facts are true and where they are written down. Everything after that is derivation. If a number can be computed from the facts, it gets computed, or it gets stored in something explicitly labelled as derived and rebuildable with one command.

FACTS
Rows a human created or a payment provider confirmed. Written once, corrected by a new row rather than an overwrite where it matters.
DERIVED
Totals, pacing, availability, progress. Recomputed on write where reads are frequent, always rebuildable from facts alone.
EPHEMERAL
Filters, open panels, form drafts. Lives in the client and is allowed to be lost.
NOWHERE ELSE
No business rule in a component. No total that only exists in a chart. No truth in a cache.
03  WHEN TO ADD

Complexity has to be earned by a measurement.

Every extra component is a thing that can fail at 2am, and a thing the next engineer has to understand. So each one needs a trigger, agreed in advance, rather than a hunch.

A CACHE
When a query is slow, frequent, and provably the bottleneck. It must be invalidatable by hand, and the app must be correct without it.
A QUEUE
When work is slow enough to time out a request, or must survive a restart. PDFs, email, imports. Never for speed alone.
A SECOND SERVICE
When parts of the product need to scale or deploy independently, and the benefit justifies maintaining a separate service.
AN ABSTRACTION
On the third occurrence, not the second. Two similar things are a coincidence.
04  FAILURE CASES

Decided before launch, not during the incident.

Every third party in the system gets the same three questions written down: what does the user see when it is down, what happens to the work that was in flight, and how do I know it happened without a customer telling me.

These are examples of decisions we agree for applications that depend on these services.

WHEN THIS IS DOWNTHE USER SEESTHE WORK
Email providerDelivery is pending or failedRecord the failure and define retry and alert rules
Payment providerA plain message, not a stack traceNothing marked paid without a confirmed webhook
File storageUpload disabled, rest of app worksNo half-written records pointing at nothing
The databaseA clear service-unavailable messageA recovery plan using tested backups
05  PRODUCTS IN PRACTICE

Shared principles, different applications.

Each application has different workflows and constraints. These examples show how those needs shape the data model and access rules.

Monark
FINANCE
Monark calculates totals from the underlying transactions and stores money as integers in minor units. The dashboard turns those figures into a plain-language view of the month's position and spending pace.
DERIVED TOTALSINTEGER MONEYSPENDING FORECASTS
READ THE CASE STUDY →
Stencil
BOOKING
The hard part was that an enquiry and a booking are not the same object. An enquiry is quoted, then accepted or declined. A booking then has a life of its own through deposit, confirmation and completion, and can still be cancelled or no-showed. Collapsing both into one status column would have made every question about money ambiguous.
TWO STATE MACHINES35 RLS POLICIESOWNER / ARTIST ROLESEN / ID
READ THE CASE STUDY →
Sightline
ACCESS
Clients reach their project through a shared link, without creating an account. That link grants access, so reads and actions must stay scoped to its project. Anyone holding the link can use that access; it needs to be treated as a credential.
NO CLIENT ACCOUNTSSLUG-SCOPED WRITESMAGIC LINKDERIVED PROGRESS
READ THE CASE STUDY →
06  DELIVERY PRINCIPLES

Built for the person who maintains it next.

01
Test the recovery path. For applications storing business data, plan backups and verify that they can be restored.
02
Verify payment status. For integrated payments, use confirmation from the provider before marking a transaction paid.
03
Enforce rules where data is handled. Check permissions and inputs on the server, and use database constraints where appropriate.
04
Make the handover usable. Document how the application is configured, deployed and maintained so another engineer can continue the work.
Let's talk through your application's requirements.