Short answer
On hardware with AES acceleration (AES-NI on almost all modern servers and laptops) AES-GCM is fastest. On devices without that acceleration — many older phones, cheap IoT devices, some ARM chips — ChaCha20-Poly1305 is significantly faster, because it is designed to run efficiently in software. So the right answer is to offer both and let the client choose.
What the two have in common
Both are AEAD — Authenticated Encryption with Associated Data. That means they encrypt and authenticate in one operation, so there is no separate MAC step (as with the old CBC suites). AEAD eliminates a whole class of attacks such as padding oracle flaws. Both are used in TLS 1.2 and TLS 1.3, and both are considered secure at full 256-bit (ChaCha20) or 128/256-bit (AES) strength.
The deciding factor: AES-NI
AES-GCM is fast because the CPU has dedicated AES instructions (AES-NI on x86, equivalents on modern ARM). With them, AES-GCM encrypts several gigabytes per second. Without them AES must run in pure software, where it is slow and — worse — vulnerable to timing-based side-channel attacks. ChaCha20 was designed to be fast and constant-time in software without special instructions.
| Scenario | Fastest |
|---|---|
| Server/laptop with AES-NI | AES-GCM |
| Older phone without AES acceleration | ChaCha20-Poly1305 |
| Low-power IoT / cheap ARM | ChaCha20-Poly1305 |
| Modern high-end mobile (with acceleration) | Roughly equal |
Measure it on your own CPU
OpenSSL can benchmark the raw throughput on your machine:
openssl speed -evp aes-256-gcm openssl speed -evp chacha20-poly1305
On a modern x86 server with AES-NI, aes-256-gcm will typically show higher numbers. Disable AES-NI (or run on a chip without it) and the ratio reverses. That is the whole point: there is no single universal answer.
Why you should let the client choose
Because the fastest cipher depends on the client's hardware, the right server configuration is to offer both and not force a server preference. Then a modern server-to-server connection picks AES-GCM, while an old phone picks ChaCha20 — each gets its fastest option. This is exactly why Mozilla's intermediate profile sets ssl_prefer_server_ciphers off.
# nginx — offer both, let the client choose ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:\ ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-CHACHA20-POLY1305; ssl_prefer_server_ciphers off;
How they are built — briefly and without hype
AES-GCM combines AES in counter mode (the encryption itself) with GMAC (the authentication). ChaCha20-Poly1305 combines the ChaCha20 stream cipher with the Poly1305 MAC. Both are constructions where encryption and integrity happen together — that is what "AEAD" means. One important pitfall applies to both: they must never reuse the same nonce with the same key. If they do, security collapses. In TLS this is handled correctly by the protocol itself, so it is not something to worry about in an ordinary server configuration — but it explains why you should not roll your own AEAD usage outside a well-tested library.
What it means in practice for you
For a typical web server on modern CPUs, the throughput difference is rarely the bottleneck — network and application logic dominate. Where it genuinely matters is in two places: high-volume API traffic from servers without AES acceleration, and mobile clients on battery, where ChaCha20's lower CPU cost translates into longer battery life. The conclusion stays the same regardless: offer both, do not force a preference, and let each client win on its own hardware.
What about TLS 1.3?
In TLS 1.3 the two suites are called TLS_AES_128_GCM_SHA256/TLS_AES_256_GCM_SHA384 and TLS_CHACHA20_POLY1305_SHA256. Both are among the five standardised suites, and negotiation works the same way — the client signals what it prefers. Read how the names are built in what is a cipher suite.
It is about having both — everywhere
The typical mistake is not picking the wrong cipher but a server offering only one — often because a hardening template removed ChaCha20 and so penalises every client without AES-NI. CertControl records which AEAD ciphers each endpoint actually offers, so you can see where both are present and where a server has accidentally ended up with only one. See the dangerous counterparts in why RC4 and 3DES are dangerous.
Frequently asked questions
Is ChaCha20-Poly1305 less secure than AES-GCM?
No. Both are modern AEAD ciphers with no known practical weaknesses. ChaCha20-Poly1305 is used by major providers at large scale. The difference is purely performance depending on hardware, not security.
Why is ChaCha20 faster on phones?
Many mobile and low-power CPUs lack hardware acceleration for AES. ChaCha20 is designed to be fast in pure software, so on those devices it beats AES-GCM substantially — which is why mobile browsers often prefer ChaCha20.
What is AES-NI?
AES-NI is a set of CPU instructions that perform AES encryption in hardware. With them, AES-GCM is extremely fast and constant-time. Almost all modern x86 servers and laptops have AES-NI.
Which should I choose on my server?
Both. Offer AES-GCM and ChaCha20-Poly1305 and do not set a server preference, so each client automatically gets whichever is fastest on its hardware.
Does the order in ssl_ciphers matter?
Only if server preference is enabled. With prefer_server_ciphers off your order is ignored and the client's preference decides — which is the right behaviour when you offer both AES-GCM and ChaCha20.