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
$ 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.
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.
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.
$ 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
$ 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
$ 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
$ 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.