yum
upgrades for production use, this is the repository for you.
Active subscription is required.
What http2_chunk_size
controls
- It sets the target size of HTTP/2 DATA frames written per send iteration for a response.
- Typical effective range is 2k–16k. Values above the peer’s maximum frame size are split into multiple frames; effective frame payload won’t exceed the peer’s max (usually 16k), so “32k/64k” behave like 16k against standard clients.
- Smaller chunks improve early-byte latency and multiplexing fairness. Larger chunks reduce framing/syscall overhead and can improve bulk throughput.
We’ve run a testing of various settings that vary payload size and http2_chunk_size
so you don’t have to.
Quick tuning picks for various payload sizes (based on our measured results)
- Small/interactive (HTML, small images, ≤64 KB):
http2_chunk_size
4k–8k - Medium assets (CSS/JS ~100–300 KB, binaries up to ~10 MB):
http2_chunk_size
8k–16k - Large/static downloads (>10 MB):
http2_chunk_size
16k
Combined policy (latency + throughput)
- Global default:
http2_chunk_size 8k;
(balanced TTFB and good throughput across sizes) - Per-location overrides:
- Small/interactive (
/
,/css/
,/js/
):http2_chunk_size 4k;
- Medium assets (e.g.,
/media/
, 0.5–10 MB):http2_chunk_size 16k;
- Large/static downloads (e.g.,
/downloads/
, >10 MB):http2_chunk_size 16k;
(note: if your clients accept >16k frames, 32k–64k may help; most browsers cap to 16k frames)
- Small/interactive (
Rule-of-thumb formula for http2_chunk_size
If you’d like a simple sizing rule from payload size S (bytes) to one of {4k, 8k, 16k}:
- Let S_kb = S / 1024.
- If S_kb ≤ 64 → 4k
- Else if S_kb ≤ 2048 → 8k–16k (start with 8k; use 16k if asset is consistently ≥1 MB)
- Else → 16k
Why: aim to keep the number of chunks per response roughly within 4–64 for typical assets, minimizing overhead without starving other streams.
Per-location examples
The http2_chunk_size
is supported in location
context, which means you may tune it up as needed.
So armed with knowledge on which locations store which payload sizes on average, the ultimate tuning is setting up the right chunk size in the right location:
server {
listen 443 ssl;
http2 on;
# Baseline
http2_chunk_size 8k;
# Small/interactive
location ~ \.php$ {
http2_chunk_size 4k;
fastcgi_pass …;
}
location /css/ { http2_chunk_size 4k; }
location /js/ { http2_chunk_size 8k; }
# Large/static
location /downloads/ { http2_chunk_size 16k; }
}
If NGINX terminates TLS in front of Varnish
When NGINX terminates TLS, you usually have a single root location
in your TLS side of things:
location / {
listen 443 ssl;
http2 on;
proxy_set_header … ;
proxy_pass …;
}
You can’t allocate a location \.php$
to set up an optimized chunk size there. However, armed this time with a knowledge that your typical framework does SEO-friendly URLs, you can set up an extra location
that targets URIs without extensions. For example /some/article
would end up there.
In other words, add a dedicated “extensionless” location for SEO‑friendly URLs (usually dynamic pages going to PHP via Varnish). These responses are typically small; prefer a low chunk size for latency:
upstream varnish { server 127.0.0.1:6081; }
server {
listen 443 ssl;
http2 on;
# Shared proxy headers (inherited by locations)
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# Baseline
location / {
http2_chunk_size 8k;
proxy_pass http://varnish;
}
# Extensionless URLs (no dot anywhere in path) → dynamic pages (favor latency)
location ~ ^/[^.]+$ {
http2_chunk_size 4k;
proxy_pass http://varnish;
}
# Static assets → larger chunk for throughput
location ~* \.(?:css|js|png|jpe?g|gif|svg|ico|woff2?)$ {
http2_chunk_size 16k;
proxy_pass http://varnish;
}
}
Notes and caveats
- http2_chunk_size values above the peer’s frame size are silently clamped; for most clients the effective maximum is 16k.
- The best value can change with network conditions (Wi‑Fi/4G/long-RTT). Validate on your own network and client mix.