Сжатие на уровне HTTP — одна из самых дешёвых оптимизацаций, которая сразу экономит трафик и ускоряет загрузку на «дальних» сетях. Но в 2026 году вопрос уже не «включить ли gzip», а какой Content-Encoding отдавать и где именно: HTML, статика, API, прокси, кэш, CDN.
Компромисс всегда один: чем сильнее сжатие, тем меньше байт по сети, но тем больше работы на CPU и тем выше риск ухудшить TTFB при сжатии «на лету».
Ещё важнее, чем «проценты сжатия», — предсказуемость для кэшей. Если один и тот же URL может уходить в br/gzip/zstd, кэш обязан различать варианты по Accept-Encoding (то есть нужен корректный Vary: Accept-Encoding).
Зачем вообще спорить про gzip, brotli и zstd в 2026
Условия изменились: браузеры и клиенты чаще умеют несколько алгоритмов, страницы тяжелее, а CPU на фронтовых узлах часто ограничен. Нельзя просто поставить «максимальный уровень» и ждать счастья.
Практически это сводится к двум вопросам:
- Что даёт лучший эффект «байты по сети» на ваших типичных ресурсах (CSS/JS/HTML/JSON)?
- Сколько это стоит по CPU и как это влияет на задержки под пиком?
Если хотите быстрый путь без экспериментов: для статики упор на предсжатие (static), для динамики — умеренный on-the-fly, а экзотику включать только после замеров.
Кратко про форматы: чем отличаются gzip, Brotli и Zstd
gzip: максимальная совместимость и предсказуемость
gzip понимают почти все клиенты, прокси и CDN. Он не самый эффективный по степени сжатия, но «ровный»: умеренная нагрузка на CPU и минимальные сюрпризы в продакшне. Для динамики (HTML/JSON) это безопасный базовый слой.
Brotli: лучший выигрыш на текстовой статике, особенно при precompress
Brotli обычно сжимает лучше gzip на CSS/JS/HTML/SVG/JSON. Но высокие уровни на лету могут дорого стоить по CPU и ухудшать TTFB. Поэтому здоровая практика — brotli_static (предсжатые .br рядом с исходниками) и умеренный уровень для on-the-fly.
Zstd: быстрый современный компромисс, но не универсальный
Zstd интересен балансом: часто быстрее Brotli при хорошей степени и заметно эффективнее gzip по размеру. В 2026 он наиболее полезен для:
- API/JSON на высоких RPS, где CPU критичен;
- внутреннего трафика сервис-сервис, где вы контролируете клиентов;
- edge-узлов, где важно снизить трафик, но не добавить задержки.
Главный нюанс — совместимость клиентов и инфраструктуры. Поэтому zstd обычно включают как опцию для контролируемой аудитории, оставляя gzip/brotli как fallback.

Как Nginx выбирает Content-Encoding и почему кэши иногда ломаются
Nginx ориентируется на заголовок запроса Accept-Encoding. Дальше он выбирает вариант, который разрешён вашей конфигурацией и подходит по условиям (тип ответа, минимальный размер, проксирование).
Если вы включаете несколько алгоритмов, убедитесь, что на сжимаемых ответах есть Vary: Accept-Encoding. Иначе proxy_cache, CDN или промежуточные кэши могут сохранить «не тот» вариант и отдать его клиенту, который этот encoding не понимает.
Отдельный класс проблем — когда upstream уже присылает Content-Encoding. В таком случае Nginx не должен пытаться «досжать» ответ: вы получите двойное сжатие или неконсистентные заголовки.
Если вам нужно быстро сверить базовую теорию с практикой, полезно также посмотреть близкую по теме заметку про сравнение подходов в Nginx и Apache: сжатие br/gzip и выбор стратегии в связке Nginx/Apache.
TTFB и CPU: когда компрессия делает хуже
TTFB включает не только сеть, но и время, которое сервер тратит, чтобы начать отдавать ответ. При on-the-fly компрессии тяжёлым алгоритмом на высоком уровне первые байты могут появляться позже, особенно под нагрузкой.
Типичные признаки «пережали на лету»:
- под пиком растёт latency и загрузка CPU на воркерах;
- апстрим быстрый, но Nginx становится узким местом;
- страницы стали меньше, но субъективно «открываются хуже» из‑за задержки старта.
Практическое правило: для динамики выбирайте компрессию, которая не убивает CPU, а максимальные уровни оставляйте для предсжатой статики.
Рекомендованная стратегия на 2026: Brotli static + gzip fallback + (опционально) zstd
Универсальная схема, которая чаще всего даёт лучший результат без ночных откатов:
- Статика (CSS/JS/SVG/JSON, иногда HTML лендингов): предсжатие Brotli и включение
brotli_static. - Совместимость «для всех»: gzip на умеренном уровне.
- API с контролируемыми клиентами: рассмотреть zstd (точечно), если клиенты точно умеют.
Не сжимайте «по природе уже сжатое»: JPEG/PNG/WebP/AVIF, архивы, видео/аудио. Выигрыш обычно мизерный, а CPU расходуется заметно.
Проверка на практике: совместимость и цена по железу
1) Проверяем, что сервер реально отдаёт нужный encoding
Минимум — посмотреть заголовки. Меняйте Accept-Encoding и тестируйте разные URL (HTML, CSS, JS, JSON).
curl -sI -H 'Accept-Encoding: br' https://example.com/app.js | grep -i -E 'content-encoding|vary|content-type'
curl -sI -H 'Accept-Encoding: gzip' https://example.com/app.js | grep -i -E 'content-encoding|vary|content-type'
curl -sI -H 'Accept-Encoding: zstd' https://example.com/api/data | grep -i -E 'content-encoding|vary|content-type'
curl -sI -H 'Accept-Encoding: br,gzip' https://example.com/ | grep -i -E 'content-encoding|vary|content-type'
Если отдаётся не то, что ожидали, проверьте:
- подключён ли модуль (Brotli/Zstd);
- попадает ли MIME-тип в
gzip_typesилиbrotli_types; - не возвращает ли upstream уже выставленный
Content-Encoding.
2) Сравниваем влияние на TTFB и CPU
Для on-the-fly сравнения гоняйте нагрузку на типичном ответе (например, 20–100 КБ JSON/HTML), параллельно снимая latency/CPU. Подойдут wrk/hey/k6 или ваши штатные средства. Важно сравнивать одинаковые ответы, одинаковый RPS, одинаковый размер.
Практичные конфиги Nginx: gzip, Brotli и static
Ниже — заготовки, которые обычно ведут себя предсказуемо. Перед продакшеном проверьте модули, MIME-типы и наличие предсжатых файлов в каталоге статики.
Базовый gzip для совместимости
gzip on;
gzip_comp_level 5;
gzip_min_length 1024;
gzip_vary on;
gzip_proxied any;
gzip_types
text/plain
text/css
application/javascript
application/json
application/xml
image/svg+xml
font/ttf
font/otf
application/vnd.ms-fontobject;
Уровень 5 обычно даёт хороший баланс. gzip_vary помогает кэшам различать варианты.
Brotli: умеренный on-the-fly + приоритет на static
brotli on;
brotli_comp_level 5;
brotli_min_length 1024;
brotli_static on;
brotli_types
text/plain
text/css
application/javascript
application/json
application/xml
image/svg+xml;
Если вы генерируете .br на этапе CI/CD, это обычно лучший вариант: стабильный TTFB и минимальная нагрузка на CPU на фронтовых узлах.
Gzip static: если вы предсжимаете .gz
gzip on;
gzip_static on;
gzip_static полезен, когда рядом с app.js лежит app.js.gz: Nginx отдаст готовый файл, если клиент согласен на gzip.

