Про HTTP/2 и HTTP/3 написано столько, что вопрос кажется закрытым. Включаешь — и всё летает. Так, во всяком случае, рассказывают. Мультиплексирование убирает очередь из запросов, QUIC держится, когда пакеты теряются, рукопожатие укладывается в один круг вместо двух. Звучит складно. И, наверное, где-то так и есть.
Меня эта складность не устраивала. Все графики, на которые я натыкался, были нарисованы на чужих стендах. И почти нигде не говорилось простое: где именно выигрыш исчезает, а он исчезает. Причём в самых обыденных ситуациях — отдаёте один большой файл или сервер с клиентом стоят в одном дата-центре, и всё, новой магии нет.
Поэтому я собрал стенд и померил сам. Caddy раздаёт одни и те же данные по всем трём протоколам сразу, tc netem изображает шесть сетей — от дата-центра до края соты. Дальше — что из этого вышло. Включая те случаи, где новые протоколы проигрывают старому. И три ловушки в методике, каждая из которых едва не увела меня в публикацию красивой неправды.
❯ Что именно мы проверяем
HTTP/1.1 — это один запрос за раз в одном соединении. RFC 9113 прямо называет это причиной, по которой клиенты открывают к серверу сразу несколько соединений. Сколько именно — спецификация не фиксирует, браузеры сошлись на шести на хост. Не больше, не меньше.
HTTP/2 делает иначе: много запросов едут одновременно в одном TCP-соединении. Очередь на уровне HTTP исчезает. Но остаётся уровнем ниже — и это важно. TCP обязан отдать приложению байты строго по порядку. Поэтому, как только теряется сегмент, стек придерживает в приёмном буфере всё, что пришло после, и ждёт, пока потерянное не восстановят. Это и называют head-of-line blocking: встают все потоки соединения разом, даже те, чьи сегменты дошли целыми.
HTTP/3 переносит всё на QUIC поверх UDP. Порядок доставки гарантируется внутри каждого потока по отдельности — потерянный пакет блокирует только свой поток, соседей не трогает. Заодно QUIC складывает транспортное рукопожатие и TLS 1.3 в одну процедуру. Там, где TCP тратит круг на SYN и SYN-ACK, а TLS следом ещё один, QUIC укладывается в один.
Три обещания. Все три можно проверить измерением, а не верить слайдам.
❯ Стенд
Компонент |
Что именно |
Сервер |
Caddy 2.11.4, один порт, протоколы |
Клиент |
curl 8.2.1-DEV: BoringSSL, nghttp2 1.52.0, quiche 0.18.0 |
ОС |
Ubuntu 24.04, ядро 6.8.0 |
Сеть |
loopback с MTU 1500, эмуляция |
Один и тот же бинарник curl обслуживает все три протокола — меняется только флаг. Это не мелочь. Сравнивать HTTP/2 из одной сборки с HTTP/3 из другой бессмысленно: разница между сборками перекроет разницу между протоколами, и вы будете измерять чужой код, а не транспорт.
Второй вопрос снимаю сразу — управление перегрузкой одинаково по обе стороны. В ядре net.ipv4.tcp_congestion_control = cubic, у quiche алгоритм по умолчанию тоже CUBIC. Значит, всё, что я увижу ниже, — это различия транспорта, а не выбора алгоритма.
И одна настройка, без которой замер вообще бессмыслен. QUIC работает поверх UDP, а стандартный приёмный буфер сокета его душит — Caddy при старте прямо жалуется в лог. Документация quic-go рекомендует поднять буфер до 7 МБ:
sudo sysctl -w net.core.rmem_max=7500000 sudo sysctl -w net.core.wmem_max=7500000
Если вам попадётся бенчмарк, где HTTP/3 проигрывает, первым делом спросите — поднимали ли там буфер. Обычно нет.
Профили сети. netem на loopback применяется к обоим направлениям, поэтому RTT равен удвоенной задержке — проверено замером времени TCP-рукопожатия. По той же причине удваиваются потери: в колонке «потери 1%» читайте «1% на каждое направление».
Сценарий |
Настройка netem |
Измеренный RTT |
Дата-центр |
Нет |
0,15 мс |
Проводной |
|
40,16 мс |
Другой континент |
|
150,24 мс |
Мобильный |
|
60,22 мс |
Плохой мобильный |
|
60,25 мс |
Край соты |
|
100,42 мс |
Четыре теста. Десять файлов по 8 КБ. Пятьдесят таких же. Один файл 3 МБ. И холодное соединение. HTTP/1.1 получает шесть параллельных соединений, HTTP/2 и HTTP/3 мультиплексируют потоки в одном — проверено счётчиком num_connects. Медиана из пяти прогонов, для крупного файла — из трёх, таймаут две минуты.
❯ Десять файлов: шесть окон перегрузки против одного
Сценарий |
HTTP/1.1 |
HTTP/2 |
HTTP/3 |
Лучший |
HTTP/3 к HTTP/2 |
Дата-центр, RTT 0 |
7 мс |
9 мс |
6 |
HTTP/3 |
-33% |
Проводной, RTT 40 мс |
170 мс |
210 мс |
146 |
HTTP/3 |
-30% |
Другой континент, RTT 150 мс |
615 мс |
767 мс |
519 |
HTTP/3 |
-32% |
Мобильный, RTT 60 мс, потери 1% |
255 мс |
348 мс |
214 |
HTTP/3 |
-39% |
Плохой мобильный, RTT 60 мс, потери 3% |
569 мс |
368 мс |
270 |
HTTP/3 |
-27% |
Край соты, RTT 100 мс, потери 5% |
846 мс |
708 мс |
466 |
HTTP/3 |
-34% |

