Когда мы включали HTTP/3 на реальном WordPress-сервере, самое полезное открытие оказалось довольно простым: добавить несколько строк в Nginx значительно легче, чем правильно доказать, что браузер действительно начал использовать HTTP/3.
В нашем рабочем случае HTTP/3 включался на Buildum.ru. Сервер уже нормально работал по HTTPS и HTTP/2, поэтому задача не состояла в полной переделке сетевого стека. Нужно было добавить QUIC, сохранить существующий fallback и после reload проверить соединение снаружи.
Именно такой сценарий встречается чаще всего:
работающий HTTPS
→HTTP/2
→добавляем HTTP/3
→ничего не ломаем для старых клиентов.
Nginx поддерживает QUIC и HTTP/3 начиная с версии 1.25.0. В актуальной документации ngx_http_v3_module по-прежнему обозначен как экспериментальный модуль, а HTTP/3 support входит в официальные Linux binary packages.
В реальном внедрении у нас уже стоял Nginx 1.31.6, поэтому обновлять весь стек только ради базовой поддержки HTTP/3 не потребовалось.
Что HTTP/3 меняет по сравнению с HTTP/2
HTTP/3 сохраняет привычную HTTP-семантику: браузер всё так же делает GET, сервер отвечает статусом 200, передаются headers и body.
Меняется нижний транспортный слой.
Упрощённо:
HTTP/1.1 → TCP → TLS
HTTP/2 → TCP → TLS
HTTP/3 → QUIC → UDP
QUIC при этом уже включает криптографический handshake на базе TLS 1.3. RFC 9114 определяет HTTP/3 именно как перенос HTTP semantics поверх QUIC.
Главное практическое отличие видно при потерях пакетов.
HTTP/2 умеет мультиплексировать несколько запросов в одном TCP-соединении, но TCP восстанавливает потерянные данные на уровне всего byte stream. Потеря пакета может временно задержать несколько активных HTTP/2 streams.
QUIC управляет потоками непосредственно на транспортном уровне, поэтому потеря данных одного stream не должна блокировать независимые streams тем же способом. Именно это RFC называет одной из причин, почему QUIC потенциально способен улучшать производительность HTTP.
Это особенно интересно на:
- мобильных сетях;
- нестабильном Wi-Fi;
- соединениях с packet loss;
- сетях, где устройство меняет маршрут или IP.
Но отсюда не следует:
HTTP/3 автоматически ускорит любую страницу.
Если основная проблема сайта — PHP формирует HTML 1,5 секунды, база делает тяжёлые запросы или LCP-картинка весит 4 МБ, новый транспорт не исправит эту архитектуру.
Почему HTTP/3 нельзя включать вместо HTTP/2

Потому что реальный интернет должен работать и тогда, когда QUIC недоступен.
HTTP/3 использует UDP. Сеть пользователя, корпоративный firewall, роутер, VPN или промежуточная инфраструктура могут блокировать UDP или конкретно QUIC.
RFC 9114 прямо предусматривает такую ситуацию: если QUIC-соединение установить не удалось, клиент должен иметь возможность использовать TCP-based HTTP.
Поэтому правильная архитектура:
TCP 443 → HTTP/1.1 / HTTP/2
UDP 443 → HTTP/3 / QUIC
а не:
удалили HTTP/2 → оставили только HTTP/3
У пользователя не должно быть необходимости знать, каким транспортом открылась страница.
Что нужно проверить в Nginx до изменения конфигурации
Первый шаг:
nginx -v
Затем:
nginx -V
Для сборок из исходников важно наличие:
--with-http_v3_module
Nginx указывает, что ngx_http_v3_module не включается автоматически при самостоятельной сборке: поддержку нужно разрешить соответствующим configure option. При этом официальные Linux packages уже поставляются с QUIC/HTTP/3 support.
Дополнительно полезно проверить SSL runtime.
В актуальной документации Nginx для QUIC рекомендуется OpenSSL 3.5.1+; со старыми библиотеками используется compatibility layer, который имеет ограничения, например в части TLS early data.
Для обычного включения HTTP/3 специально активировать early data не требуется.
Конфигурация, которую мы использовали на реальном сервере
До изменений сайт уже имел:
listen 443 ssl;
http2 on;
Для HTTP/3 добавился отдельный QUIC listener:
listen 443 quic;
http3 on;
А сайт начал объявлять возможность HTTP/3:
add_header Alt-Svc 'h3=":443"; ma=86400' always;
Итоговая логика server block выглядит примерно так:
server {
listen 443 ssl;
listen 443 quic;
http2 on;
http3 on;
server_name example.ru www.example.ru;
ssl_certificate /etc/letsencrypt/live/example.ru/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.ru/privkey.pem;
add_header Alt-Svc 'h3=":443"; ma=86400' always;
root /var/www/example.ru;
location / {
try_files $uri $uri/ /index.php?$args;
}
}
Официальный пример Nginx строится по той же схеме: обычный SSL listener и отдельный listen ... quic, плюс Alt-Svc, сообщающий браузеру адрес HTTP/3 endpoint.
А где reuseport
Nginx рекомендует:
listen 443 quic reuseport;
для лучшей работы с несколькими workers.
Но на сервере с несколькими virtual hosts на одном IP:443 нельзя механически написать socket-level option reuseport в каждом конфликтующем listen.
Поэтому сначала нужно смотреть всю конфигурацию:
grep -R "listen 443.*quic" /etc/nginx/
Если сервер обслуживает много доменов, socket options нужно согласовать между всеми vhosts.
Это важнее копирования готового блока из статьи.
Зачем нужен Alt-Svc

