Акция Панель управления ispmanager для VDS — первый месяц бесплатно
до 31.07.2026 Подробнее
Выберите продукт

Linux: dmesg «TCP: out of memory» — rmem/wmem, backlog и drops: диагностика и настройка

Сообщение dmesg «TCP: out of memory» обычно означает не нехватку RAM, а упор в лимиты сетевого стека: буферы rmem/wmem, очереди backlog, tcp_mem. В статье — диагностика по drops/ListenOverflows, пошаговые проверки и безопасные правки sysctl.
Linux: dmesg «TCP: out of memory» — rmem/wmem, backlog и drops: диагностика и настройка

Сообщение в dmesg вида TCP: out of memory -- consider tuning tcp_mem (или упоминания rmem, wmem, backlog) — почти всегда не про «закончилась оперативка» в прямом смысле. Обычно ядро упирается в лимиты сетевого стека (память под TCP/буферы сокетов/очереди приёма) или не успевает обрабатывать входящий поток пакетов, из-за чего растут drops, retransmits и хвостовые задержки.

Ниже — практический разбор: как подтвердить проблему метриками, где именно возникает узкое место (netdev backlog, SYN/accept backlog, TCP memory), и какие параметры (net.core.rmem_max, net.core.wmem_max, net.core.netdev_max_backlog, net.ipv4.tcp_mem) имеет смысл менять. Сценарий рассчитан на типичный сервер Linux (чаще всего VDS или выделенный) с современным ядром.

Что именно означает «TCP: out of memory»

У TCP есть несколько уровней «памяти», и сообщение «out of memory» может относиться к разным ограничениям:

  • Буферы сокетов (receive/send buffers): верхние границы регулируются через net.core.rmem_max и net.core.wmem_max, а фактический размер обычно подбирает автотюнинг TCP.
  • Глобальные пороги TCP-памяти (страницы под TCP): задаются net.ipv4.tcp_mem.
  • Очереди обработки: входящая очередь на уровне сетевого устройства (netdev backlog) и очереди на уровне сокета/accept.

Когда ядро пишет «out of memory» в контексте TCP, оно сообщает: «я не могу выделить память/буфер для TCP-операции в текущих условиях и лимитах». Итог — пакеты/сегменты могут быть отброшены, соединения становятся нестабильными, приложения начинают ловить таймауты.

Это может происходить даже при заметном свободном объёме RAM по free. Срабатывают внутренние лимиты, давление на аллокации страниц, фрагментация, либо очередь пакетов переполняется быстрее, чем CPU успевает её разгрести.

Быстрая проверка: есть ли реальные drops и где они появляются

Перед правками sysctl подтвердите проблему счётчиками. Минимальный набор команд для первичной картины:

dmesg -T | grep -E "TCP: out of memory|tcp_mem|backlog|rmem|wmem"
ip -s link
ss -s
netstat -s | grep -i -E "listen|drops|overflow|retrans"
nstat -az | grep -i -E "ListenOverflows|ListenDrops|TCPSynRetrans|TCPRetransSegs"

Как интерпретировать вывод

  • ip -s link: растут RX drops на интерфейсе — чаще проблема на пути «карта → ядро» (драйвер/IRQ/очереди), а не в самом TCP.
  • nstat: ListenOverflows и ListenDrops указывают на переполнение очередей вокруг приёма новых соединений.
  • netstat -s: «dropped», «overflowed», «pruned» — явные признаки, что что-то выкидывается до приложения.

Счётчики drops в nstat и ip -s link для диагностики проблем сети

Карта узких мест: rmem/wmem vs backlog

Ключевой момент: rmem/wmem и backlog — разные уровни. Ошибка, которая встречается чаще всего: поднять только net.core.rmem_max/net.core.wmem_max, хотя дропы происходят в очередях.

1) Узкое место: netdev backlog (очередь входящих пакетов)

net.core.netdev_max_backlog ограничивает очередь пакетов, которые уже приняла сетевая карта, но сетевой стек ещё не успел обработать. При перегрузе CPU (softirq), неправильном распределении IRQ или всплеске трафика очередь переполняется, и ядро начинает дропать «раньше TCP».

