TLS 1.2 needed two round trips before you could send application data. TLS 1.3 gets it down to one, and the trick is that the client guesses.

The client guesses a key

In the ClientHello, the client doesn’t just say “here are the ciphers I support”. It also throws in a key share — an ephemeral (EC)DH public key for the group it bets the server will pick:

ClientHello
  + supported_versions: TLS 1.3
  + key_share: x25519 <client pubkey>
  + signature_algorithms, ...

If the bet is right (it usually is — almost everyone does x25519), the server replies with its own key share in the ServerHello, and both sides can derive the session keys immediately. Everything after the ServerHello — including the server’s certificate — is already encrypted.

ServerHello
  + key_share: x25519 <server pubkey>
{EncryptedExtensions}
{Certificate}
{CertificateVerify}
{Finished}

Why this matters beyond speed

Because the certificate is encrypted, a passive observer can’t see which cert the server presented. The one thing still in the clear is the SNI in the ClientHello — which is exactly what ECH (Encrypted Client Hello) is trying to close.

0-RTT, briefly

On resumption the client can send data in its very first flight using a pre-shared key. It’s fast and it’s dangerous: that early data is replayable, so it must be idempotent. I keep 0-RTT off for anything that mutates state.