Zstd в Nginx: где уместен и как не сломать клиентов
Для публичного сайта на массовых браузерах zstd обычно включают осторожно: совместимость по всей цепочке (клиент, прокси, CDN) может отличаться. Зато для API и внутренних клиентов он может дать отличный баланс «скорость/CPU/размер».
Рабочий подход:
- Оставить gzip как гарантированный fallback.
- Включать zstd точечно: отдельный
location /api/или отдельный домен API. - Сначала собрать статистику по
$http_accept_encodingв логах, и только потом расширять охват.
Если вы планируете миграции домена/API или параллельно наводите порядок с HSTS и сертификатами, держите под рукой чеклист по безопасным редиректам и SSL: миграция домена, 301 и HSTS без сюрпризов.
Частые ошибки: почему «включил — стало хуже»
1) Сжимаем уже сжатое
Сжатие для image/webp, image/avif, application/zip и подобных типов чаще всего — трата CPU. Делайте списки типов явными и держите их короткими.
2) Слишком высокий уровень on-the-fly
Высокие уровни Brotli на динамике — частая причина роста CPU и ухудшения TTFB. Для on-the-fly держите уровень умеренным, а «максимум» переносите в предсжатие.
3) Upstream уже сжимает
Если приложение/апстрим уже выставляет Content-Encoding, не пытайтесь «поверх» включать сжатие на Nginx для тех же ответов. Результат — двойное сжатие, битые заголовки и сложный дебаг.
4) Кэш без Vary и путаница вариантов
Когда один URL может быть отдан в br/gzip/zstd, кэш обязан различать варианты по Accept-Encoding. Проверьте наличие Vary: Accept-Encoding именно на тех ответах, которые реально сжимаются.
Мини-чеклист внедрения (чтобы не откатывать ночью)
- Определите типы, которые реально нужно сжимать (HTML/CSS/JS/JSON/SVG).
- Включите gzip с умеренным
gzip_comp_level. - Добавьте Brotli и
brotli_static, если у вас есть сборка ассетов. - Проверьте заголовки:
Content-Encoding,Vary,Content-Type. - Снимите метрики до/после:
TTFB, CPU, latency под нагрузкой. - Только после этого экспериментируйте с zstd и точечными включениями.
Практическое правило: лучшее сжатие почти всегда достигается предсжатием статики (Brotli), а лучший
TTFBпод нагрузкой — умеренными уровнями on-the-fly (gzip или zstd в контролируемых сценариях).
Итог
В 2026 году «победитель» не один: gzip остаётся базой ради совместимости, Brotli даёт максимум выгоды на статике (особенно с brotli_static), а zstd — хороший инструмент для API и внутренних клиентов, когда важны CPU и задержки. Самый безопасный путь: gzip как фундамент, Brotli static для ассетов, zstd — только после измерений и при понятной аудитории клиентов.