Симптомы обычно такие:

  • растут RX drops в ip -s link;
  • заметная нагрузка в softirq, скачки latency;
  • пики PPS (packets per second), особенно на мелких пакетах.

2) Узкое место: backlog на уровне TCP/сокета (очередь соединений)

Вокруг TCP-accept есть два «backlog», которые важно не путать:

  • net.core.somaxconn — верхняя граница accept backlog в ядре (ограничивает то, что приложение передаёт в listen(backlog)).
  • net.ipv4.tcp_max_syn_backlog — очередь полуоткрытых соединений (SYN-RECV), актуальна при наплыве новых подключений.

Симптомы:

  • растут ListenOverflows/ListenDrops;
  • клиенты видят таймауты на этапе подключения;
  • нагрузка CPU может быть умеренной, но всплески новых соединений «сносят» очередь.

3) Узкое место: TCP memory (tcp_mem) и буферы rmem/wmem

Если много одновременных TCP-потоков и/или большие окна, TCP начинает активно потреблять память под буферы. Тогда чаще всего всплывают параметры:

  • net.core.rmem_max и net.core.wmem_max — максимальные размеры receive/send буферов на сокет (верхняя граница).
  • net.ipv4.tcp_mem — глобальные пороги TCP-памяти, после которых ядро ужесточает выделение и может «душить» новые аллокации.

Симптомы:

  • в dmesg есть упоминания tcp_mem, rmem, wmem;
  • много активных соединений с передачей (прокси, стриминг, репликации, API с большими ответами);
  • растут retransmits и падает throughput.
FastFox VDS
Облачный VDS-сервер в России
Аренда виртуальных серверов с моментальным развертыванием инфраструктуры от 195₽ / мес

Шаг 1. Зафиксируйте базовую картину до изменений

Тюнинг сетевых лимитов имеет побочные эффекты: можно снизить drops, но создать давление по памяти и получить уже системные проблемы. Поэтому сначала снимите слепок:

uname -r
sysctl net.core.rmem_max net.core.wmem_max net.core.netdev_max_backlog net.ipv4.tcp_mem net.core.somaxconn net.ipv4.tcp_max_syn_backlog
ss -m
cat /proc/meminfo | grep -E "MemAvailable|Slab|SReclaimable|SUnreclaim|Commit"
cat /proc/net/sockstat
cat /proc/net/sockstat6

/proc/net/sockstat* показывает, сколько памяти реально занято сокетами. Это помогает отличить «TCP реально упирается в память» от ситуации, когда дропы идут из-за очередей или CPU.

Шаг 2. Приведите в порядок backlog, если проблема в наплыве пакетов/соединений

Если у вас явные ListenOverflows/ListenDrops или RX drops на интерфейсе — начинать стоит с очередей, а уже потом переходить к rmem/wmem.

Увеличение netdev backlog

Аккуратно поднимите net.core.netdev_max_backlog. На нагруженных узлах типовые значения — от 5000 до 50000, но универсального числа нет: зависит от PPS, CPU и задержек обработки.

sysctl -w net.core.netdev_max_backlog=16384

Если после этого drops заметно снизились — вероятно, вы попали в цель. Если при этом растёт задержка и CPU уходит в softirq, одно увеличение очереди может лишь «буферизовать боль»: дальше нужно смотреть распределение прерываний и обработку пакетов (IRQ affinity, RPS/RFS, драйвер/virtio).

Увеличение очередей для accept

При большом числе коротких соединений (HTTP без keepalive, агрессивные healthchecks, всплески ботов) полезно синхронно поднять somaxconn и SYN backlog:

sysctl -w net.core.somaxconn=4096
sysctl -w net.ipv4.tcp_max_syn_backlog=8192

Важно: приложение должно успевать «выедать» очередь. Если у веб-сервера мало воркеров или есть блокировки на accept, вы просто перенесёте проблему на следующий слой.