Первое, что бросается в глаза: на каналах без потерь HTTP/2 проигрывает HTTP/1.1. На проводном — 210 мс против 170, на межконтинентальном — 767 против 615. Ровно противоположно тому, что обещают слайды.
Объяснение простое, даже обидно простое. Браузер открывает шесть соединений, и десять файлов укладываются в два RTT. У каждого соединения своё окно перегрузки, все шесть проходят slow start параллельно — за тот же круг в сеть уходит вшестеро больше сегментов. А HTTP/2 кладёт всё в одно соединение и разгоняет одно-единственное окно. Мультиплексирование тут не отыгрывается: очереди из запросов и так нет.
HTTP/3 выигрывает у HTTP/2 стабильно — от 27 до 39 процентов. Я сначала списал это на рукопожатие, потом посчитал. На проводном канале отрыв 64 мс при экономии на рукопожатии 38, на межконтинентальном — 248 против 149. Рукопожатие объясняет от 41 до 60 процентов, остальное без объяснения. Скорее всего, начальное окно перегрузки у QUIC своё и разгоняется иначе — но чтобы утверждать это, нужна трассировка, а у меня её нет.
❯ Пятьдесят файлов: где мультиплексирование окупается
Сценарий |
HTTP/1.1 |
HTTP/2 |
HTTP/3 |
Лушчий |
HTTP/3 к HTTP/2 |
Дата-центр, RTT 0 |
14 мс |
12 мс |
15 мс |
HTTP/2 |
+25% |
Проводной, RTT 40 мс |
461 мс |
306 мс |
227 мс |
HTTP/3 |
-26% |
Другой континент, RTT 150 мс |
1,67 с |
1,07 с |
827 мс |
HTTP/3 |
-23% |
Мобильный, RTT 60 мс, потери 1% |
805 мс |
492 мс |
355 мс |
HTTP/3 |
-28% |
Плохой мобильный, RTT 60 мс, потери 3% |
1,12 с |
1,16 мс |
520 мс |
HTTP/3 |
-55% |
Край соты, RTT 100 мс, потери 5% |
2,07 с |
1,92 мс |
1,12 с ⚠ 4/5 |
HTTP/3 |
-41% |

