# «Cannot assign requested address» при тысячах коротких соединений к Redis или базе: исчерпаны локальные порты, а лечится пулом соединений

**URL:** <https://kryptos.forum/t/cannot-assign-requested-address-pri-tysyachah-korotkih-soedinenij-k-redis-ili-baze-ischerpany-lokalnye-porty-a-lechitsya-pulom-soedinenij/127>\
**Category:** Разработка ПО\
**Tags:** разработка\
**Created:** [30.Сентябрь.2026 08:51:44 UTC](https://kryptos.forum/t/cannot-assign-requested-address-pri-tysyachah-korotkih-soedinenij-k-redis-ili-baze-ischerpany-lokalnye-porty-a-lechitsya-pulom-soedinenij/127 "2026-09-30T08:51:44Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![team\_dev](https://kryptos.forum/letter_avatar_proxy/v4/letter/t/ecae2f/32.png) [@team\_dev](https://kryptos.forum/u/team_dev)\
**Post date:** [30.Сентябрь.2026 08:51:44 UTC](https://kryptos.forum/t/cannot-assign-requested-address-pri-tysyachah-korotkih-soedinenij-k-redis-ili-baze-ischerpany-lokalnye-porty-a-lechitsya-pulom-soedinenij/127/1 "2026-09-30T08:51:44Z")

</div>

**Что было.** Приложение открывает к Redis соединение на каждую операцию и сразу закрывает. Примерно на 28 тысячах операций в минуту начинаются ошибки `connect: cannot assign requested address`, хотя Redis свободен и отвечает мгновенно.

**Почему именно 28 тысяч.** Каждое исходящее соединение занимает локальный порт из диапазона `net.ipv4.ip_local_port_range`, по умолчанию 32768–60999, то есть около 28 тысяч портов. Закрытое соединение держит порт ещё 60 секунд в состоянии `TIME_WAIT`. Если за минуту открыть больше 28 тысяч коротких соединений к одной паре адрес:порт, свободных портов не остаётся. Это ограничение TCP на стороне клиента, Redis тут ни при чём; то же будет с MySQL, HTTP-клиентом к внутреннему API, чем угодно.

**Настоящее решение: не открывать соединения на каждую операцию.** Пул соединений или одно долгоживущее соединение на рабочий поток. Во всех клиентских библиотеках Redis пул есть из коробки; в HTTP-клиентах это keep-alive и переиспользование сессии (`requests.Session`, агент с `keepAlive: true` в Node, `http.Client` с общим `Transport` в Go). После этого число портов перестаёт зависеть от числа операций.

**Паллиативы на уровне ядра** , если код поправить нельзя быстро:

- `net.ipv4.ip_local_port_range = 1024 65535`: даёт около 64 тысяч портов вместо 28.
- `net.ipv4.tcp_tw_reuse = 1`: разрешает повторно использовать порт в `TIME_WAIT` для исходящих соединений, если временные метки TCP включены. Безопасно.
- `net.ipv4.tcp_tw_recycle`: **не включать**. Ломает соединения клиентов за NAT и удалён из ядра начиная с 4.12. Его до сих пор советуют в старых статьях.
- `net.ipv4.tcp_fin_timeout` на `TIME_WAIT` не влияет, вопреки популярному совету: он про `FIN_WAIT_2`.

**Как убедиться, что это ваш случай.**

```auto
ss -s # сводка: сколько в timewait
ss -tan state time-wait | awk '{print $4}' | cut -d: -f1 | sort | uniq -c | sort -rn | head

```

Если десятки тысяч `TIME_WAIT` от одного локального адреса к одному удалённому порту, диагноз ясен.

**Со стороны сервера** (когда `TIME_WAIT` копятся на нём) вреда почти нет: это лишь память под записи, и портов сервера они не занимают. Бороться с ними на сервере не нужно.

Параметры описаны в [документации ядра Linux](https://www.kernel.org/doc/html/latest/networking/ip-sysctl.html).
