Когда веб‑проект растёт, стандартные настройки сети в Linux быстро перестают быть оптимальными. Очередь прослушивания, таймауты завершения TCP и размеры буферов напрямую влияют на пропускную способность, задержки и устойчивость к всплескам. В этой статье разбираем три ключевых блока: somaxconn и связанный с ним backlog, таймаут tcp_fin_timeout и набор параметров rmem/wmem (включая tcp_rmem/tcp_wmem). Всё — с упором на практический тюнинг для веб‑нагрузки, воспроизводимые команды и критерии успешности.
Как Linux принимает входящие соединения: короткая модель
Чтобы правильно крутить somaxconn и backlog, важно понимать, что происходит, когда клиент стучится к вашему порту:
- Half-open очередь (SYN backlog): хранит полуоткрытые соединения после получения SYN до завершения трёхстороннего рукопожатия. Её верхний предел регулируется
net.ipv4.tcp_max_syn_backlog, а также эффективностью обработки прерываний и RTO. - Accept queue (listen backlog): очередь завершённых соединений, ожидающих, когда приложение вызовет
accept(). Её верхний предел — минимум из значения, которое передал процесс вlisten(backlog), и системногоnet.core.somaxconn. - Ingress backlog: если ядро не успевает разбирать пакеты с сетевой карты, используется
net.core.netdev_max_backlog. Это уже более низкоуровневая часть стека, но при экстремальной нагрузке она тоже важна.
Если слушающая очередь переполнена, ядро начнёт отбрасывать входящие соединения. Клиенты увидят задержки с последующими таймаутами или мгновенные ошибки, а вы — рост метрик ListenDrops/ListenOverflows.
somaxconn и backlog: где узкое место
somaxconn — системный потолок для длины очереди уже установленных, но ещё не принятых приложением соединений. Даже если сервер (например, Nginx) попросит очень большой backlog в системном вызове listen(), ядро ограничит его до somaxconn. Поэтому всегда думайте о них как о связке.
Как посмотреть текущие значения и нагрузку
sysctl -n net.core.somaxconn
sysctl -n net.ipv4.tcp_max_syn_backlog
ss -lnt
ss -s
awk '/ListenOverflows|ListenDrops/ {print}' /proc/net/netstat
Полезная интерпретация:
ss -sпокажет накопительную статистику по TCP, включая состояние очередей./proc/net/netstatсодержит пары ключей и значений; особенно нас интересуютTcpExt: ListenOverflowsиListenDrops. Рост этих счётчиков под нагрузкой — сигнал, чтоbacklog/somaxconnмало или приложение не успеваетaccept().
Практические значения
Исторически многие дистрибутивы имели низкие дефолты (порядка 128). Для веб‑нагрузки разумно поднимать somaxconn до тысяч или даже десятков тысяч в зависимости от профиля. Но просто «крутить до упора» бессмысленно — если приложение не успевает вычитывать соединения, очередь останется полной, а задержки вырастут.
# осторожный старт для активного фронтенда
sysctl -w net.core.somaxconn=4096
sysctl -w net.ipv4.tcp_max_syn_backlog=8192
Затем дайте реальную нагрузку и следите за ListenOverflows/ListenDrops, латентностью и 99‑й перцентилью TTFB. Если сбросы исчезли, а задержки не выросли — оставляйте значения. Если очередь всё ещё переполняется — повышайте ступенчато.
Связь с настройками приложения
Серверы умеют указывать желаемый backlog на уровне сокета. Например, в Nginx:
# фрагмент nginx.conf
# директива listen может принимать параметр backlog
# пример: увеличиваем очередь для порта 80
listen 0.0.0.0:80 backlog=65535;
Помните: фактический предел = min(backlog, somaxconn). То есть нет смысла ставить в приложении backlog=65535, если somaxconn — 4096. Про устойчивые keepalive‑соединения в апстримах — см. руководство Keepalive для upstream в Nginx.
Если вы разворачиваете сервис на собственном сервере, такие настройки доступны полностью. На общем хостинге системные sysctl обычно недоступны, поэтому для тонкого тюнинга выбирайте VDS.
tcp_fin_timeout: ускоряем уборку без потерь
tcp_fin_timeout управляет тем, сколько времени ядро держит сокет в состоянии FIN‑WAIT‑2 для соединений, закрытых нашей стороной и не привязанных к пользовательскому процессу. Если значение слишком велико, при бурстовой нагрузке будут накапливаться «висящие» записи, расходуя память и таблицы. Слишком маленькое значение — риск разорвать соединение до того, как медленный клиент дочитает ответ.
Частые вопросы возникают из‑за путаницы с TIME_WAIT. На веб‑фронтендах TIME_WAIT — нормальное состояние, защищающее от старых дублей сегментов. Её укорачивание не должно идти вразрез со стандартами. В современном ядре лучше оставить управление TIME_WAIT по умолчанию и не трогать агрессивные и устаревшие опции (вроде давно удалённого tcp_tw_recycle).
Рекомендации по значениям
Дефолт часто около 60 секунд. Для большинства HTTP(S)‑нагрузок приемлем компромисс в диапазоне 15–30 секунд. Если у вас преобладают крупные загрузки и клиенты с высоким RTT, оставляйте ближе к 30. Для API с короткими запросами и устойчивой сетью можно пробовать 15–20.
# безопасный шаг вниз
sysctl -w net.ipv4.tcp_fin_timeout=20
Мониторьте динамику состояний сокетов:
ss -ant 'state fin-wait-2'
ss -ant 'state time-wait'
Если после снижения tcp_fin_timeout начали появляться жалобы на обрывы при медленных загрузках — верните более щадящее значение. Для сценариев крупных загрузок и длинных запросов пригодится материал о лимитах и буферах Nginx и PHP‑FPM: загрузки и скачивания в Nginx/PHP.