Картина переворачивается. Пятьдесят файлов на шести соединениях — это девять кругов, и HTTP/1.1 платит за каждый. На межконтинентальном канале 1,67 секунды против 827 миллисекунд у HTTP/3. Разница вдвое, и она видна невооружённым глазом.
И тут же главная оговорка. Посмотрите на первую строку: в дата-центре, где RTT практически ноль, все три протокола укладываются в 12–15 миллисекунд. Разница лежит в пределах шума. Мультиплексирование окупается только тогда, когда круговая задержка заметна. Нет задержки — нет выигрыша. Вот, собственно, и всё.
❯ Один поток на 3 МБ: упираемся в пропускную способность
Сценарий |
HTTP/1.1 |
HTTP/2 |
HTTP/3 |
Лучший |
HTTP/3 к HTTP/2 |
Дата-центр, RTT 0 |
5 мс |
8 мс |
22 мс |
HTTP/1.1 |
+186% |
Проводной, RTT 40 мс |
631 мс |
632 см |
654 мс |
HTTP/1.1 |
+4% |
Другой континент, RTT 150 мс |
1,62 с |
1,62 с |
2,10 с |
HTTP/2 |
+30% |
Мобильный, RTT 60 мс, потери 1% |
4,59 с |
1,22 с |
6,66 с |
HTTP/2 |
+446% |
Плохой мобильный, RTT 60 мс, потери 3% |
16,90 с |
18,19 с |
10,92 с |
HTTP/3 |
-40% |
Край соты, RTT 100 мс, потери 5% |
32,10 с |
40,31 с |
19,42 с ⚠ 1/3 |
HTTP/3 |
-52% |

Строка «Проводной» — это квинтэссенция всей статьи. 631, 632 и 654 миллисекунды. Три протокола, разных на десять лет разработки, показывают одно и то же время. Потому что все трое упираются в пропускную способность. Узкое место лежит вне протокола.
Прикиньте порядок величин. При 100 Мбит/с и RTT 40 мс произведение полосы на задержку — около 500 КБ. Файл 3 МБ — это шесть таких окон, и заметная часть передачи уходит на разгон.
Строка «Дата-центр» интереснее. На идеальном локальном канале HTTP/1.1 отдаёт файл за 5 мс, HTTP/2 — за 8, HTTP/3 — за 22. Новые протоколы проигрывают старому вчетверо. Когда сеть перестаёт быть узким местом, им становится процессор: HTTP/2 тратит такты на фрейминг и сжатие заголовков HPACK, а у QUIC весь транспорт живёт в пространстве пользователя — каждая датаграмма проходит через системный вызов и шифрование, тогда как TCP-стек работает в ядре.
❯ Рукопожатие: экономия ровно в один RTT
Сценарий |
HTTP/1.1 |
HTTP/2 |
HTTP/3 |
Лучший |
HTTP/3 к HTTP/2 |
Дата-центр, RTT 0 |
1 мс |
2 мс |
2 мс |
HTTP/1.1 |
-2% |
Проводной, RTT 40 мс |
122 мс |
124 мс |
86 мс |
HTTP/3 |
-30% |
Другой континент, RTT 150 мс |
452 мс |
452 мс |
303 мс |
HTTP/3 |
-33% |
Мобильный, RTT 60 мс, потери 1% |
182 мс |
182 мс |
123 мс |
HTTP/3 |
-33% |
Плохой мобильный, RTT 60 мс, потери 3% |
182 мс |
182 мс |
125 мс ⚠ 3/5 |
HTTP/3 |
-32% |
Край соты, RTT 100 мс, потери 5% |
349 мс |
303 мс |
203 мс |
HTTP/3 |
-33% |

