ARCHIVED from builddistributedsystem.com on 2026-04-28 — URL: https://builddistributedsystem.com/tracks/proxies
Tracks/Proxies
12

Proxies

Intermediate
Scalability|10 tasks

Build proxy servers that relay requests, deduplicate calls, and implement collapsed forwarding to reduce backend load. Learn how proxies serve as building blocks for scalable architectures.

Subtracks & Tasks

Interview Prep

Common interview questions for Infrastructure / Platform Engineer roles that map directly to what you build in this track. Click any question to reveal the model answer.

Model Answer

A reverse proxy sits in front of backend servers, receiving client requests and forwarding them on behalf of the servers. It can do TLS termination, compression, caching, authentication, request transformation. A load balancer is a specific type of reverse proxy that distributes requests across multiple backends. The distinction is blurry — Nginx and HAProxy do both. "Load balancer" emphasizes traffic distribution; "reverse proxy" emphasizes the request manipulation and forwarding role.

Model Answer

A service mesh provides network-level features (retries, timeouts, circuit breaking, mTLS, observability) via sidecar proxies, without any changes to application code. Reasons to use over application-level implementation: (1) language-agnostic — works for every language/framework in your infrastructure, (2) consistent policy enforcement — the same retry/timeout configuration across all services, (3) observability without instrumentation — L7 metrics for every service-to-service call automatically, (4) security — mTLS between all services without application changes. Cost: operational complexity, added latency per hop (~1ms for Envoy), large memory footprint at high pod counts.

Model Answer

Envoy's circuit breaker is resource-based, not error-rate-based (unlike Hystrix). It tracks: max_connections (concurrent TCP connections to upstream), max_pending_requests (queued requests waiting for a connection), max_requests (concurrent active requests), max_retries (concurrent active retries). When any limit is exceeded, new requests fail immediately with 503. For error-rate-based outlier detection, use Envoy's outlier_detection config: consecutive 5xx errors, success rate thresholds, and latency percentile thresholds trigger ejection of hosts from the load-balancing pool.

Model Answer

Without resilience: the timeout propagates up. The backend waits for the downstream timeout (e.g., 30s), returns a 500, gateway returns 500, user waits 30s and sees an error. With resilience: (1) The downstream has a short timeout (e.g., 2s), not 30s. (2) The backend uses a circuit breaker — if the downstream has been failing, fail fast without waiting. (3) The backend returns a degraded response (partial data) rather than a 500 if the failed downstream is non-critical. (4) The gateway adds a hedge or retry. This is the resilience pattern Netflix called "graceful degradation" — the system stays available with reduced functionality rather than fully failing.

Model Answer

Request mirroring: send a copy of live production requests to a shadow service, discard responses, without affecting the user. Use cases: (1) testing a new service version with real traffic before cutover — any differences in behavior are logged but do not affect users, (2) load testing a new implementation under real traffic patterns, (3) comparing old and new algorithm outputs. Envoy supports request mirroring natively via the request_mirror_policy config. Netflix's Diffy tool performs differential testing this way. The shadow service should not have side effects (no emails, no payment processing) — typically use a read-only mode or mock dependencies.

Questions are representative of real interview patterns. Model answers are starting points — adapt them with your own experience and the specific context of the interview.

Common Mistakes

The top 5 mistakes builders make in this track — and exactly how to fix them. Click any mistake to see the root cause and the correct approach.

Why it happens

The backend server sees the connection as coming from the proxy. Without additional headers, the real client address is lost.

The fix

Set `X-Forwarded-For` (or `X-Real-IP`) on the proxied request. On the backend, extract the client IP from this header, not from `remoteAddr`.

Why it happens

HTTP/1.1 defaults to keep-alive, but a naive proxy that does not support persistent connections closes and re-opens TCP connections for every forwarded request.

The fix

Maintain a connection pool to upstream backends. Reuse existing TCP connections for subsequent requests to the same backend. Most HTTP client libraries do this by default when keep-alive is enabled.

Why it happens

A buffering proxy stores the complete upstream response in memory before writing to the client.

The fix

Stream the response: read chunks from the upstream and write them immediately to the client without waiting for the full body.

Why it happens

A naive header-copy approach passes all client headers, including authentication tokens, to every upstream.

The fix

Maintain an allowlist of headers to forward. Strip `Authorization`, `Cookie`, and similar headers unless the upstream is explicitly trusted to receive them.

Why it happens

The backend redirects HTTP → HTTPS based on the scheme of the incoming request. The proxy connects to the backend over plain HTTP (internally), so the backend keeps redirecting.

The fix

Set `X-Forwarded-Proto: https` when the original client connected over HTTPS. Configure the backend to trust this header and use it to determine the original scheme rather than the internal connection scheme.

Comparison Mode

Side-by-side comparisons of the approaches, algorithms, and trade-offs you encounter in this track. Expand any comparison to see a detailed breakdown.

DimensionForward ProxyReverse ProxySidecar Proxy
Who initiates the connectionClient — proxies on behalf of clients to any serverExternal client — proxies to a known set of backendsLocal service — proxies all inbound/outbound traffic
PlacementClient-side (corporate network, VPN)Server-side (CDN edge, API gateway, Nginx)Same pod/host as the service (Envoy, Linkerd)
Aware of upstream identityNo — sees any destinationYes — routes to known backendsYes — service registry integration
mTLS / encryptionCONNECT tunnelling (opaque)TLS termination at the edgemTLS between every service pair
ObservabilityClient-side egress logsIngress logs + metricsPer-request traces, metrics, logs for every call
Operational overheadLowLow–MediumHigh (one proxy process per pod)
Verdict:Reverse proxy for ingress control. Sidecar proxy (service mesh) when you need uniform observability and mTLS across many services. Forward proxy for egress control and corporate filtering.

Concepts Covered

proxyforwardingrequest handlingdeduplicationidempotencyrequest coalescingcollapsed forwardingthundering herdcache miss handlingreverse proxyHTTP cachingCache-Controlhealth checkscircuit breakerfailoverAPI gatewayservice routingmicroservicesunified entry pointservice discoveryAPI gateway authenticationJWT validationOAuth2authorizationcentralized securitytoken validationrequest transformationresponse transformationprotocol translationformat conversionlegacy integrationAPI compositionaggregation patterndata compositionparallel requestsbackend fan-outresponse mergingrate limitingquota managementAPI tiersthrottlingusage trackingbilling integration

Prerequisites

It is recommended to complete the previous tracks before starting this one. Concepts build progressively throughout the curriculum.