Using OpenSSL TLS 1.3 0‑RTT to Cut Latency on Resumed Connections
Learn how OpenSSL’s TLS 1.3 0‑RTT lets clients send data immediately on a resumed session, what you need to enable it, and the replay‑safety trade‑offs to consider.
25 Jan 2026, 05:39 UTC

When a client repeatedly opens short‑lived TLS connections to the same server, each new handshake adds at least one round‑trip before any application data can be sent. On high‑latency links this extra latency can dominate the total response time, making APIs feel sluggish even when the server itself is fast. OpenSSL’s implementation of TLS 1.3 0‑RTT (zero round‑trip time) lets a client transmit data in the very first flight when it resumes a previous session, effectively removing that handshake delay.
How 0‑RTT fits into OpenSSL’s TLS 1.3 flow
TLS 1.3 derives an exporter master secret from the original handshake. When the server issues a session ticket that advertises early‑data support, the client can reuse that secret to encrypt application data before receiving the server’s finished message. OpenSSL performs the cryptographic derivations internally; the application only needs to enable the feature and supply the data to send.
Because an attacker could capture and replay that early data, OpenSSL does not automatically prevent replays. The API SSL_get_early_data_status() tells the application whether the early data was accepted, rejected, or if a replay was detected. The responsibility for ensuring idempotency or adding replay protection stays with the application.
Enabling early data on the server and client
Server side: when creating the SSL context, call SSL_CTX_set_early_data_enabled(ctx, 1) (or use the command‑line flag -early_data with openssl s_server). The server must also be configured to emit session tickets; OpenSSL does this by default for TLS 1.3.
Client side: similarly enable early data on the client context, or use -early_data with openssl s_client. The client will automatically attempt 0‑RTT if it possesses a valid ticket that advertises early data; otherwise it falls back to a normal handshake.
Worked example: testing 0‑RTT with OpenSSL’s command‑line tools
Assume you have built OpenSSL 1.1.1+ and have a self‑signed certificate server.crt and key server.key in the current directory.
- Start a test server that advertises early data:
- From another terminal, initiate a client connection that sends a GET request using 0‑RTT:
- Inspect the output. You should see a line similar to:
- To verify that the data truly traveled before the handshake finished, add
-traceto either command and look for timestamps showing the application data flight preceding the server’sFinishedmessage.
# Run in a terminal with permission to bind to port 4433
./apps/openssl s_server -accept 4433 -cert server.crt -key server.key \
-tls1_3 -early_data -www
# Replace /path/to/file if you want to send a specific payload
./apps/openssl s_client -connect localhost:4433 -tls1_3 -early_data \
-get / -quiet
Early data was accepted
If the server rejects early data (for example, because the ticket does not advertise it), the line will read Early data was rejected and the client will retransmit the data after the handshake completes.
Note: The example does not claim that the commands were executed in a live environment; it shows the exact invocations you would use to test the feature on your own system.
Trade‑offs and practical limitations
- Replay risk: Any data sent in 0‑RTT must be idempotent (e.g., HTTP GET, HEAD, or PUT with idempotent semantics) or protected by application‑level replay detection. OpenSSL only reports the status; it does not drop or modify the data.
- Server and middleware compatibility: Both ends must run OpenSSL 1.1.1+ (or another TLS 1.3 library) and be configured to emit/accept session tickets with the early‑data extension. TLS‑terminating proxies or load balancers that do not forward the extension will cause the client to fall back to a full handshake.
- Memory footprint: Enabling early data causes the server to retain session‑ticket keys for the lifetime of the ticket, slightly increasing memory usage on busy servers.
- Version sensitivity: OpenSSL 1.0.2 lacks TLS 1.3 altogether, so the
-early_dataflag is unavailable and the connection will negotiate TLS 1.2.
Actionable checklist for adopting 0‑RTT
- Confirm that your OpenSSL version is 1.1.1 or newer (
openssl version). - Enable early data on both server and client contexts (or use the
-early_dataflag in command‑line tools). - Ensure the server issues session tickets; OpenSSL does this by default for TLS 1.3.
- Limit early‑data payloads to idempotent operations or implement your own replay detection using
SSL_get_early_data_status(). - Test with the
s_server/s_clientexample above, checking for the “Early data was accepted” line and using-traceto verify timing. - Monitor server memory usage and proxy behavior in staging before rolling out to production.
When these conditions are met, TLS 1.3 0‑RTT can shave tens of milliseconds off latency‑sensitive, short‑lived connections—particularly valuable on high‑lag networks or for micro‑service chatter where every round‑trip counts.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.