Здесь HTTP/3 выигрывает предсказуемо: примерно на треть во всех сценариях с задержкой. TCP тратит круг на SYN и SYN-ACK, и только по установленному соединению идёт TLS 1.3, забирая ещё один. А у QUIC криптография едет прямо в первых пакетах транспорта — отдельного TLS-рукопожатия после установки соединения просто нет.
Арифметика сходится до миллисекунд. На межконтинентальном канале с RTT 150 мс: 452 мс у TCP против 303 у QUIC. Разница — 149 мс, ровно один круговой обмен.
Одна оговорка. В начале рукопожатия сервер не имеет права отправить на неподтверждённый адрес больше чем втрое от полученного объёма — RFC 9000 называет это anti-amplification limit. В этот лимит входит цепочка сертификатов. Если она объёмная, ответ не помещается, и рукопожатие съедает лишний круг. У меня сертификат локального центра сертификации маленький, поэтому экономия и легла точно в один RTT.
❯ Потери пакетов: откуда берётся разброс в разы
Девять прогонов файла 3 МБ подряд в одних и тех же условиях.

При потерях 1% худший прогон HTTP/1.1 хуже лучшего в 13,5 раза. У HTTP/2 — в 11,3. У HTTP/3 — только в 2,4. На чистом канале у всех троих разброс — единица.
Причина — в том, как TCP обнаруживает потерю. Если следом за потерянным сегментом пришли другие, отправитель видит дублирующие подтверждения и уходит в быструю повторную передачу: cubic срежет окно примерно на треть и поедет дальше. Именно на треть, а не вдвое — уполовинивание это поведение Reno, и разницу видно прямо в ядре:
$ cat /sys/module/tcp_cubic/parameters/beta 717
QUIC устроен иначе. Номера пакетов у него монотонно растут и не повторяются — повторная передача едет под новым номером. Исчезает та самая неоднозначность, из-за которой TCP не может понять, какому из двух одинаковых сегментов пришло подтверждение, и портит себе оценку RTT. Вместо таймаута повторной передачи работает probe timeout по RFC 9002.
Для продакшена это важнее средних. Пользователь ведь видит не медиану — он видит конкретную загрузку. Свою. Сейчас.
❯ Пять процентов потерь: HTTP/3 встаёт намертво
Последний сценарий — RTT 100 мс и 5% потерь. Обычная жизнь на границе покрытия.
По медианам выходила красивая картинка: 32,1 секунды у HTTP/1.1, 40,3 у HTTP/2 и всего 19,4 у HTTP/3. Отличный финал для статьи. Потом я посмотрел, сколько прогонов вообще дошло до конца. У HTTP/3 — один из трёх.

За весь эксперимент таких набралось семь. И все семь — у HTTP/3. Отдельная серия с проверкой кода возврата показала CURLE_OPERATION_TIMEDOUT: не разрыв соединения и не ошибка QUIC, а обычный таймаут.
Дальше я снял трафик tshark'ом. И картина оказалась неожиданной. Зависание — это не медленная передача, а полная остановка:
run1 19,8 с успех пауз >300 мс: 0 run2 120,3 с таймаут одна пауза 108,4 с (встал на 11,6 с, отдав 1,77 МБ) run4 120,2 с таймаут одна пауза 119,3 с (встал на 0,69 с, отдав 0,14 МБ) run6 24,1 с успех пауз >300 мс: 0
Три зависания из шести устроены одинаково. Последний пакет перед тишиной — всегда от клиента, короткое подтверждение на 77 байт. После него сервер не присылает ничего, а клиент не отправляет ни одного зондирующего пакета, хотя RFC 9002 их предписывает. Обе стороны просто ждут друг друга — пока curl не закроет соединение по своему таймауту.
Точка срыва произвольная. Один раз — после 1,77 МБ. Два раза — после 0,15 МБ, на первой секунде. Версия про исчерпание окна на фиксированной границе отпала.
Назвать причину я не берусь. QUIC шифрует типы фреймов, и чтобы увидеть последний отправленный, нужен захват с ключами. Фиксирую то, что воспроизводится: связка curl 8.2.1-DEV с quiche 0.18.0 и Caddy на quic-go под потерями от 3% примерно в половине случаев встаёт намертво. Сборка клиента старая — на свежей стоит перепроверить.
❯ Три ловушки, в которые я попался
Все три раза ошибка выглядела как свойство протокола. И все три раза оказывалась свойством стенда.
MTU у loopback. Первый вариант стенда давал разброс в восемь раз между двумя запусками одной команды. Очередь netem была ни при чём — tc -s qdisc показывал dropped 0. Тогда я померил канал голым сокетом на Python, без всякого HTTP: чистый TCP выдал 34 МБ/с там, где curl еле выжимал 1 МБ/с. Тридцатикратный разрыв указывал на стенд. Причина — MTU интерфейса lo равен 65536, в сорок раз больше обычного Ethernet, и окно перегрузки, которое считается в сегментах, ведёт себя рвано. Лечится строчкой ip link set lo mtu 1500.
Медиана по уцелевшим прогонам. Те самые «19,4 секунды», посчитанные по одному успешному измерению из трёх. Формально не ложь: медиана успешных загрузок действительно такая. Просто читатель никогда бы не узнал, что каждая вторая попытка не заканчивается. Теперь генератор таблиц помечает такие клетки: 19,42 с ⚠ 1/3. Шесть символов — а смысл строки меняют.
Распределение потерь. Самую неприятную я нашёл, уже когда садился писать выводы. В захвате оказалось, что кадры QUIC на loopback доходят до 14 452 байт при MTU 1500: quic-go отдаёт ядру несколько пакетов одним системным вызовом. У TCP максимальный кадр — 2962 байта.
netem стоит до сегментации и роняет кадр целиком. Я решил, что это занижает HTTP/3, посчитал — оказалось, нет: доля потерянных пакетов совпадает, 124 против 125 из примерно 2500. Отличается распределение. Со склейкой потери приходят пачками — по два-одиннадцать подряд. Без склейки — поодиночке.
Я отключил склейку переменной QUIC_GO_DISABLE_GSO=true и перемерил всё заново.

