The 7 building blocks are your construction materials. But materials alone don't tell you what to build or how to build it. Something has to push on your system from the outside to force decisions.
That something is what we call external entities. There are exactly three: Users, External Services, and Time. Every system you will ever design is shaped by some combination of these forces. Understanding them is the difference between a system that works on your laptop and one that works in the real world.
Users: The Force You Can See
Users are the most obvious external entity. Someone clicks a button, submits a form, or uploads a photo. Your system has to respond.
But here is the part that junior engineers miss: the user's expectation about how fast you respond determines which building blocks you choose.
When a user searches for a product on an e-commerce site, they expect results in under a second. That expectation forces you toward a Service that reads from a fast store, maybe a Key-Value Store with pre-indexed results. You cannot send that request to a queue and process it later. The user will leave.
But when a user uploads a video to YouTube, they do not expect it to be available instantly. They expect it to process. That different expectation means you can accept the upload with a Service, then hand it off to a Queue and Worker for transcoding. The user gets a progress bar instead of a frozen screen.
Same user. Same system. Two completely different architectural patterns. The only variable that changed was the user's expectation about response time. Does the user need the result right now, or can they wait? That single question determines whether you use synchronous processing or asynchronous processing.
# Synchronous: user waits for the result
POST /search → Service → Key-Value Store → Response (200ms)
# Asynchronous: user gets acknowledgment, work happens later
POST /upload → Service → Queue → Worker → File Store (minutes)
External Services: The Force You Can't Control
The second external entity is any third-party service your system depends on. Stripe for payments. SendGrid for email. Twilio for SMS.
The defining characteristic: you do not control its reliability. It can go down, slow down, change its API, or rate-limit you, and there is nothing you can do about it.
This single fact should change how you architect your system. If your checkout flow directly calls Stripe and Stripe is having a bad day, your entire checkout is broken. Every user sees an error. Revenue stops.
The resilient approach is to put a Queue between your system and the external service. Instead of "call Stripe right now and hope it works," you put the payment intent on a Queue. A Worker processes it. If Stripe is down, the Worker retries. The payment goes through when Stripe recovers.
This pattern shows up everywhere:
- Email sending: Don't call SendGrid inline with your API response. Queue the email, let a Worker send it. If SendGrid is slow, your API stays fast.
- Webhook processing: When Stripe sends you a webhook, acknowledge it immediately (return 200), then queue the actual processing. If your processing logic is slow or fails, you don't lose the webhook.
- Data syncing: If you need to push data to a CRM like Salesforce, queue the updates. Salesforce's API has rate limits, and a queue lets your Worker respect those limits without slowing down your users.
The pattern is always the same: decouple your system's reliability from the external service's reliability by putting a Queue in between.
Time: The Invisible Force
The third external entity is the one most engineers forget about when whiteboarding a system: Time.
Time is the trigger that has no user attached to it. Nobody clicked anything. No API called you. The clock just hit a certain moment, and now work needs to happen.
Examples are everywhere once you start looking:
- Every night at midnight, generate daily analytics reports
- Every hour, check for abandoned shopping carts and send reminder emails
- Every five minutes, poll an external API for new data
- Every Monday morning, send weekly digest emails to all subscribers
Time-triggered work almost always routes to a Worker. There is no user waiting for a response, so there is no need for a Service to be involved. A scheduled trigger fires, a Worker picks up the job, and it processes in the background.
But Time also introduces a challenge that Users and External Services do not: batching. When a user makes a request, you process one thing. When Time triggers a job, you might need to process millions of things. "Send reminder emails to all users with abandoned carts" could mean 10 emails or 10 million.
This is where the Queue becomes essential. Instead of one Worker trying to send 10 million emails, you have a Worker that queries for all abandoned carts and puts one message per email onto a Queue. Then many Workers process those messages in parallel. The job that would take hours with one Worker takes minutes with a hundred.
# Time trigger → fan-out pattern
Cron (midnight) → Worker → queries abandoned carts
→ puts 50,000 messages on Queue
→ 100 Workers process in parallel
Why AI Gets This Wrong
Here is the part that makes external entities especially important in the AI era.
When you ask AI to design a system, it builds for the happy path. It assumes the user is patient, the external services are always available, and there are no scheduled jobs. It gives you a Service that calls an API directly, processes the result, and returns it to the user. Clean, simple, and fragile.
AI has no intuition for failure. It has never been paged at 2 AM because Stripe went down. It has never watched a nightly batch job take 6 hours because someone forgot to parallelize it. You have that intuition, or you will develop it. Understanding external entities is what transforms a technically correct design into one that survives the real world.
The Takeaway
Every system sits at the intersection of these three forces:
- Users tell you whether processing is synchronous or asynchronous
- External Services tell you where you need queues for resilience
- Time tells you where you need workers for batch processing
When you can identify which external entities are pushing on your system, the building block choices start to become obvious. That is the goal. Not to memorize patterns, but to see the forces that make one pattern the right choice and another the wrong one.
Next, we will see all of these forces in action when we break down how Netflix actually works using the building blocks. And if you want to see how external entities shape the full decision framework, that ties everything together.