Server
Reverse proxy
Reverse proxy is a server that sits in front of your application, accepts visitors' requests, and forwards them to the app. The visitor never talks to the app directly.
How it is measured
Confirm it by headers and logs. Look for `Via`, `X-Forwarded-For` and `X-Forwarded-Proto` on the app side, and for two entries in the chain: proxy log and app log for the same request. The proxy's time minus the upstream's shows its overhead.
Check what it does: TLS termination, caching, compression, rate limiting and routing to different backends by path.
Worked example
An Express app on port 3000 reads `req.ip` and logs 127.0.0.1 for every visitor, because Nginx connects to it locally. Rate limits in the app then treat all visitors as one person and block everyone after 100 requests.
Passing `X-Forwarded-For` from Nginx and setting `trust proxy` in Express makes the real addresses visible. Per-visitor limits start to work.
How it differs
A reverse proxy stands in front of servers and forwards requests to them. A load balancer chooses between several backends. A proxy can front one app, and a balancer needs more than one target. The proxy excludes any promise of spreading load, the balancer excludes caching or rewriting. Nginx and HAProxy do both.
Common errors
Forgetting to forward the client IP and protocol. Redirect loops because the app thinks requests are HTTP when the proxy terminated TLS. Trusting X-Forwarded-For from anyone. Buffering large uploads in memory. Leaving the app port reachable from the public internet.
In practice
Check that the app sees the real client IP and scheme, lock the app port to the proxy only, and put compression, caching and timeouts in the proxy where they are easy to change.