Пул потоков Tomcat: почему 200 — не магическое число

14.08.2026 · Tomcat 10.1 / 11, Spring Boot 3

У коннектора Tomcat по умолчанию maxThreads="200", и это значение годами переезжает из проекта в проект без изменений. Обычно с ним всё в порядке — до первого инцидента, после которого его либо поднимают до тысячи, либо опускают до пятидесяти. Оба решения чаще всего принимают наугад.

Сколько потоков нужно на самом деле

Хорошая отправная точка — закон Литтла: среднее число одновременно обрабатываемых запросов равно потоку запросов, умноженному на среднее время ответа. 400 запросов в секунду при 50 мс на запрос — это 20 занятых потоков в среднем. При 500 мс — уже 200, и пул упирается в потолок.

Отсюда главный вывод: число потоков почти никогда не определяет пропускную способность само по себе. Оно определяет, сколько запросов может одновременно ждать — базу, соседний сервис, диск.

Узкое место обычно не в Tomcat

Типичная картина: maxThreads=200, а у HikariCP maximumPoolSize=10 (значение по умолчанию). Когда база начинает отвечать медленнее, 190 потоков выстраиваются в очередь за соединением, держат память и сокеты клиентов, а Tomcat выглядит «зависшим». Поднимать в этот момент maxThreads бессмысленно — очередь просто станет длиннее.

Что помогает на практике:

Что меняют виртуальные потоки

В Tomcat 11 и в свежих версиях 10.1 коннектор умеет работать на виртуальных потоках Java 21:

<Connector port="8080" protocol="HTTP/1.1"
           useVirtualThreads="true" />

В Spring Boot то же самое включается одной настройкой spring.threads.virtual.enabled=true. Ограничение в 200 потоков исчезает, но вместе с ним исчезает и неявная защита: раньше пул платформенных потоков сам ограничивал нагрузку на базу, теперь тысячи виртуальных потоков разом придут к тем же десяти соединениям. Лимиты приходится выставлять явно — семафором, размером пула или rate limiter'ом на входе.

Короткий вывод

Прежде чем менять maxThreads, стоит посчитать ожидаемую конкурентность по закону Литтла и сравнить её с самым узким ресурсом за приложением. Почти всегда настраивать нужно именно его.