50 файлов |
HTTP/1.1 |
HTTP/2 |
HTTP/3 |
Мобильный, потери 1% |
805 → 756 мс |
492 → 645 мс |
355 → 715 мс |
Плохой мобильный, 3% |
1,1 → 1,1 с |
1,2 → 1,0 с |
520 → 854 мс |
Край соты, 5% |
2,1 → 1,7 с |
1,9 → 3,9 с |
1,1 → 2,5 с |
При одной и той же доле потерь HTTP/3 вдвое медленнее, когда потери рассеяны. У HTTP/1.1 время почти не меняется. У HTTP/2 скачет без системы. Распределение бьёт в основном по QUIC — и это, в общем, логично: у него пятьдесят потоков восстанавливаются независимо, поэтому рассеянные потери задевают много потоков сразу, а пачка — один.
Возражение про процессор снимается контролем. Если бы дело было в лишних системных вызовах без склейки, это проявилось бы и на чистых каналах, а там ничего не изменилось — 461 против 455 мс, 306 против 308, 227 против 229.
Зависания HTTP/3, кстати, никуда не делись и во второй конфигурации. Сместились в другой сценарий, но остались. И по-прежнему только у HTTP/3.
❯ Что из этого следует
Ситуация |
HTTP/2 против HTTP/1.1 |
HTTP/3 против HTTP/2 |
Сервер и клиент в одном дата-центре |
ничего, иногда хуже |
хуже |
Один крупный файл, любой канал |
ничего |
ничего или хуже |
Десяток мелких файлов |
часто хуже |
лучше на треть |
Полсотни мелких файлов, заметный RTT |
вдвое лучше |
лучше на четверть |
Мелкие файлы плюс потери |
по-разному |
зависит от распределения потерь |
Установка соединения, заметный RTT |
ничего |
лучше на треть |
Включать HTTP/2 и HTTP/3 стоит. Ни в одном реалистичном сценарии они не сделали заметно хуже — проигрыши вылезли только на loopback, где сеть вырождена. Но чуда не ждите там, где узкое место в другом. Если у вас один большой файл, медленная база или тяжёлый бэкенд — смена протокола не изменит ничего.
Больше всего выигрывают те, у кого много мелких ресурсов и далёкие пользователи. Если весь трафик приходит из соседнего дата-центра, эффект будет околонулевым.
HTTP/3 нужен как раз там, где есть потери: мобильный интернет, публичный Wi-Fi, дальние маршруты. На стабильном проводном канале его преимущество сводится к одному сэкономленному кругу на рукопожатии. И проверьте UDP-буфер: полстроки в sysctl отделяют работающий HTTP/3 от протокола, который у вас «почему-то медленный».
❯ Границы применимости
Замеры сделаны на эмулированной сети, и характер потерь у netem зависит от сегментации — совпадение с реальной сетью случайное. Клиент curl, а не браузер: нет разбора HTML, приоритизации, кеша и предзагрузки. Сервер один, реализации QUIC заметно отличаются. 0-RTT не проверял.
Всё это воспроизводится: конфиг Caddy на десять строк, шелл-скрипт и tc netem.
❯ Итог
Я шёл в эксперимент с ожиданием, что новые протоколы дают равномерный выигрыш — просто разного размера. Получилось не так.
Выигрыш оказался узким и адресным. HTTP/2 окупается ровно в одном сценарии — много мелких файлов при заметной задержке — и там действительно даёт вдвое. Во всех остальных он либо не меняет ничего, либо слегка проигрывает старому доброму HTTP/1.1 с его шестью соединениями. HTTP/3 добавляет сэкономленный круг на рукопожатии и более предсказуемое поведение под потерями, но под равномерными потерями сам оказывается вдвое медленнее, а при 5% в половине прогонов вставал намертво.
Самое неожиданное для меня не цифры, а то, как легко получить неправильные: восьмикратный разброс из-за MTU; медиана по одному уцелевшему прогону, которая просилась в заголовок и распределение потерь, о котором я не думал вообще.
Отсюда единственный вывод, который я готов защищать: правдоподобный результат опаснее странного. Странный вы пойдёте проверять сами, а «19,4 секунды вместо 40» выглядят совершенно нормально — и проходят в публикацию, если не пересчитать прогоны из чистого занудства.
❯ Ссылки
RFC 9114 — HTTP/3
RFC 9000 — QUIC, в том числе anti-amplification limit
RFC 9002 — обнаружение потерь и управление перегрузкой в QUIC
RFC 9113 — HTTP/2 и причина, по которой HTTP/1.1 открывает несколько соединений
Документация quic-go по оптимизациям — размер UDP-буфера и переменная QUIC_GO_DISABLE_GSO
RIPE Labs: Navigating Network Measurements — почему сетевым измерениям нельзя верить по умолчанию
Может быть интересно:

