TLS/SSL performance is often crippled by the overhead of repeated full handshake negotiations, but session reuse and modern extensions can make it practically free for subsequent connections.

Let’s see session reuse in action. Imagine a client connecting to a web server.

Client Hello (new session)
  -> Server Hello (negotiates cipher, sends session ID)
  -> Server Certificate
  -> Server Key Exchange
  -> Server Hello Done
  -> Client Certificate (if requested)
  -> Client Key Exchange
  -> Change Cipher Spec
  -> Finished
  -> Change Cipher Spec
  -> Finished
(Encrypted data exchange begins)

Now, if the client needs to connect again shortly after and the server still remembers the session ID, it looks very different.

Client Hello (resumes session ID)
  -> New Session Ticket (from server, contains encrypted session state)
  -> Change Cipher Spec
  -> Finished
(Encrypted data exchange begins)

Notice how many fewer round trips are involved. The client and server already agreed on ciphers and keys, so they just need to confirm that agreement and get to encrypting data. This is session reuse.

The same principle applies to OCSP stapling and ALPN. OCSP (Online Certificate Status Protocol) is how clients check if a server’s certificate is still valid. Without OCSP stapling, the client has to make a separate request to the Certificate Authority (CA) to check the status. This adds latency. With OCSP stapling, the server periodically queries the CA for its certificate’s status and "staples" that signed response into the TLS handshake itself. The client then trusts this stapled response because it’s signed by the CA.

ALPN (Application-Layer Protocol Negotiation) is crucial for performance in protocols like HTTP/2. When a client and server establish a TLS connection, they might support multiple application protocols (like HTTP/1.1 and HTTP/2). ALPN allows them to negotiate which protocol to use during the TLS handshake. This prevents the client from having to establish a TLS connection and then discover that the server only supports an older, slower protocol, forcing another connection attempt.

Here’s a simplified view of how ALPN works within the TLS handshake. The client advertises the protocols it supports in its Client Hello:

Client Hello
  -> Extension: ALPN (protocols: ["h2", "http/1.1"])
  -> ... other extensions ...

The server, if it supports ALPN and a protocol the client also supports, will indicate its choice in the Server Hello:

Server Hello
  -> Extension: ALPN (protocol: "h2")
  -> ... other extensions ...

Now, both client and server know to use HTTP/2 for this connection, avoiding a separate negotiation step after the TLS handshake.

To configure session reuse on an Nginx server, you’d typically adjust ssl_session_cache and ssl_session_timeout. A common configuration might look like:

ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;

This sets up a 10MB shared cache for SSL session IDs and allows sessions to be reused for up to 10 minutes. The shared:SSL:10m part means a shared memory zone named SSL with a size of 10 megabytes. This allows multiple Nginx worker processes to access the same session cache. The timeout determines how long a session ID remains valid in the cache.

For OCSP stapling with Nginx, you’d use ssl_stapling on; and ssl_stapling_verify on;. You also need to specify the trusted CA certificates that Nginx will use to verify the OCSP responses:

ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /etc/nginx/ssl/my_domain.chained.crt;

The ssl_trusted_certificate directive points to a file containing your server certificate and any intermediate certificates needed to form a chain back to a trusted root CA. Nginx uses this chain to validate the OCSP response it receives from the CA.

For ALPN, especially if you’re serving HTTP/2, you need to ensure your listen directive includes the http2 parameter and that your ssl_protocols and ssl_ciphers are set appropriately for modern TLS versions.

listen 443 ssl http2;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:...'; # A strong, modern cipher suite

The http2 parameter on the listen directive tells Nginx to enable HTTP/2 support over TLS. Nginx then automatically handles the ALPN negotiation during the TLS handshake when http2 is enabled.

The most surprising thing about these optimizations is how much of the "work" of establishing a secure connection is actually just negotiation, and how much of that negotiation can be skipped or pre-computed. A full TLS 1.3 handshake with modern ciphers can be as fast as one round trip, but the real win comes from avoiding that entirely with session resumption, which can be nearly zero round trips. The computational cost of validating a certificate and agreeing on keys is significant; doing it once and reusing the result is a massive performance gain.

The next hurdle after optimizing these aspects is often managing certificate expiry and ensuring your cipher suites remain secure against evolving threats.

Want structured learning?

Take the full Tls-ssl course →