For internet facing apps, yes, in nearly every case. The Fastify documentation calls exposing Node directly to the internet an anti pattern, and Node's own HTTP docs say that timeouts must be set when there is no reverse proxy, to protect against denial of service. A proxy or load balancer takes on the network edge jobs.
What the docs say
The Fastify recommendations page says the temptation is to write applications that handle multiple domains and ports and expose them directly, and that the team strongly considers this an anti pattern. Its reasons are added complexity in the application and blocked horizontal scalability. Its example needs are multiple instances, TLS termination, HTTP to HTTPS redirects, multiple domains and static files.
The Node.js http documentation says headersTimeout and requestTimeout should be non zero, for example 120 seconds, to protect against potential denial of service in case the server is deployed without a reverse proxy in front.
Express's own security guide recommends handling TLS with a dedicated server such as Nginx.
Who does what
| Job | Proxy or balancer | Your Node app |
|---|---|---|
| TLS certificates and termination | Yes | Optional |
| HTTP to HTTPS redirect | Yes | No |
| Slow client and header timeouts | Yes, first line | Yes, second line |
| Request size cap | Yes | Yes |
| Static files and compression | Often | Rarely |
| Authentication and authorization | Sometimes coarse | Yes, always |
| Input validation | No | Yes |
| Rate limits by account | No | Yes |
The right column never goes away. A proxy reduces exposure. It does not understand your business rules.
New risks the proxy brings
Putting a proxy in front changes what your app sees. Client addresses arrive in forwarded headers, so you must configure trust carefully. See Express trust proxy and Fastify trustProxy and rate limit keys. Make sure the app is only reachable through the proxy, otherwise a client can skip the proxy and send forged headers directly.
Steps
- Run the app on a private interface or network, reachable only from the proxy.
- Terminate TLS at the proxy and redirect HTTP to HTTPS there.
- Set client header and body timeouts and a body size cap on the proxy.
- Keep timeouts and limits in the app too. See Node.js HTTP server timeouts.
- Configure trust proxy to match your chain, and test with forged headers.
- Keep health checks and graceful shutdown aligned between proxy and app.
When you might not need one
Platform services that already put a managed edge in front of your code count as a reverse proxy for this purpose. What matters is that something other than your Node process faces the open internet.
Safeguard's asset discovery can help find services that are exposed without an edge in front, and a free scan is available at gold.safeguard.sh/scan.
Quick check
Is Node.js production ready without a proxy?
Node can serve HTTP directly, but the Fastify docs advise against exposing it, and Node's docs rely on timeouts to compensate when no proxy exists.
Does a proxy remove the need for body limits in my app?
No. Keep both, since internal traffic or misconfiguration can reach the app without the proxy.
Sources
Last reviewed: 19 October 2026.