Клиент изначально может прийти по HTTP/2.
Сервер отвечает:
Alt-Svc: h3=":443"; ma=86400
Смысл:
тот же origin доступен по HTTP/3 на UDP 443, а объявление можно кэшировать на 86400 секунд.
RFC 9114 прямо определяет Alt-Svc как один из механизмов discovery HTTP/3 endpoint.
После получения заголовка браузер может открыть QUIC-соединение.
Но слово может здесь принципиально.
Наличие:
Alt-Svc: h3=":443"
не доказывает, что UDP доступен.
Не доказывает, что Nginx реально принял QUIC.
Не доказывает, что клиент договорился о h3.
Это лишь объявление.
Самая частая ошибка — открыть TCP 443 и забыть UDP
С обычным HTTPS мы привыкли думать:
443 = HTTPS.
Для HTTP/3 нужно точнее:
TCP 443 = HTTP/1.1 / HTTP/2
UDP 443 = QUIC / HTTP/3
Если используется UFW:
sudo ufw allow 443/udp
И проверить:
sudo ufw status
Но локальный firewall — только один уровень.
UDP могут блокировать:
- firewall VPS-провайдера;
- security group;
- cloud firewall;
- внешний reverse proxy;
- NAT;
- CDN;
- сеть пользователя.
Поэтому проверка:
ss -lunp | grep ':443'
показывает, что сервер слушает UDP 443, но ещё не доказывает, что порт доступен из интернета.
Именно поэтому после локальной настройки нужна внешняя проверка.
Как применять изменения безопасно
До reload:
sudo nginx -t
Нормальный результат:
syntax is ok
test is successful
Только после этого:
sudo systemctl reload nginx
Не restart без необходимости.
После reload первым делом проверяем обычный сайт:
curl -I https://example.ru/
Нормальный ответ может начинаться:
HTTP/2 200
и содержать:
Alt-Svc: h3=":443"; ma=86400
И это совершенно нормально.
Ваш curl в этом запросе мог использовать HTTP/2, пока сервер одновременно уже предлагал HTTP/3 другим capable-клиентам.
Именно здесь мы чуть не сделали неправильный вывод при реальной настройке
На сервере, где мы внедряли HTTP/3, системный curl был версии 8.5.0, но конкретная сборка не имела HTTP/3 support.
Это важный урок.
Наличие относительно новой версии:
curl 8.x
не означает:
умеет QUIC
curl должен быть собран с HTTP/3-capable backend. Официальная документация curl перечисляет разные QUIC backends и отдельно говорит, что --http3 работает только тогда, когда underlying libcurl действительно собран с поддержкой HTTP/3.
Если поддержка есть:
curl --http3 https://example.ru/
или для строгого теста без fallback:
curl --http3-only https://example.ru/
--http3 может вернуться к HTTP/2/HTTP/1.1, если QUIC не устанавливается достаточно быстро.
--http3-only должен завершиться ошибкой, если HTTP/3-соединение не получилось.
Для диагностики второй вариант информативнее.
Почему обычный curl и Alt-Svc недостаточны
У нас после настройки уже было видно:
HTTP/2
и:
Alt-Svc: h3=":443"; ma=86400
То есть Nginx:
- продолжал нормально обслуживать HTTP/2;
- объявлял HTTP/3.
Но это всё ещё не было прямым доказательством успешного QUIC handshake.
Следующий этап — внешний клиент, который умеет HTTP/3.
Проверка через Chrome DevTools
Откройте сайт.
Затем:
DevTools → Network
Правой кнопкой по заголовкам таблицы включите:
Protocol.
Chrome DevTools официально показывает в этой колонке negotiated protocol, например:
h2
для HTTP/2 и:
h3
для HTTP/3.
После очистки Network и перезагрузки страницы смотрим основные requests.
Если отображается:
h3
браузер действительно использует HTTP/3.
Если:
h2
это ещё не обязательно ошибка.
Проверьте:
- был ли получен
Alt-Svc; - открыт ли UDP 443;
- не блокирует ли QUIC сеть;
- не используется ли proxy;
- закэшировал ли браузер состояние origin;
- действительно ли текущий hostname обслуживается нужным server block.
Проверка через внешний HTTP/3 checker