Если у вас Nginx/стриминг/прокси-сценарии, может быть полезна статья про удержание соединений и поведение очередей: как работает upstream keepalive в Nginx и что он даёт под нагрузкой.

Шаг 3. Настройка rmem/wmem и tcp_mem: когда это действительно нужно

Если «TCP: out of memory» коррелирует с большим числом активных TCP-потоков, а sockstat показывает существенные расходы памяти на сокеты, тогда имеет смысл корректировать лимиты буферов и, при необходимости, tcp_mem.

Понимание rmem_max/wmem_max (и почему «поставить побольше» опасно)

net.core.rmem_max и net.core.wmem_max задают максимальные размеры буфера приёма/передачи на сокет. Это не означает, что каждый сокет получит максимум: автотюнинг подбирает фактические значения исходя из RTT/BDP и активности обмена.

Типичная ошибка — выставить огромные значения «на всякий случай». При тысячах соединений это легко превращается в резкий рост пикового потребления памяти и новые проблемы уже на уровне системы.

tcp_mem: глобальные пороги TCP-памяти

net.ipv4.tcp_mem — три числа в страницах памяти:

  • нижний порог: TCP расходует память свободно;
  • pressure: ядро начинает ограничивать рост;
  • верхний предел: жёсткое ограничение, возможны отказы выделения.

Так как это страницы, «правильность» чисел зависит от размера страницы (обычно 4096 байт). Поэтому полезнее мыслить эффектом: «сколько памяти суммарно я готов отдать под TCP в пике» с учётом остальных сервисов (БД, кеш, JVM).

Если вы не измерили фактическое потребление сокетов и не понимаете бюджет памяти под сеть, не начинайте с правки tcp_mem. Часто сначала нужно вылечить очереди и/или нагрузку на CPU.

Стартовый профиль для теста (без изменения tcp_mem)

Ниже — не «магические числа», а безопасная стартовая точка для итеративного теста на сервере с запасом RAM. Меняйте постепенно и после каждого шага проверяйте drops/latency/память:

sysctl -w net.core.rmem_max=33554432
sysctl -w net.core.wmem_max=33554432
sysctl -w net.core.netdev_max_backlog=16384

Если вам нужен системный подход к тюнингу сети (и чтобы не упустить вторичные параметры), держите под рукой общий гайд: шпаргалка по sysctl для сетевой производительности Linux.

Виртуальный хостинг FastFox
Виртуальный хостинг для сайтов
Универсальное решение для создания и размещения сайтов любой сложности в Интернете от 95₽ / мес

Как проверить, что стало лучше (и что вы не сделали хуже)

После каждой серии изменений (сначала очереди, затем буферы) прогоняйте один и тот же чек-лист:

  • dmesg -T: перестали ли появляться новые сообщения про TCP: out of memory;
  • ip -s link: снизились ли RX/TX drops;
  • nstat -az: перестали ли расти ListenOverflows/ListenDrops;
  • netstat -s: уменьшились ли retransmits;
  • /proc/net/sockstat: не ушла ли память сокетов в опасный рост.

Если drops упали, но latency выросла — это намёк, что вы увеличили очереди, не увеличив способность сервера обрабатывать трафик. Тогда фокус смещается на CPU, softirq, распределение IRQ и оптимизацию приложения (keepalive, пул соединений, компрессия, лимиты воркеров).

Типовые причины, из-за которых sysctl не спасает

1) CPU упирается в softirq

Сеть — это ещё и вычисления. При высоком PPS узким местом становится CPU, а очереди лишь откладывают дропы. Быстрые проверки:

mpstat -P ALL 1
top -H

Если одно ядро стабильно забито softirq, нужен разбор распределения нагрузки по ядрам (IRQ affinity, RPS/RFS), а иногда — банально больше vCPU.

2) Слишком много коротких соединений

HTTP без keepalive, агрессивные проверки здоровья, «шторма» от клиентов — всё это создаёт лавину TCP-рукопожатий. Тогда растёт нагрузка на accept/SYN-очереди, и вы видите ListenDrops даже при нормальном throughput. Лечение обычно в приложении и на прокси-слое: keepalive, уменьшение числа новых соединений, корректные таймауты.

