We started with one click: Place Order. The interface presents it as one action, but the request moves through several components before the user sees a result. At every handoff, it can wait, fail, or be attempted again.
This final episode puts that full path back together.
- 01DeliveryLook up the addressRequestDNS finds an IP
- 02DeliveryFind the building and receiving doorRequestIP address and port
- 03DeliveryTrack numbered parcels and receiptsRequestTCP orders and acknowledges bytes
- 04DeliverySeal the parcel and verify the facilityRequestTLS protects the channel
- 05DeliverySort it at the distribution centreRequestThe edge chooses a backend
We are still following the systems path of the request, so this recap does not cover every responsibility of a production API. Authentication, authorization, input schemas, cookie and session security, CSRF, and detailed error contracts need their own treatment. A real checkout still has to handle all of them.
1. The browser creates intent
The UI validates what it can, gathers the cart and delivery choice, and creates a request. It assigns an idempotency key so a retry can refer to the same intended order.
POST /orders
Idempotency-Key: checkout_8a10d2
Content-Type: application/json
{"cartId":"cart_42","deliveryOption":"standard"}
Client-side validation gives the user faster feedback. The server still validates everything because the client can be stale, modified, or acting at the same time as another client.
2. The client locates and secures the service
DNS maps the hostname to an address for an edge. Routing moves packets toward it. TCP or QUIC establishes transport state. TLS authenticates the hostname and derives keys that protect application data.
On a warm path, the browser may reuse a cached DNS answer and an existing HTTP/2 or HTTP/3 connection, skipping much of this setup. I still use the cold path as the diagnostic map when a first request is slow or the connection fails.
TLS may end at a CDN or load balancer, followed by another protected connection to the application. The team needs to know where that boundary sits and how the next hop is secured. The public https URL does not tell us that by itself.
3. The edge admits and routes the request
The edge applies limits and chooses a destination. A Layer 4 component may distribute connections. An HTTP-aware reverse proxy can route /orders to the order service, enforce deadlines, and forward trusted client context.
Health checks decide which instances may receive new work. Graceful shutdown removes an instance from rotation before terminating in-flight requests.
During overload, the edge also decides which work the system should admit. Rejecting requests that cannot finish protects enough capacity to complete work the system has already accepted.
4. Node turns bytes into application work
The kernel accepts the connection and buffers network data. Node’s runtime receives readiness notifications, parses HTTP, and schedules JavaScript callbacks. Framework middleware authenticates, validates, adds tracing context, and selects the route.
The event loop keeps many I/O operations in progress without assigning one JavaScript thread to every wait. CPU-heavy synchronous work still blocks other request callbacks, so it belongs in bounded worker threads, separate processes, or another service when necessary.
The handler inherits a deadline. When the caller no longer cares or the remaining budget cannot complete useful work, downstream calls should be cancelled where possible.
5. The database protects durable invariants
The handler waits for a pooled PostgreSQL connection. PostgreSQL parses and plans SQL, uses indexes to locate candidate tuples, applies MVCC visibility rules, and writes durable WAL for committed changes.
Inventory correctness lives at a serialization point. A conditional update can reserve the last item atomically:
update inventory
set available = available - 1
where sku = $1 and available > 0
returning sku;
Constraints keep protecting the invariant when a new code path forgets an application check. Transactions make related database changes atomic, but they should not stay open while the application waits on a slow network call.
6. Slow external work becomes a state machine
Payment may finish before the request deadline or continue in the background. In either design, a timeout means the caller does not know the outcome. It does not prove that payment failed. The workflow uses a stable idempotency key and later reconciles its state with the provider.
If the API responds before final payment, it returns an honest intermediate state:
{
"orderId": "ord_123",
"status": "payment_pending"
}
The database transaction records both the order and an outbox event. A publisher delivers the event to a queue. At-least-once delivery means workers must safely handle duplicates.
Payment, order, reservation, and fulfillment move through explicit valid transitions. Compensating actions such as releasing stock or issuing a refund repair cross-system workflows that cannot share one transaction.
7. The response is one observation, not the truth
The API returns 201 Created, 202 Accepted, or a deliberate error. The reverse proxy forwards it over the client connection. The browser updates the interface.
The response may be lost after the order commits. A retry therefore needs the same idempotency identity, and the client needs a way to fetch the order state. The durable record remains the source of truth even when the browser never receives the original response.
8. Telemetry connects the boundaries
A trace follows the critical path from edge to handler, pool wait, queries, and payment. Metrics show request rate, error rate, latency percentiles, and saturation. Structured logs record meaningful discrete events with trace and business identifiers.
Measure queueing separately from execution:
- socket and proxy wait;
- event-loop delay;
- database pool wait;
- lock wait;
- message age;
- downstream concurrency wait.
Without separate queue measurements, a fast query behind a long connection-pool wait looks like a slow database.
The complete map
user click
→ browser validation + idempotency identity
→ DNS
→ transport + TLS
→ CDN / load balancer / reverse proxy
→ kernel socket queues
→ Node HTTP parsing + middleware + route
→ database pool
→ PostgreSQL plan + index + MVCC + transaction + WAL
→ durable order and outbox event
→ payment worker / provider / webhook / reconciliation
→ order state query or notification
→ user sees the result
This is the logical path, not a promise that every request touches every box. A warm connection may skip setup, a cache can satisfy a read, and payment may stay synchronous. One infrastructure product may also perform several of the jobs shown here. The map is useful because it tells us who owns each part of the work.
Diagnose by asking how far it got
When an order is missing or slow, locate the last confirmed boundary:
| Evidence | What to inspect next |
|---|---|
| DNS failed | records, resolver behavior, delegation |
| TLS failed | hostname, certificate chain, protocol negotiation |
| Edge logged request; app did not | routing, health, upstream connection, sampling |
| Handler started; no DB span | application work, event-loop delay, instrumentation |
| Pool wait is high | pool sizing, query duration, transaction lifetime, instance count |
| Inventory update affected zero rows | stock exhausted or wrong key |
| Order committed; no payment message | outbox publisher and queue delivery |
| Payment succeeded; UI says pending | webhook, consumer idempotency, state transition |
| Client timed out; order exists | deadline alignment and idempotent recovery |
I prefer asking “how far did it get?” instead of starting with “which service is down?” The first question follows the evidence through the request path before we guess which component or team owns the failure.
The principles that survive implementation changes
Across all twelve episodes, these are the ideas I keep coming back to:
- Every abstraction has a boundary. Know where ownership and failure change.
- Users experience time spent waiting too, so measure queues as well as execution.
- Retries create another attempt. Idempotency gives repeated delivery one business meaning.
- Correctness needs one place where competing decisions are serialized.
- Async workflows introduce states such as pending, unknown, failed, and compensated. Model them explicitly.
- Scaling one part of the system moves pressure to the next dependency.
- A response can be lost. Design around the durable state and provide a way to reconcile it later.
- Instrument the places where the architecture waits or hands work to something else.
You do not need to memorize every packet field or PostgreSQL subsystem. You need to know how to follow the request when an abstraction stops hiding the details. Find the last confirmed boundary, check where work is waiting, identify the invariant being protected, and use the evidence the system recorded.
One click has taken us through the full systems journey. The next set of topics starts with the security and API contract around the request: who may send it, which input the server accepts, and what each response promises.
