TLS session caching cuts the CPU cost of repeated HTTPS handshakes and reduces latency for clients that reconnect often. On busy Nginx reverse proxies and web servers, resumption is one of the simplest ways to lower handshake overhead without changing application behavior.

Nginx exposes TLS resumption through ssl_session_cache and ssl_session_timeout. A shared cache creates a memory zone that all worker processes can use, which keeps resumed TLS 1.2 handshakes available across workers and avoids relying on the per-worker OpenSSL built-in cache.

Cache size and timeout should match the traffic pattern: one megabyte stores about 4,000 sessions, the timeout defaults to 5 minutes, and current Nginx releases also use the shared cache to generate and rotate session ticket keys unless ssl_session_ticket_key files are configured explicitly. TLS session tickets remain enabled by default, so the verification commands below disable tickets on the client side with -no_ticket to prove that the shared session cache is working.

Steps to enable TLS session caching in Nginx:

  1. Create or update a TLS session cache snippet that is loaded from the http context.
    $ sudo tee /etc/nginx/conf.d/tls-session-cache.conf >/dev/null <<'EOF'
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 10m;
    EOF

    shared:SSL:10m creates a 10 MB memory zone shared across all Nginx workers, and the same directives can be placed inside a single TLS server { } block when only one site should use them. If the packaged layout does not load /etc/nginx/conf.d/ from http { }, add the same directives to the active file that does.

  2. Test the Nginx configuration for syntax errors.
    $ sudo nginx -t
    nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
    nginx: configuration file /etc/nginx/nginx.conf test is successful

    A failing test prints the first file and line that stopped parsing, and that error must be fixed before a reload can succeed.

  3. Reload the nginx service to apply the new configuration.
    $ sudo systemctl reload nginx

    On systems without systemd, a graceful reload can be triggered with sudo nginx -s reload.

  4. Save a resumable TLS 1.2 session without session tickets to a temporary file.
    $ openssl s_client -connect example.com:443 -servername example.com -tls1_2 -no_ticket -sess_out /tmp/nginx-tls-session.pem </dev/null
    CONNECTED(00000003)
    ##### snipped #####
    New, TLSv1.2, Cipher is ECDHE-RSA-AES256-GCM-SHA384
    ##### snipped #####
    Verify return code: 0 (ok)

    -no_ticket disables TLS session tickets for the client test so the result reflects the shared session ID cache instead of ticket-based resumption.

  5. Repeat the connection with the saved session to confirm resumption from the shared cache.
    $ openssl s_client -connect example.com:443 -servername example.com -tls1_2 -no_ticket -sess_in /tmp/nginx-tls-session.pem </dev/null
    CONNECTED(00000003)
    ##### snipped #####
    Reused, TLSv1.2, Cipher is ECDHE-RSA-AES256-GCM-SHA384
    ##### snipped #####
    Verify return code: 0 (ok)

    If the second handshake stays at New, check directive inheritance, timeout expiry, cache size, and whether a load balancer sent the follow-up connection to a different Nginx node.

  6. Remove the temporary session file.
    $ rm --force /tmp/nginx-tls-session.pem

    The session file can contain resumption material and belongs in /tmp/ only for short-lived verification.