Skip to content
← Production DevOps & SRE

Learning bite

System design: requirements, interfaces, and trade-offs

Turn a MicroBank user journey into a bounded design with explicit evidence and unknowns.

Documentation reviewed2026-10-01 · 3 min read
  1. Why
  2. Predict
  3. Try
  4. Inspect
  5. Explain
  6. Save evidence

Predict before you try

Can a result that works for one small example establish the algorithm or design works at its boundary?

Try it: Build a design in layers →
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

LayerDecision to recordMicroBank exercise
User behaviorWhat counts as success and failure?Accepted deposit versus verified Ledger entry
InterfaceValidation, response, identity, timeout, retryWhat can a caller safely do after losing a response?
Data ownershipSource of truth and transaction boundaryAccounts request record versus Ledger entries
CommunicationSynchronous call or asynchronous messageAcceptance can precede Ledger convergence
Read pathFreshness, pagination, and cache policyA cached balance must not authorize an unsafe withdrawal
RuntimeRouting, service discovery, placementMore replicas do not remove a shared database bottleneck
OperationsMeasurements, recovery, ownership, costWhich 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↗.

Prove what you learned

Inspect the result

Retain input/assumptions, expected result, actual trace and complexity or design limits.

Explain it in your own words

Explain why your observation supports the stated outcome, and name one thing it does not prove.

Try a small variation

Change one boundary condition—empty input, duplicate value, interval edge or missing dependency—and explain the outcome.

Your evidence should show

  • Record the context/revision or label the work as a paper or prepared fixture.
  • Compare the prediction with the actual result from “Build a design in layers”.
  • Retain input/assumptions, expected result, actual trace and complexity or design limits.
  • Explain the transfer challenge and retain the same verification question.
Hint

State the input assumptions and trace an empty, repeated or limiting case.

Answer guide: compare after predicting

No. Explain correctness and cost or the design trade-off, and compare a declared boundary case.

Compare this with your actual observation. A paper answer is useful reasoning practice; record execution separately.

Recall bounded loops, data types and explicit failure handling in Python. Revisit the previous lesson.

Save the prediction, result and explanation ↓

Your notes and evidence

Record observations, questions, or links to your work. Keep credentials out of your notes.

Loading saved progress…

Back up or restore this path

Progress and notes stay in this browser. A backup contains only this learning path.