3) Вы завысили буферы и спровоцировали давление по памяти

Подняли rmem_max/wmem_max, стало лучше, а потом начались подлагивания и внезапные убийства процессов? Классика: TCP получил право брать больше, а остальным сервисам стало тесно. В такой ситуации ищите баланс: снижайте потолки, ограничивайте одновременные соединения, внедряйте backpressure.

Мониторинг retransmits и ListenDrops до и после изменения sysctl

Как закрепить изменения (и не потерять их после перезагрузки)

Временные изменения через sysctl -w живут до перезагрузки. Для постоянной настройки создайте отдельный файл:

cat > /etc/sysctl.d/99-tcp-memory-backlog.conf << 'EOF'
net.core.netdev_max_backlog = 16384
net.core.somaxconn = 4096
net.ipv4.tcp_max_syn_backlog = 8192
net.core.rmem_max = 33554432
net.core.wmem_max = 33554432
EOF
sysctl --system

Если решите менять net.ipv4.tcp_mem, фиксируйте это там же, но делайте итеративно и записывайте, какой симптом лечите и какими метриками подтверждаете улучшение.

Мини-runbook: если ошибка уже в проде

  1. Сопоставьте время сообщений в dmesg с ростом счётчиков (drops, ListenOverflows, RX drops).

  2. Если шторм подключений: поднимите net.core.somaxconn и net.ipv4.tcp_max_syn_backlog, проверьте backlog на стороне приложения (параметр listen(backlog) у сервиса).

  3. Если дропы на интерфейсе: поднимите net.core.netdev_max_backlog и параллельно проверьте CPU/softirq.

  4. Если упираетесь в TCP-память: оцените расход через /proc/net/sockstat, затем аккуратно корректируйте rmem_max/wmem_max; к tcp_mem переходите только с понятным бюджетом RAM.

  5. После каждого шага сравните динамику счётчиков и latency. Если стало стабильно — закрепите настройки в /etc/sysctl.d.

Итоги

TCP: out of memory в dmesg — это сигнал, что сетевой стек не справляется в рамках текущих лимитов/очередей, а не обязательно проблема «в целом не хватает RAM». Сначала определите, где растут drops: на интерфейсе (netdev backlog), на уровне приёма соединений (SYN/accept backlog) или в буферах TCP (rmem/wmem и пороги tcp_mem). Правильная последовательность — измерить, поправить очереди по симптомам, затем буферы, и только в конце осознанно трогать tcp_mem.

Если после тюнинга sysctl ошибка возвращается на пиках, это часто означает упор в ресурсы (CPU/память) или профиль нагрузки. Тогда эффективнее пересмотреть поведение клиентов/приложения и масштабирование (например, перейти на более мощный VDS), чем бесконечно раздувать буферы.

Поделиться статьей

Вам будет интересно

Debian/Ubuntu: mount: wrong fs type, bad option, bad superblock — как быстро найти и исправить причину OpenAI Статья написана AI (GPT 5)

Debian/Ubuntu: mount: wrong fs type, bad option, bad superblock — как быстро найти и исправить причину

Ошибка mount: wrong fs type, bad option, bad superblock в Debian/Ubuntu может означать и простую опечатку в имени раздела, и пробл ...
Debian/Ubuntu: XFS metadata corruption и emergency read-only — пошаговое восстановление OpenAI Статья написана AI (GPT 5)

Debian/Ubuntu: XFS metadata corruption и emergency read-only — пошаговое восстановление

Если XFS-раздел внезапно стал доступен только для чтения, а сервер ушёл в emergency mode, главное — не спешить. Разберём безопасны ...
Debian/Ubuntu: как исправить Failed to fetch при apt update OpenAI Статья написана AI (GPT 5)

Debian/Ubuntu: как исправить Failed to fetch при apt update

Ошибка Failed to fetch при apt update в Debian и Ubuntu обычно связана не с самим APT, а с DNS, сетью, зеркалом, прокси, временем ...