OpenSSL 0‑RTT TLS 1.3: Cut Latency, Manage Replay Risk
Learn how to enable OpenSSL 0‑RTT for faster TLS handshakes, see a concrete HTTP GET example, and balance latency against replay‑attack exposure.
26 Aug 2025, 18:22 UTC

The latency problem and why 0‑RTT matters
When a client reconnects to a server it must finish a full TLS handshake before any application data can flow. Each handshake round‑trip adds at least one network RTT, which can push connection establishment from tens of milliseconds to several hundred, hurting user experience for repeat visits.
What is 0‑RTT?
0‑RTT (zero‑round‑trip) is a TLS 1.3 extension defined in RFC 8446 that allows the client to send application data in the first handshake round‑trip. The server can resume the session using a previously exchanged ticket, so the client’s first packet already contains the HTTP request. This reduces the perceived connection time to sub‑100 ms in many benchmarks.
Enabling 0‑RTT in OpenSSL
OpenSSL 1.1.1 and newer support 0‑RTT. The feature is disabled by default; it is only activated when the client explicitly requests early data. To make sure 0‑RTT is off for state‑changing operations, do not set the `SSL_OP_ENABLE_EARLY_DATA` flag on the SSL_CTX. The default configuration already prevents early data for non‑idempotent requests.
If you want to guarantee that early data is never sent, you can explicitly clear any option that might enable it:
SSL_CTX_set_options(ctx, 0); /* start with a clean slate */
/* ensure no early‑data flag is set */
SSL_CTX_clear_options(ctx, SSL_OP_ENABLE_EARLY_DATA);
To enable 0‑RTT for a specific connection, the client must request early data (e.g., with the -early_data flag in the openssl s_client command). The server must be configured to accept early data and to track nonces or timestamps to mitigate replay attacks.
Worked example: HTTP GET over 0‑RTT
The following command shows a client that sends an HTTP GET in early data, then completes the handshake:
# Run on a machine with OpenSSL 1.1.1+ (check with `openssl version`)
# Replace example.com with the target host
openssl s_client -connect example.com:443 -early_data \
-msg -status \
-servername example.com
The -early_data switch tells the client to include the HTTP GET request in the first packet. After the server validates the nonce inside the ticket, the handshake proceeds and the client receives the response. In controlled benchmarks this entire exchange can finish in under 100 ms, compared to ~200 ms for a full handshake.
To verify that the server accepted early data, inspect the server log or use openssl s_client -status and look for the line early data: yes. If the server rejects early data, the connection will fall back to a full handshake and you will see early data: no.
Trade‑off: replay risk
Because the client sends data before the server has authenticated the session, an attacker who records the early packet can replay it later. If the request is not idempotent (e.g., POST, PUT, DELETE) the server may execute the same operation twice, causing unintended side effects. The recommended mitigation is to restrict 0‑RTT to safe, idempotent methods such as HTTP GET. For state‑changing requests, the client should either disable early data or implement application‑level replay protection (e.g., a nonce or timestamp that the server checks).
Servers must maintain a replay‑window – a short-lived cache of nonces or timestamps – to detect duplicate early data. OpenSSL does not automatically provide this cache; the application must supply a callback via SSL_CTX_set_rec_client_cb or use a higher‑level library that implements it.
Actionable closing
- Check your OpenSSL version. Run
openssl version. If the output shows OpenSSL 1.1.1 or newer, the API for 0‑RTT is available. - Decide the scope. Use 0‑RTT only for read‑only, repeat‑connection traffic (e.g., GET requests).
- Configure the context safely. Ensure
SSL_OP_ENABLE_EARLY_DATAis not set, or explicitly clear it. - Test the flow. Use
openssl s_client -connect host:443 -early_dataand verify that the server logs “early data: yes”. Confirm that the connection time is lower than a full handshake. - Monitor replay protection. If you enable early data for any request, implement a nonce or timestamp check on the server side and keep the replay window short (typically a few seconds).
By following these steps you can reap the latency benefits of OpenSSL 0‑RTT while keeping the security exposure under control.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.