Learning bite
System design: requirements, interfaces, and trade-offs
Turn a MicroBank user journey into a bounded design with explicit evidence and unknowns.
On this page
Begin with the user journey
Use the MicroBank deposit journey from DevOps Foundations: submit a transaction, identify the accepted operation, and inspect its eventual Ledger effect. Separate request acceptance, durable storage, and the user-visible result. A successful health endpoint does not prove that all three happened.
Before drawing components, write what the design must do and what remains outside scope. Ask about expected users, traffic shape, latency, consistency, data sensitivity, retention, recovery, and operating budget. Where a requirement is unknown, label it unknown and propose how to obtain it. Keep traffic estimates and availability targets tied to evidence or clearly stated requirements.
Work one requirement into an interface decision
For an invented requirement, suppose a caller must safely retry after losing a deposit response. A vague “highly available API” does not specify the answer. A concrete interface can require an idempotency key, define its scope per account, reject a changed payload under the same key, and return the original operation identifier on a valid retry. The database and application must implement that promise together.
Practice with two options: keep the accepted request while Ledger processes asynchronously, or wait for a Ledger result before responding. The first needs a visible pending state and a way to query progress. The second adds a dependency to response latency and still needs a rule for a lost response. Neither removes the need to reconcile an ambiguous result. Write the chosen user experience before drawing extra components.
Build a design in layers
| Layer | Decision to record | MicroBank exercise |
|---|---|---|
| User behavior | What counts as success and failure? | Accepted deposit versus verified Ledger entry |
| Interface | Validation, response, identity, timeout, retry | What can a caller safely do after losing a response? |
| Data ownership | Source of truth and transaction boundary | Accounts request record versus Ledger entries |
| Communication | Synchronous call or asynchronous message | Acceptance can precede Ledger convergence |
| Read path | Freshness, pagination, and cache policy | A cached balance must not authorize an unsafe withdrawal |
| Runtime | Routing, service discovery, placement | More replicas do not remove a shared database bottleneck |
| Operations | Measurements, recovery, ownership, cost | Which local observation proves the journey completed? |
A load balancer spreads requests but does not resolve a write race. A cache can reduce repeated reads but creates invalidation and freshness decisions. A queue decouples arrival from processing but introduces backlog and replay decisions. Replication can improve availability while changing consistency behavior; partitioning changes data placement and cross-partition operations. Choose each component to address a specific constraint.
Separate observed, proposed, and unverified
Inspect your selected MicroBank revision. Use three labels on the diagram: observed in source, observed in a run, and proposed change. The reference revision is f75da680251eebeb38bf17bce3e49b2fea8385c0; later local fixes may differ, so record your own commit and dirty state.
The reference Accounts service writes a transaction and outbox row in one database commit. Its outbox publisher sends through SNS; the Ledger consumer reads from SQS and removes a message after processing. This establishes places to investigate, not proof of end-to-end correctness or production readiness. Authentication and authorization also require backend evidence; a frontend login alone is insufficient.
Checkpoint and revision
Produce a one-page design brief with the journey, success condition, interface contract, state owners, dependency arrows, and three unanswered questions. Compare one simpler design with one proposed extension. Explain the cost of the extension, including what another operator must diagnose when it fails.
Bring this brief into the final design lab. Use the later Kubernetes, GitOps, observability, and SRE modules to test and refine its assumptions.
Checkpoint guide: a useful open question names the missing fact and the decision it affects: “What deadline must the user receive for completion?” guides timeout/notification design. “Do we need Kubernetes?” does not answer the user contract. Carry one concrete contract into the distributed-failure matrix next.
Sources
MicroBank transaction service at the reference revision↗, Google SRE: implementing user-oriented SLOs↗, and AWS transactional outbox pattern↗.
Your notes and evidence
Record observations, questions, or links to your work. Keep credentials out of your notes.
Back up or restore this path
Progress and notes stay in this browser. A backup contains only this learning path.