Enabling client keep-alive in Nginx lets one browser or API client reuse the same TCP connection for several requests instead of opening a new connection for every object, redirect, or follow-up call. That reduces handshake overhead and usually improves page latency, TLS efficiency, and frontend asset delivery on busy sites.
On the client-facing side, Nginx keeps persistent HTTP connections open for a bounded idle period with keepalive_timeout. The related keepalive_requests directive limits how many requests one connection can serve, and keepalive_time caps the total lifetime of that connection before Nginx closes it after a later request.
Examples below use packaged Nginx on Debian or Ubuntu with /etc/nginx/nginx.conf and nginx.service. Setting keepalive_timeout 0; disables client keep-alive entirely, and reverse-proxy reuse to backend servers is a separate setting: current upstream Nginx 1.29.7 and later proxy HTTP backends with keep-alive by default, while older packaged builds still need explicit proxy-side keepalive directives.
Related: How to improve Nginx performance
Related: How to tune worker_connections in Nginx
Steps to enable keepalive in Nginx:
- Open a terminal with a user account that can run sudo.
- Open the main Nginx configuration file or the included file that owns the http block.
$ sudo vi /etc/nginx/nginx.conf
On packaged Debian and Ubuntu systems, /etc/nginx/nginx.conf commonly includes additional files from /etc/nginx/conf.d/, /etc/nginx/sites-enabled/, or both. Place client keepalive directives at the http level unless you intentionally need a narrower server or location override.
- Enable client keep-alive by setting non-zero keepalive directives in the http block.
http { keepalive_timeout 15s 15s; keepalive_requests 1000; keepalive_time 1h; ##### snipped ##### }keepalive_timeout 75s; is the current default when the directive is unset. The zero value disables client keep-alive, and the optional second keepalive_timeout value adds a Keep-Alive: timeout= header that makes validation with curl easier.
Current Nginx defaults already use keepalive_requests 1000; and keepalive_time 1h;, so setting them explicitly is mainly about keeping the intended behavior obvious during reviews and future edits.
Keep the timeout long enough for normal page or API reuse, but not so long that idle clients consume too many file descriptors or worker_connections slots under load.
- If this server also proxies HTTP requests to an upstream on Nginx versions earlier than 1.29.7, keep backend connection reuse configured separately from client keep-alive.
location /api/ { proxy_pass http://app_backend; proxy_http_version 1.1; proxy_set_header Connection ""; }Current upstream Nginx 1.29.7 and later already proxy HTTP upstreams with HTTP/1.1 keep-alive by default. Older packaged builds such as Nginx 1.24.x still need the explicit proxy-side lines above.
- Test the updated configuration for syntax errors before reloading the daemon.
$ sudo nginx -t nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful
Related: How to test Nginx configuration
- Reload Nginx to apply the keepalive change without a full stop.
$ sudo systemctl reload nginx
Use sudo nginx -s reload when systemd is not managing the daemon, such as in some containers or hand-started test environments.
Related: How to manage the Nginx service
- Confirm that the service stayed active after the reload.
$ systemctl is-active nginx active
If the unit does not return active, inspect sudo journalctl --unit=nginx.service --no-pager --lines=20 before retrying the reload.
Related: How to manage the Nginx service
- Check the response headers and confirm the server is advertising a persistent connection.
$ curl -I -sS http://127.0.0.1/ HTTP/1.1 200 OK Server: nginx/1.24.0 (Ubuntu) Date: Thu, 09 Apr 2026 13:43:37 GMT Content-Type: text/html Content-Length: 20 Last-Modified: Thu, 09 Apr 2026 13:43:36 GMT Connection: keep-alive Keep-Alive: timeout=15 ETag: "69d7ad08-14" Accept-Ranges: bytes
If the response shows Connection: keep-alive but no Keep-Alive header, client keep-alive can still be working; the optional header is emitted only when you set the second keepalive_timeout value.
If the response shows Connection: close instead, search the active config for keepalive_timeout 0;, an explicit Connection: close header rule, or an upstream proxy or load balancer that is closing the client-side connection.
Mohd Shakir Zakaria is a cloud architect with deep roots in software development and open-source advocacy. Certified in AWS, Red Hat, VMware, ITIL, and Linux, he specializes in designing and managing robust cloud and on-premises infrastructures.