rmem/wmem и TCP‑автотюнинг: когда и зачем увеличивать
Параметры net.core.rmem_* и net.core.wmem_* задают пределы для сокетных буферов (receive/send), а net.ipv4.tcp_rmem и net.ipv4.tcp_wmem содержат триплеты: минимальный, дефолтный и максимальный размер буфера для TCP. Современный стек Linux умеет динамически увеличивать окна, но не превысит ваши максимумы. Поэтому при высоком BDP (широкий канал с большим RTT) стоит поднять верхние лимиты, иначе загрузки «не разгоняются».
Проверка и аккуратное повышение
sysctl -n net.core.rmem_max
sysctl -n net.core.wmem_max
sysctl -n net.ipv4.tcp_rmem
sysctl -n net.ipv4.tcp_wmem
Умеренный старт для фронтендов и сценариев «много мелких ответов»:
sysctl -w net.core.rmem_max=262144
sysctl -w net.core.wmem_max=262144
sysctl -w net.ipv4.tcp_rmem="4096 87380 262144"
sysctl -w net.ipv4.tcp_wmem="4096 65536 262144"
Для раздачи крупных файлов на клиентов с высоким RTT (например, международный трафик):
sysctl -w net.core.rmem_max=8388608
sysctl -w net.core.wmem_max=8388608
sysctl -w net.ipv4.tcp_rmem="4096 2097152 8388608"
sysctl -w net.ipv4.tcp_wmem="4096 1048576 8388608"
Следите за общей памятью: агрессивные лимиты на больших RPS увеличивают суммарное потребление RAM на сокетные буферы. Тестируйте под реалистичным RPS и конкаренси. Для внешнего мониторинга задержек и успешности подключений посмотрите Blackbox‑пробы HTTP/TCP/ICMP.
План безопасного тюнинга и отката
- Соберите базу: снимите текущие значения
sysctl, зафиксируйте метрики RPS, p95/p99 латентности, ошибки и overflow/drops из/proc/net/netstat. - Подготовьте конфиг: сделайте отдельный файл, например
/etc/sysctl.d/99-web-tuning.conf, и применяйте его траншем, а не точечно. - Применяйте по шагам: сначала
somaxconnиtcp_max_syn_backlog, затемtcp_fin_timeout, и уже потомrmem/wmem. Между шагами — нагрузочное тестирование. - Фиксируйте эффект: исключения ListenOverflows/ListenDrops должны уйти, латентность — не вырасти, потребление памяти — остаться в разумных пределах.
- План отката: храните прошлый конфиг рядом и в случае деградации верните его одной командой.
Шаблон файла настроек
# /etc/sysctl.d/99-web-tuning.conf
# Очереди входящих соединений
net.core.somaxconn = 4096
net.ipv4.tcp_max_syn_backlog = 8192
# Таймаут FIN-WAIT-2 (осторожно с очень низкими значениями)
net.ipv4.tcp_fin_timeout = 20
# Буферы TCP: умеренные лимиты для веб-фронтенда
net.core.rmem_max = 262144
net.core.wmem_max = 262144
net.ipv4.tcp_rmem = 4096 87380 262144
net.ipv4.tcp_wmem = 4096 65536 262144
Применение и проверка:
sysctl --system
sysctl -a | grep -E "somaxconn|tcp_max_syn_backlog|tcp_fin_timeout|tcp_.*mem|rmem|wmem"

