Senior Engineering Interview Handbook / Chapter 969
Appendix E - Architecture Component Catalogue
A technical-foundation appendix for choosing databases, caches, queues, gateways, CDNs, search indexes, schedulers, workflow engines, blob stores, vector stores, and observability systems without turning a system design into a collection of familiar boxes.
Page tools
A box is a claim
Putting a component on a design says that it owns some work. It also says the team accepts a new failure boundary, a new body of state or policy, and a new operating obligation. If none of those can be named, the box is decoration.
Start with a verb: persist an order, route a request, buffer work, index text, schedule a deadline, or diagnose a failed attempt. Then choose the smallest component that can own that responsibility. Product names can wait.
The rejected alternative is important. “Add a cache” is recall. “The database meets the freshness requirement but not the measured read latency, and these objects can be stale for one minute” is a decision.
The catalogue
The final column is part of the choice, not cleanup to perform later. If the design cannot carry the obligation, reject the component even when its upside is attractive.
| Component | Responsibility it can own | Introduce it when | Obligation it creates |
|---|---|---|---|
| Relational database | Canonical structured state whose relationships and invariants need transactions, constraints, joins, or flexible queries. | Several records must change consistently, or the database must reject an invalid state. | Schema evolution, contention, query plans, connection pressure, backup, restore, and replica lag. |
| Key-value or document store | Records addressed by a known key or aggregate, with data shaped around established access paths. | Key-local reads and writes dominate and cross-record relationships are limited or handled elsewhere. | Partition-key choice, hot keys, conditional updates, secondary-index limits, and application-enforced relationships. |
| Cache | A disposable copy or computed result that shortens a hot read path. | The source path is too slow or costly and the product can state a freshness rule. | Key design, invalidation or TTL, miss behavior, stampede control, eviction, and permission-safe contents. |
| Queue or durable log | Work or facts that producers can publish without waiting for every consumer. | A synchronous side effect may be delayed, load must be buffered, or consumers need independent replay. | Delivery semantics, stable event identity, idempotent effects, ordering scope, lag bounds, poison work, and replay. |
| Load balancer | Distribution of traffic among serving endpoints judged healthy. | More than one endpoint serves the same contract or failure of one must not end the service. | Health-check truth, draining, uneven load, connection behavior, locality, and a plan for balancer failure. |
| API gateway | Shared edge policy such as authentication, quotas, routing, or protocol adaptation. | Several clients or services need one enforceable external contract. | Policy rollout, added latency, capacity, bypass resistance, failure blast radius, and ownership of what stays out of the gateway. |
| CDN | Geographically distributed delivery of cacheable bytes or responses. | User distance or origin load harms a path whose content has an explicit cache and purge policy. | Cache keys, purge delay, stale behavior, origin protection, personalization boundaries, and access control at the edge. |
| Search index | A derived retrieval view for tokenization, ranking, facets, or fuzzy matching. | Authoritative-store queries cannot provide the required retrieval quality or latency. | Ingestion lag, delete propagation, rebuilds, tenant isolation, ranking evaluation, and a clear source of truth. |
| Scheduler | Creation of work at a future time or cadence. | Time itself releases an otherwise independent action. | Time-zone and daylight-saving rules, missed and duplicate runs, clock skew, catch-up policy, and durable schedule state. |
| Workflow engine | Durable progress through a multi-step process with waits, retries, and recovery. | The business process outlives one request and its intermediate state must be visible and repairable. | Deterministic or version-safe definitions, activity idempotency, timeouts, compensation, migration, and manual intervention. |
| Blob store | Durable storage for large byte objects outside the primary record store. | Files, media, backups, or model artifacts need independent scale, retention, and transfer behavior. | Metadata ownership, checksums, permissions, malware handling, lifecycle rules, multipart failure, and egress cost. |
| Vector index or store | Nearest-neighbor retrieval over embeddings. | Similarity by learned representation has demonstrated product value that ordinary filters or text search cannot supply. | Corpus and embedding versioning, freshness, access filtering, relevance evaluation, privacy, drift, and re-embedding. |
| Observability system | Evidence about user journeys, component behavior, change, and invariant violations over time. | Operators must detect, explain, and act on failures across boundaries. | Signal ownership, cardinality, sampling, retention, sensitive data controls, alert actionability, and cost. |
These rows name families, not interchangeable products. A durable log and a work queue can both decouple producers, but replaying an ordered history is a different requirement from distributing tasks among workers. A document store and a key-value store may share a key-shaped access pattern while offering very different update and query semantics. A vector index may be a capability of an existing search or database system; semantic retrieval does not by itself justify another service.
Do not confuse the neighboring jobs
Several choices become clearer when the nearby component is stated and then rejected.
Canonical store, cache, search index. The canonical store decides what is true. A cache serves a disposable copy under a freshness policy. A search index answers a retrieval question from a derived view. If a deletion or permission change occurs, both derived paths need a bounded propagation and repair story; neither should quietly become a second authority.
Queue, scheduler, workflow. A queue says work may wait. A scheduler says when work becomes eligible. A workflow says which durable step follows which, including what happens after timeout, retry, or human intervention. A nightly independent cleanup may need only a scheduler and a queue. A refund that waits for a provider, branches on the result, and requires reconciliation has workflow state whether or not a workflow product is used.
Load balancer, gateway, CDN. A load balancer chooses a serving endpoint. A gateway applies shared edge policy. A CDN serves eligible content from distributed caches. One platform may implement all three, but the explanation should keep their responsibilities and failure policies separate.
Metrics, logs, and traces. These do not make an architecture observable by mere presence. Begin with a user promise or invariant. Use a metric to show scope and trend, a trace to follow an attempt across calls and queued work, and a structured log to explain a local decision. Keep a durable business identifier when a request ID will not survive retries or redelivery.
Let one design earn its components
Consider document ingestion for a multi-tenant search product. The first version needs only two durable truths: a document record that owns tenant, permissions, checksum, and processing state; and the uploaded bytes. A relational database and blob store can own those responsibilities. The upload may return success only after both can be reconciled, rather than after bytes arrive in an unowned bucket.
Now impose a latency requirement: text extraction can take several minutes, while upload acknowledgement must take seconds. A queue earns its place because extraction no longer belongs on the request path. The new design must give every document version a stable identity, make workers safe to retry, put a bound on queue age, and expose poison files for repair. Without those answers, the queue has moved the failure rather than handled it.
Users then require ranked full-text retrieval. A search index becomes a derived read model, not the authority for the document or its permissions. The design needs a lag objective, permission-safe indexing, deletion propagation, and a rebuild path from canonical state. “Upload complete” and “searchable” are now different user-visible states.
Suppose product discovery shows that people also need semantic retrieval over specialized terminology. Test that claim against full-text search before adding a vector index. If offline judgments and live outcomes show a useful gain, record which document and embedding versions produced each vector and apply tenant permissions before results escape. If the gain is unproved, the search index remains the simpler design.
Finally, ask whether a workflow engine is necessary. Independent extraction and indexing tasks with idempotent workers may be recoverable from explicit database states and queues. If the process grows to include human review, long waits, branching conversions, compensation, and versioned recovery, a workflow engine may earn its operational cost. Complexity is evidence for examining the boundary, not automatic permission to add it.
Throughout the design, observability follows the user journey: upload accepted, bytes durable, extraction progressing, document searchable, and permissions correct. Queue age, failure class, index lag, and a cross-system document-version identifier help an operator decide whether to retry, repair, or stop. A dashboard of green machines cannot prove that a particular document is discoverable by the right tenant.
Rehearse rejection, not recall
Take a design you have already completed. Choose one box and say, in order:
- the user or operating requirement that introduced it;
- the exact responsibility and state or policy it owns;
- the simpler alternative and the evidence that ruled it out;
- the new failure the component introduces;
- the signal and repair action for that failure.
Then remove the box. If nothing breaks, leave it out. If something does break, name the broken promise rather than restoring the component by habit.
For a second pass, mutate one constraint: require immediate deletion, remove staleness tolerance, increase one tenant’s load by one hundred times, forbid duplicate effects, or require recovery after a day-long outage. The best component choice may change. The responsibility and product promise should remain visible while it does.