TLS 1.3 introduced an optional feature called 0-RTT (zero round trip time) that lets a client send application data in the very first message, before the handshake completes. The data arrives at the server with zero round trips of latency.
Think of it like a regular at a coffee shop. They walk in and the barista already knows their order. “The usual?” The coffee starts brewing before the customer even reaches the counter. That’s 0-RTT. The server starts processing the request before the handshake is finished, because it recognizes the client from a previous visit.
If the client has a PSK from a previous session, it can encrypt application data using keys derived from that PSK and include it in the ClientHello. The server decrypts it immediately.
sequenceDiagram
participant C as Client
participant S as Server
C->>S: ClientHello + PSK + key_share + early_data (encrypted HTTP request!)
S->>S: Decrypt early data using PSK
S->>S: Process the HTTP request
S->>C: ServerHello + key_share + Finished
S->>C: HTTP Response (encrypted with full session keys)
C->>S: Finished
The client’s HTTP request arrives with the very first packet. No waiting for the handshake to complete. For repeat visitors to a website, this means the page starts loading immediately.
0-RTT has a fundamental security weakness: replay attacks.
Imagine someone records the regular customer walking into the coffee shop and saying “the usual.” They play that recording back the next day. The barista hears “the usual” and makes another coffee. The customer gets charged twice.
An attacker who captures the ClientHello with early data can replay it. They send the exact same ClientHello to the server again. The server decrypts the early data and processes it again.
For idempotent requests (like GET /index.html), this is harmless. The server returns the same page twice. But for non-idempotent requests (like POST /transfer?amount=1000), a replay could cause the action to execute twice.
TLS itself cannot prevent this replay. The early data is encrypted with the PSK, and the replayed message is identical to the original. The server can’t distinguish them at the TLS layer.
Many deployments disable 0-RTT entirely because the replay risk is hard to mitigate correctly. The performance benefit is real but small (one round trip), and the security risk is significant for applications that aren’t carefully designed for it.
Next: TLS 1.3 Extensions