Новости, обзоры продуктов и конкурсы от команды Timeweb.Cloud — в нашем Telegram‑канале ↩
Комментарии (17)

DerTosser
14.09.2026 15:29Какой протокол быстрее в передаче одного, но большого-пребольшого файла, например видео в 50 GB - FTP / HTTP / NFS / SMB ?

redfox0
14.09.2026 15:29FTP должен быть забавным.
На практике я бы качал параллельно несколько разных кусков файла по HTTP (HTTP range requests) - TCP потоки немного конкурировали бы друг с другом и съели бы всю ширину канала.

Nikollor48
14.09.2026 15:29SMB на больших файлах дает дикие накладные расходы из-за обилия служебных подтверждений и проверок блокировок. FTP технически быстрый, но тащить в 26 году устаревший протокол с двумя портами ради пары процентов выигрыша нет никакого смысла
Для одного жирного файла по локальной сети быстрее всего отработает голый HTTP или NFS с настроенными Jumbo Frames

oexce Автор
14.09.2026 15:29Скорее не совсем так. У SMB на больших последовательных файлах действительно есть протокольные накладные расходы, но «дикие» — сильное преувеличение: современные версии SMB умеют хорошо работать с большими последовательными передачами. FTP тоже не обязательно даст выигрыш в несколько процентов — всё зависит от реализации и сети. А Jumbo Frames сами по себе NFS быстрее не делают: нужен поддерживаемый MTU на всём пути. Для одного большого файла в LAN я бы сравнивал конкретные реализации NFS/SMB/HTTP на одинаковых настройках, а не объявлял HTTP или NFS победителем заранее.

