The weekly letter from Systems Thinking Lab: one system-design teardown framed through the seven building blocks.
You can know the seven blocks cold and still design the wrong system. The blocks tell you what to build. They do not tell you why.
The why comes from outside.
Picture a design review. An engineer at the whiteboard has sketched a Service, a Database, a Worker, and a Queue. Each block is correct in isolation. The diagram is clean. The arrows make sense. The review still goes badly.
The senior in the room asks a question the engineer cannot answer. "Who is waiting for this?" The engineer points at the Service. "What if it fails?" The engineer points at the Database. "When does this run?" Long pause.
The blocks were right. The forces behind them were never named. Without the forces, the design is a drawing. A drawing of correct shapes that does not survive contact with the real world.
There are three forces. Every architectural decision you will ever make comes from one of them.
The first is the User. Someone has tapped a button, made a request, opened a page. They are waiting. They do not care that your downstream service is slow or that your database is sharded. They care about three things: the response is fast, it is correct, and it shows up reliably. Every synchronous path in your system exists because of them. The User is why Services exist.
The second is the External Service. Something outside your control that your system depends on. Stripe. SendGrid. OpenAI. Twilio. You did not write their code. You do not own their uptime. Their pager is not your pager. Sooner or later they will fail, time out, throttle you, deprecate the endpoint you depend on, or change the response shape. Your design has to assume this happens. Workers absorb the unreliability. Queues buffer the traffic. Idempotency keys make retries safe. The External Service is why your system has shock absorbers.
The third is Time. The clock. Cron jobs. TTL expirations. Scheduled invoices. The midnight backup. Time does not initiate a request. It fires when it fires. It does not care that the engineering team is in a meeting. It is not waiting for a response. It is simply the heartbeat that triggers work. Time is why Workers run when no User is in sight.
When you look at a system through these three forces, the block selection stops being a debate.
User is waiting? You need a Service. The path must complete in milliseconds and return.
Work has to happen but the User has moved on? You need a Worker, and a Queue feeding it. The User does not stay on the page for the receipt email to send. The receipt email runs in the background.
External Service is unreliable? You need a Worker with retries and a Queue as a buffer. When SendGrid is down at 3 AM, the email is not lost. It sits in your Queue.
Clock fires at midnight? Time pulls a Worker. The Worker rolls invoices, expires sessions, regenerates feeds, takes the backup. No User involved.
The blocks are the answer. The forces are the question.
This is the lens most engineers never get. They learn the technologies. Postgres, Redis, SQS, Kafka. They learn the patterns. Services, queues, workers. They miss that the patterns are responses to something. The system is not a pile of components arranged for elegance. It is a set of decisions about what to do when the three forces show up.
The most common failure mode is to design only for the User. The happy path. The one force you can see. The screenshot in the spec. So the engineer builds a Service and a Database and ships it. Then a third-party API rate-limits them on launch day, and the Service crashes because there is no Worker to absorb the failure. Then the midnight backup fires and there is no Time + Worker arrangement, so it runs inside the same Service as the User requests and slows everything down. Then the engineer rebuilds half the system in production. They blame complexity. The real cause is that they only saw one force.
In Course 1 I teach the three external forces alongside the seven blocks, because the blocks do not mean anything without them. The first thing we do in every design challenge is name the forces. Then we pick blocks. Always in that order. The framework collapses if you skip it.
You do not start a system design with the database. You start with the force asking something of your system.
P.S. There is a full walkthrough of the external forces and how each one pulls different blocks at systemthinkinglab.ai/learn/building-blocks/external-entities/