Understand the building blocks / CHAPTER 07
System design building blocks
Follow one request through compute, storage, networking, and background work.
Builds on A practical system design template.
- Assign a clear responsibility to each building block.
- Separate persistent truth from replaceable processing.
- Trace success and partial failure through a simple service.
01Meet the parts through one photo
Aya uploads a 6 MB photo. The service saves the original and later creates a 60 KB thumbnail. Start with the jobs required by that operation:
- The application verifies Aya and records which photo belongs to her.
- File storage retains the original bytes.
- Saved pending work tells a worker to create the thumbnail.
- The worker writes the thumbnail and records completion.
- A later read checks Aya’s permission and returns the permitted image.
The usual component names describe these jobs:
- Compute runs the application or worker instructions.
- A database saves structured records and supports queries and changes.
- Object storage saves named files such as the original and thumbnail.
- A queue conveys pending work to workers under its delivery rules.
- A cache keeps reusable copies that can be rebuilt from saved originals.
- Networking carries requests between them, where delay or lost responses can leave one part finished and another uncertain.
Choose which saved data decides each question. The database says who owns the photo and whether it is pending, processing or ready. Object storage holds the actual files. These are the sources of truth for those different questions; a cached list or queue message does not replace them.
These jobs can begin in a small deployment. A separate name in the diagram does not require a separate team or independent service.
02Trace upload, processing, and viewing
Call Aya’s photo p18, so upload, work and reads can refer to the same photo. The phone sends bytes directly to private storage while the application controls permission and completion:
- Verify Aya and create a pending photo record for
p18. - Grant short-lived permission to upload the intended original, within the size limit.
- Transfer the original and verify that the expected complete file exists.
- In one database transaction, change
p18to processing and save a pending thumbnail-job record referring to it. - Return the completed upload result after its required bytes and records are retained. The thumbnail may still be processing.
- A publisher reads pending job records and sends them to the queue.
- A worker creates and verifies the thumbnail, then records that this photo/job finished and changes
p18to ready.
The pending-job row saved with the photo change is a transactional outbox. Its purpose is specific: if the application crashes after step 4 but before sending the queued task, a publisher can still find the saved work.
Measure both acceptance and completion:
- An uploaded original may correctly show processing while the thumbnail runs.
- A queue can hold a temporary burst, but it does not increase the worker’s sustained processing rate.
- Track how long the oldest pending photo has waited. Fast upload responses can hide a growing thumbnail delay.
03Close the gaps between components
The publisher may send a job, then crash before saving that it sent it. Another publisher can therefore send the same job again. Handle the repeated job through stored data:
- The worker reads the job and photo record. If that same job already completed, use its saved result rather than create another photo.
- If unfinished, prepare the thumbnail for the repeatable output name derived from this photo and transformation version. In this example, the file store must expose only complete writes and support creating that named object only if it is absent.
- If an earlier or competing attempt already created that output, verify its completeness and the photo/transformation version before reusing it. A failed check leaves the photo processing or failed until the bad output is repaired; it must not become ready.
- In a supported database update, record job completion and make the same photo ready only if its expected job/state still matches.
- If the worker crashes between output and completion, a later attempt can verify the existing file and finish the missing record update.
The job identifier and saved completion check suppress repeated logical results. They do not prevent every repeated computation. Only one attempt can create the named object; a competing attempt verifies and reuses that object. The complete-write and create-if-absent rules prevent readers from seeing a partly written replacement. A store without those operations needs another publication procedure before this design can use it.
Use saved state for each other failure:
- An unfinished phone upload remains pending until confirmation or cleanup.
- A lost confirmation response repeats the same photo identifier.
- An outbox publisher recovers unsent work from database rows.
- A vanished cache is rebuilt from metadata and retained files.
A replica is another current copy; a backup preserves recoverable history. A mistaken deletion can reach every replica. Test a restore from suitable history as well as a replacement server, and check both original bytes and metadata.
Upload confirmation creates recoverable thumbnail work
Follow the numbered arrows
- Aya’s phone → Private originalupload the allowed file within its size limit
- Private original → Photo status and pending workconfirm expected bytes
- Photo status and pending work → Pending-work publisherload saved thumbnail task
- Pending-work publisher → Thumbnail workersend the same photo p18 task on retry
- Thumbnail worker → Photo marked readyverify output and commit state
Trace the diagram in words
- Separate completed bytes from confirmed metadata.
- Commit pending work with processing state.
- Verify or create the complete named thumbnail, then finish the matching job and photo record.
04Choose deployment boundaries deliberately
Suppose thumbnail jobs need more CPU while account reads remain modest. Decide how much of the application should be deployed and scaled separately.
- A modular monolith keeps related code in clear modules, such as accounts and photos, but releases one application. Calls can remain local function calls, and related records may share a database transaction.
- Microservices run selected responsibilities as independently deployed services. A team can release or scale its service without replacing every other part.
- An application plus a separately scaled thumbnail worker pool may already solve this workload. It need not become many autonomous services.
A split is useful when it buys a concrete benefit:
- Thumbnail capacity can grow without multiplying account servers.
- A team can release the worker independently when that is needed.
- A failed transformation process can be isolated from interactive reads.
Account for the new work before splitting:
- A remote call can finish while its response is lost, so callers need defined retry and recovery behavior.
- Different deployed versions must agree on requests, fields and errors.
- A change spanning two independent stores may no longer fit one transaction.
Choose the simplest deployment that meets these needs. Explain where accepted work is saved and how another process resumes it; counting services does not establish either property.
DRAW. CALCULATE. EXPLAIN.
Recover a duplicate thumbnail job
20 minutes · guided practice
Photo p18 has one saved pending thumbnail job. The publisher sends it twice. The first worker writes the thumbnail, then crashes before marking it ready.
- Show what the second worker reads before doing work.
- Explain how it finds and verifies the existing output.
- Show the saved completion update that keeps one photo.
Compare the worked solution
- Both deliveries name the same photo and transformation job. Read that job’s saved result and current photo status. A completed matching job does not need another photo or result.
- For an unfinished job, inspect its repeatable output name. Reuse a complete file only after checking its photo/transformation version. If absent, create the complete output only if that name is still absent; if another worker wins, verify its file. A corrupt existing file must be repaired before ready status is allowed.
- Save job completion and the processing-to-ready update for the same photo under a checked database operation. Reject a completion that no longer matches the expected job.
- Retain pending information until unfinished publication and work can be recovered. Monitor photos stuck processing; do not infer readiness merely because the queue delivered a task.
The checkboxes record your own assessment. The worked solution gives you a way to check the reasoning.
RETRIEVE BEFORE YOU REVEAL
Keep the important ideas.
Say the answer aloud, then turn the card over.
CARD 01Which saved records and files must the photo service trust?
- The database records ownership and processing status.
- Object storage retains original and thumbnail files.
- A cache is a replaceable copy.
- Saved work records let another process resume a job.
Losing a temporary component must not erase the only required record or file.
CARD 02What does an outbox solve?
- Save the photo change and pending job together.
- A publisher sends the saved job later.
- A worker checks whether that job already completed, verifies or creates its named output, then saves completion.
The outbox prevents forgotten publication; delivery can still repeat.
CARD 03When should a module become a service?
- Keep modules together when local calls and shared transactions meet the need.
- Split when independent capacity, releases or failure protection gives a concrete benefit.
- Include timeouts, compatible interfaces and recovery of partially finished cross-service work in the cost.
CHECK THE REASONING
Can you explain the choice?
Answer every question, then finish for an immediate score and an explanation for each answer. Aim for 80%, then revisit any gaps.
CLOSE THE LOOP
Explain it without the page.
Summarise the mechanism, one trade-off, and one failure mode. Then mark this chapter complete.