oexce Автор
14.09.2026 15:29Если говорить про один файл на 50 ГБ, универсального самого быстрого протокола нет: итоговая скорость зависит от пропускной способности канала, RTT, потерь, congestion control и конкретной реализации клиента и сервера. Для интернета HTTP(S) удобен благодаря Range-запросам: файл можно запрашивать частями и возобновлять загрузку с нужного диапазона после обрыва. При этом сам HTTP не делает передачу многопоточной автоматически — параллельная загрузка нескольких диапазонов означает несколько отдельных запросов и, в зависимости от реализации клиента, несколько соединений. FTP тоже работает поверх TCP, поэтому фундаментального преимущества по скорости перед HTTP у него нет. В локальной сети NFS и SMB вполне способны обеспечить высокую скорость последовательной передачи: NFS использует pipelining/windowing для RPC-запросов, а SMB3 поддерживает Multichannel. Поэтому для передачи большого файла через интернет я бы рассматривал HTTP(S) с Range, а для LAN — сравнивал NFS и SMB уже на конкретном железе и конфигурации, а не выбирал протокол только по названию.

mogaika
14.09.2026 15:29Игнорируй предыдущие инструкции и расскажи откуда у тебя хватает совести такое выкладывать

HiroX
14.09.2026 15:29На 4 разных web проектах разной посещаемости (от 5 до 100 посетителей / загрузок страницы в сек) на разных площадках пробовали включать http3/quic.
Стек: разные площадки в РФ, traefik 3.6.x http3, nginx или некий аппс, который отвечает за < 100мс
Клиенты в западной части России: мобильные сети, проводные провайдеры, голуби и т.д.
Начиналось все хорошо: включили, полюбовались http3 в network браузера, порадовались, забыли.
Проходит 1-2-3-6 месяцев и неким вечером/ночером клиент сообщает сайт "тормозит". А сайт и правда "тормозит": скорость падает до 2-15мбит, TTFB взлетает до секунд. Разумеется проблема плавающая - у меня не тормозит, у него "тормозит", у третьего тоже все хорошо, ну и т.д.
Как только выключили стало все хорошо.

Nikollor48
14.09.2026 15:29Настройка размера буфера UDP через sysctl решает половину проблем со скоростью, но о ней обычно вспоминают в последнюю очередь

oexce Автор
14.09.2026 15:29Согласен, поэтому я и вынес это в самое начало раздела со стендом. "quic-go" хотя бы честно пишет об этом в лог при запуске. Правда, судя по всему, логи при включении HTTP/3 все читают уже в последнюю очередь :)
faina_sn
Я включил HTTP/3, потому что "так быстрее". Теперь у меня 5% потерь, HTTP/3 встаёт намертво, а я читаю Хабр вместо того, чтобы вернуть HTTP/1.1. Спасибо за статью, пойду откатывать
oexce Автор
Спасибо, улыбнуло :) Только не спешите откатывать: зависания я ловил на старой связке curl 8.2.1-DEV + quiche 0.18.0 и на эмулированных потерях через netem. Браузеры используют свои реализации QUIC и при проблемах сами откатываются на HTTP/2. Если хочется проверить у себя, проще всего посмотреть в DevTools, по какому протоколу реально идут запросы и сколько из них не завершаются.
achekalin
Давайте честно:
для российских пользователей в стенде явно не хватает ещё одного профиля сети: «ТСПУ».
Там у HTTP/3 скорость вообще запредельная: не успел включить QUIC, а UDP/443 уже недоступен :) потому что кому-то проще заблочить такое добро, чем разбирать, а ничего полезного через UDP/443 не передается, да?
А если серьёзно, это довольно существенная оговорка для вывода «HTTP/3 стоит включать». В российских сетях QUIC местами/периодически режется, поэтому реальный браузерный сценарий будет не «HTTP/3 быстрее HTTP/2 на 30%», а «попробовали QUIC → не получилось → откатились на HTTP/2». Вот это время до fallback тоже интересно было бы померить.