Ещё один удобный вариант — внешний HTTP/3 Check.
Например, http3check.net сначала получает обычные response headers, анализирует Alt-Svc, а затем пытается выполнить настоящий HTTP/3 request к endpoint. При успехе сервис сообщает отдельно:
QUIC is supported
и:
HTTP/3 is supported.
Такой тест важен именно потому, что выполняется снаружи вашей сети.
Он одновременно проверяет:
- DNS;
- доступность UDP;
- QUIC negotiation;
- HTTP/3 endpoint.
В нашем реальном внедрении внешняя проверка была особенно полезной именно из-за отсутствия HTTP/3 support в системном curl сервера.
Как проверить сам протокол на стороне Nginx
У ngx_http_v3_module есть встроенная переменная:
$http3
Для настоящего HTTP/3 она содержит:
h3
Для обычного HTTP/2/HTTP/1.x будет пустой.
При временной диагностике можно добавить отдельный header:
add_header X-HTTP3 $http3 always;
или собственный формат access log.
Но постоянный технический заголовок на production мне обычно не нужен: DevTools и логов достаточно.
После проверки его можно убрать.
http3 on действительно обязательно?
В актуальной документации:
http3 on;
имеет default:
on
при наличии ngx_http_v3_module.
То есть технически при корректном QUIC listener явная строка может быть избыточной.
Я всё равно предпочитаю писать её явно в рабочем server block:
http2 on;
http3 on;
Потому что тогда через полгода по одному конфигу сразу видно, какие протоколы мы намеренно обслуживаем.
Это уже вопрос читаемости конфигурации, а не обязательное требование Nginx.
Нужен ли quic_retry
Nginx предоставляет:
quic_retry on;
для QUIC Address Validation. По умолчанию он выключен.
Для базового включения HTTP/3 он не обязателен.
То же относится к:
quic_gso on;
ssl_early_data on;
Это уже дальнейшая настройка транспорта.
Я бы не включал дополнительные QUIC-функции просто ради максимального количества директив.
Правильный порядок:
работающий HTTP/3
→стабильность
→измерения
→только затем дополнительный tuning.
А нужен ли HTTP/3 WordPress
HTTP/3 вообще не знает, работает сайт на WordPress, Laravel или статическом HTML.
Протокол заканчивается на уровне веб-сервера.
Запрос:
browser
→ QUIC
→ Nginx
→ FastCGI
→ PHP-FPM
→ WordPress
WordPress получает обычный HTTP request уже после того, как Nginx разобрал транспорт.
Поэтому:
- плагин HTTP/3 для WordPress не нужен;
- менять PHP-код не требуется;
- тему переделывать не нужно;
.htaccessдля Nginx к этому отношения не имеет.
Настройка находится в сетевом и серверном слоях.
Что HTTP/3 реально способен улучшить
На хорошей проводной сети с низкой задержкой пользователь иногда почти не увидит разницу.
Преимущество QUIC становится интереснее при:
- packet loss;
- мобильных соединениях;
- нестабильном Wi-Fi;
- большом количестве параллельных requests;
- повторных соединениях;
- смене network path.
RFC прямо выделяет low-latency connection establishment, stream multiplexing и независимое управление stream recovery как основные свойства QUIC, полезные для HTTP.
Но ни одна из этих особенностей не отменяет обычную оптимизацию сайта.
Если TTFB плохой из-за backend, сначала нужно работать с backend.
Если изображение LCP слишком тяжёлое — с изображением.
Если main thread забит JavaScript — с JavaScript.
Если вы вообще не уверены, сервер ли создаёт задержку, на Vagizov.com уже есть отдельный разбор «Как понять, что сайт тормозит именно хостинг».
HTTP/3 и SEO
HTTP/3 не нужно внедрять ради галочки в SEO-аудите.
Google ещё в официальном Search Office Hours прямо отвечал, что HTTP/3 не используется как ranking factor. В текущей документации Page Experience Google также акцентирует Core Web Vitals, безопасность HTTPS и общий пользовательский опыт, а не конкретную версию HTTP.
Поэтому формула:
включили h3 → выросли позиции
не имеет оснований.
Корректнее:
HTTP/3
→потенциально более устойчивый/быстрый transport в части сетевых сценариев
→возможное улучшение реального UX
→измеряем фактический результат.
И если CrUX/LCP/INP не изменились, не нужно придумывать SEO-эффект.
В полном техническом аудите сайта HTTP-протокол разумно рассматривать как часть серверной и performance-диагностики, но не как самостоятельный фактор поискового ранжирования.
Когда HTTP/3 может вообще не доходить до вашего Nginx
Очень важный случай — CDN или reverse proxy.
Если перед сайтом стоит сервис, который сам принимает пользовательское соединение:
User
→ HTTP/3
→ CDN
→ HTTP/2
→ Origin Nginx
пользователь может получать HTTP/3, даже если origin Nginx его не принимает.
И наоборот: вы можете идеально включить QUIC на origin, но пользователь его никогда не увидит, если внешний proxy завершает соединение раньше.
Поэтому при проверке всегда задавайте вопрос:
кто является публичным TLS/QUIC endpoint?
Это может быть:
- ваш Nginx;
- CDN;
- load balancer;
- reverse proxy.
Настраивать HTTP/3 нужно именно на том слое, где заканчивается пользовательское соединение.
Типовые причины, почему Alt-Svc есть, а h3 нет
Первая — UDP 443 закрыт.
Вторая — Nginx не собран с нужным модулем.
Третья — изменён не тот server block.
Четвёртая — внешний proxy не пропускает или сам завершает QUIC.
Пятая — IPv6 настроен иначе, чем IPv4.
Шестая — reuseport или другие socket options конфликтуют между несколькими vhosts.
Седьмая — клиент не поддерживает HTTP/3 или текущая сборка curl собрана без QUIC.
Восьмая — сама сеть пользователя блокирует UDP.
Поэтому диагностический маршрут всегда должен идти снизу вверх:
nginx -V
→ конфиг
→ nginx -t
→ UDP listener
→ firewall
→ Alt-Svc
→ внешний QUIC
→ Protocol: h3
Не наоборот.
Практический кейс Buildum.ru
В нашем случае исходное состояние было хорошим:
- HTTPS уже работал;
- HTTP/2 работал;
- сертификат был валиден;
- Nginx уже был достаточно новым.
Мы добавили QUIC listener и Alt-Svc, оставив HTTP/2.
После reload обычная проверка показывала:
HTTP/2
Alt-Svc: h3=":443"; ma=86400
Это подтвердило, что старый transport не сломан и HTTP/3 объявляется.
Но системный curl не умел HTTP/3, поэтому на этом останавливаться было нельзя.
Финальная проверка выполнялась с внешней стороны HTTP/3-capable клиентом.
Вот именно это я считаю хорошим критерием готовности:
не «в конфиге появилась строка quic», а реальный внешний клиент договорился с сервером о протоколе h3.
Нужен ли HTTP/3 каждому сайту
Если используется современный CDN и HTTP/3 уже включён на edge — отдельно делать что-либо на origin часто не требуется.
Если сайт работает напрямую на Nginx и версия сервера уже поддерживает QUIC, включение обычно относительно небольшое изменение.
Если ради HTTP/3 нужно:
- собирать нестабильный custom server;
- менять весь proxy stack;
- ломать текущую TLS-инфраструктуру;
я бы сначала оценил реальный эффект.
Особенно на небольшом корпоративном сайте.
HTTP/3 — хороший современный транспорт.
Но он не должен превращаться в инфраструктурный проект ради одной надписи h3 в DevTools.
Как я проверяю HTTP/3 после внедрения
Мой итоговый критерий состоит из нескольких независимых проверок.
Конфигурация
nginx -V
sudo nginx -t
Listeners
ss -lntp | grep ':443'
ss -lunp | grep ':443'
Нужны TCP и UDP.
Fallback
curl -I https://example.ru/
Обычный HTTPS продолжает работать.
Advertisement
Alt-Svc: h3=":443"; ma=86400
Реальный browser connection
DevTools → Network → Protocol → h3
Внешний тест
HTTP/3 checker реально устанавливает QUIC-соединение.
Если все уровни сходятся, настройка закончена.
Главный вывод
HTTP/3 на современном Nginx включается сравнительно просто.
Сложная часть — не написать:
listen 443 quic;
а проверить всю цепочку:
Nginx поддерживает QUIC
→ UDP 443 открыт
→ TLS работает
→ Alt-Svc объявлен
→ внешний клиент видит endpoint
→ QUIC handshake проходит
→ HTTP/3 negotiated как h3
→ HTTP/2 остаётся fallback
Именно такой подход мы использовали на реальном сервере.
Он защищает от самого неприятного ложного результата:
«HTTP/3 настроен», потому что в response header есть слово h3, хотя ни один внешний клиент соединиться по QUIC не может.
HTTP/3 стоит внедрять как нормальное эволюционное улучшение сетевого слоя: без обещаний магического SEO, без отключения HTTP/2 и с обязательной проверкой реального соединения после каждого изменения.
Практика
Как включить и проверить HTTP/3 на Nginx
Проверьте сборку Nginx
Выполните nginx -V и убедитесь, что серверная сборка поддерживает ngx_http_v3_module. Если Nginx собран вручную без HTTP/3 module, одной правкой virtual host протокол не включить.
Оставьте HTTPS по TCP
Не удаляйте обычный listen 443 ssl и HTTP/2: они остаются рабочим fallback для клиентов и сетей без QUIC.
Добавьте QUIC listener
Добавьте listen 443 quic и при подходящей конфигурации reuseport; после изменения nginx -t должен завершиться без ошибок.
Объявите HTTP/3
Добавьте Alt-Svc: h3=":443"; ma=86400, чтобы браузеры узнали о доступном HTTP/3 endpoint.
Откройте UDP 443
Проверьте firewall и инфраструктуру перед сервером. TCP 443 может работать идеально, но заблокированный UDP 443 полностью исключит прямое QUIC-соединение.
Проверьте конфигурацию
Выполните nginx -t и reload. Обычный HTTPS должен продолжать отвечать по HTTP/2, а в ответах появиться корректный Alt-Svc.
Подтвердите реальный h3
Проверьте колонку Protocol в Chrome DevTools, HTTP/3-capable curl либо внешний HTTP/3 checker. Нормальный результат — фактически установленное соединение h3.
Сравните работу сайта
После включения проверьте реальные шаблоны сайта, ошибки Nginx и полевые показатели. Не считайте сам факт HTTP/3 доказанным ускорением, пока пользовательские данные этого не показывают.
FAQ
Что проверить перед и после включения HTTP/3
Нет. На практике сервер продолжает принимать HTTP/1.1 и HTTP/2 по TCP 443, а HTTP/3 — по QUIC через UDP 443. Если UDP недоступен или QUIC-соединение не устанавливается, клиент может вернуться к TCP-версии HTTP. RFC Editor
Нет. Alt-Svc лишь сообщает клиенту, что origin доступен через HTTP/3 на указанном порту. После этого клиент ещё должен успешно установить QUIC-соединение. Именно поэтому заголовок нужно проверять отдельно от фактического протокола запроса.
Обычно используется тот же номер 443, но HTTP/1.1/HTTP/2 работают через TCP, а QUIC/HTTP/3 — через UDP. Nginx рекомендует для совместимости использовать одинаковый номер порта для HTTPS и QUIC.
Гарантии нет. HTTP/3 способен помочь на сетях с потерями и уменьшить влияние потери одного пакета на независимые потоки, но выигрыш зависит от сети и страницы. Google публично говорил, что HTTP/3 не является прямым фактором ранжирования; актуальная документация Page Experience по-прежнему акцентирует Core Web Vitals и общий пользовательский опыт.
Версия curl сама по себе не гарантирует HTTP/3: конкретный бинарник libcurl должен быть собран с подходящим QUIC backend. Если поддержки нет, для проверки используйте другой HTTP/3-capable curl, браузер DevTools или внешний QUIC checker.
Рейтинг статьи
Материал был полезен?
Оценка помогает понимать, какие материалы стоит обновлять и расширять.