Как понять, что именно упирается
- Overflow/Drop растут, p99 TTFB скачет, CPU в норме — вероятно, не хватает
somaxconn/backlogили приложение медлит сaccept(). - Много SYN‑RECV в
ss -antи медленный прогресс до ESTABLISHED — проверьтеtcp_max_syn_backlogи задержки в сети. - Море FIN‑WAIT‑2 — пересмотрите
tcp_fin_timeoutи поведение приложения при закрытии сокетов. - Высокие RTT и недоиспользованный канал при скачиваниях — увеличьте верхние лимиты
tcp_rmem/tcp_wmemиrmem_max/wmem_max.
Антипаттерны и мифы
- «Поставлю backlog побольше — и всё починится». Нет. Если приложение не успевает
accept(), то вы лишь растянете очередь и задержки. Смотрите профилирование воркеров и сетевые прерывания. - Агрессивное уменьшение таймаутов. Слишком низкий
tcp_fin_timeoutможет резать медленных клиентов. Двигайтесь постепенно. - Отключение TCP timestamps. Это может мешать расчёту RTO и взаимодействию с расширениями. Дефолт обычно разумен.
- Устаревшие твики. Опции вроде
tcp_tw_recycleдавно удалены. Не используйте рецепты из старых постов без проверки на актуальность ядра.
Мониторинг, который поможет
- Срез TCP:
ss -sи выборочные выборки по состояниям черезss -ant 'state ...'. - Переполнения очередей: читайте
/proc/net/netstat, парыListenOverflowsиListenDrops. Дополнительно полезныSynRetransmitsи прочие поляTcpExt. - Буферы: следите за общей памятью и сокетной статистикой. При росте лимитов
rmem/wmemпроверяйте RSS процесса и свободную RAM.
Готовые профили (от них удобно отталкиваться)
Профиль «Стандартный фронтенд»
Подойдёт для большинства сайтов и API, если нет экстремальных RTT и больших скачиваний.
net.core.somaxconn = 4096
net.ipv4.tcp_max_syn_backlog = 8192
net.ipv4.tcp_fin_timeout = 20
net.core.rmem_max = 262144
net.core.wmem_max = 262144
net.ipv4.tcp_rmem = 4096 87380 262144
net.ipv4.tcp_wmem = 4096 65536 262144
Профиль «Раздача крупных файлов и высокий RTT»
Для скачиваний, стриминга и международной аудитории, где важны окна побольше.
net.core.somaxconn = 8192
net.ipv4.tcp_max_syn_backlog = 16384
net.ipv4.tcp_fin_timeout = 30
net.core.rmem_max = 8388608
net.core.wmem_max = 8388608
net.ipv4.tcp_rmem = 4096 2097152 8388608
net.ipv4.tcp_wmem = 4096 1048576 8388608
Профиль «Шторм пиков»
Если трафик приходит волнами (например, флэш‑раскрутка), задача — не терять соединения в пики. Важно убедиться, что приложение и веб‑сервер масштабированы.
net.core.somaxconn = 16384
net.ipv4.tcp_max_syn_backlog = 32768
net.ipv4.tcp_fin_timeout = 20
net.core.rmem_max = 524288
net.core.wmem_max = 524288
net.ipv4.tcp_rmem = 4096 262144 524288
net.ipv4.tcp_wmem = 4096 131072 524288
Сопутствующие факторы, о которых часто забывают
- Квоты дескрипторов: увеличьте
fs.file-maxи лимиты вsystemd/ulimit, иначе вы упрётесь в открытые файлы раньше, чем в сеть. - Прерывания и очереди NIC: настройте распределение IRQ по CPU и RPS/XPS, иначе узким местом станет обработка пакетов.
- Веб‑сервер: проверьте
worker_processes,worker_connectionsи режимыaccept, чтобы он успевал опустошать accept‑очередь. - Защита от SYN‑флуда: убедитесь, что
net.ipv4.tcp_syncookiesвключен. Это не панацея, но полезный базовый уровень.
Чеклист перед продакшн‑включением
- Снята база метрик и сделана нагрузочная репетиция.
- Подключен файл
/etc/sysctl.d/99-web-tuning.conf, применён черезsysctl --system. - Параметры увеличивались ступенчато, за каждым шагом — измерения.
- После изменения
somaxconn/backlogфиксируем, чтоListenOverflows/ListenDropsне растут. - После изменения
tcp_fin_timeoutнет жалоб на обрывы при медленных загрузках. - После изменения
rmem/wmemпамять в пределах бюджета; латентность не ухудшилась.
Главная мысль: тюнинг сети — это не «магические числа», а управляемый процесс с измерениями до и после. Начинайте с очередей (
somaxconn/backlog), затем корректируйте таймауты и буферы, оценивая эффекты на реальной нагрузке.
Двигаясь по этому плану, вы снимете внезапные потери соединений, стабилизируете tail‑латентность и подготовите фронтенд к всплескам трафика без лишних рисков.


