PRODСуверенная европейская платформа BaaSОткрыть панель управления →

Производительность · 9 минута чтения

Postgres max_connections без пулера

Affane Daylami · Fondateur · 6 июня 2026 г.

Вернуться в блог

Без пула перед вашим сервером max_connections должен одновременно охватывать каждое открытое клиентское соединение, а не количество запросов, которые Postgres может эффективно обрабатывать параллельно. Смешение этих двух чисел является наиболее распространенной причиной неправильной установки max_connections: слишком низкое, чтобы поглотить нагрузку, или слишком высокое для реально доступной памяти.

Этот текст на английском языке был создан автоматически на основе французского оригинала и еще не проверялся.
Эта страница была переведена автоматически. Английская версия является авторитетной.

В этой статье приводится формула, опубликованная в вики PostgreSQL для расчета идеального одновременного выполнения вашего оборудования (наиболее цитируемая формула определения размера пула соединений в экосистеме), объясняется, почему каждое соединение стоит больше, чем поток приложения, а затем без догадок подробно описана процедура установки max_connections. Наша методология тестирования документирует протокол измерений, используемый для любых заявлений о производительности в этом блоге.

Самое необходимое

  • Без объединения в пул max_connections должен охватывать все одновременные клиентские соединения, а не только те, которые Postgres может эффективно обрабатывать параллельно.
  • Справочная формула вики-сайта PostgreSQL: идеальный активный параллелизм = (физические ядра × 2) + эффективные диски. Отправная точка, которая должна быть подтверждена измерениями, а не жесткий предел.
  • max_connections — это параметр контекста postmaster: его изменение требует полного перезапуска сервера, а не простой перезагрузки.
  • Каждое соединение Postgres — это отдельный системный процесс, а не легкий поток: именно это делает накладные расходы реальными, как только количество соединений увеличивается.
  • Проверено в коде: в своих выделенных кластерах Postgres Aurabase варьирует max_connections от 50 (уровень бесплатного пользования) до 400 (уровень предприятия) в зависимости от размера кластера.
#
Диагностика

Почему соединение Postgres стоит дороже, чем поток приложения

Postgres не использует облегченный пул потоков для своих соединений. Каждое подключение клиента запускает полноценный системный процесс.

Процесс postmaster создает новый («вилку») для каждой попытки подключения, посвященный этому единственному сеансу, пока он не будет закрыт. Официальная документация проекта описывает именно этот механизм в главе, посвященной основам архитектуры (postgresql.org/docs/current/connect-estab.html, раздел «Семантика соединения», по состоянию на 24 августа 2026 г.).

У этого выбора есть реальное преимущество: сбой одного соединения не влияет на другие, каждый процесс изолирован от остального сервера. Это также имеет прямую стоимость: каждое дополнительное соединение добавляет в расписание целый процесс ОС со своим собственным пространством памяти и собственными накладными расходами на переключение контекста для ядра.

Что это меняет на практике

Приложение, открывающее 500 прямых подключений к Postgres без объединения в пул, заставляет сервер управлять 500 одновременными системными процессами, даже если подавляющее большинство из них простаивают между двумя запросами.

#
Стоимость памяти

Что на самом деле потребляет соединение: общая память и work_mem

Два различных механизма влияют на память, и их путаница почти всегда приводит к неправильному диагнозу.

Первое исправлено. При запуске Postgres резервирует структуры общей памяти (блокировки, таблица процессов), размер которых равен значению max_connections, независимо от того, будут ли впоследствии открыты эти соединения. В официальной документации по этому параметру прямо указано: для его увеличения может потребоваться больше общей системной памяти, чем позволяет конфигурация вашей ОС по умолчанию (postgresql.org/docs/current/runtime-config-connection.html, по состоянию на 24 августа 2026 г.).

Второй является переменным и гораздо более опасен в масштабе: work_mem выделяется не один раз для каждого соединения, а один раз для каждой операции сортировки или хеширования в плане запроса. Официальная документация ясно говорит на этот счет: сложный запрос может запускать несколько таких операций параллельно, и несколько сеансов могут делать то же самое одновременно, так что фактически используемая память может стоить в несколько раз больше work_mem (postgresql.org/docs/current/runtime-config-resource.html, по состоянию на 24 августа 2026 г.).

Самый худший случай, который стоит запомнить

Не только max_connections × work_mem угрожает памяти сервера. Это max_connections × work_mem × количество одновременных операций на запрос. Именно этот продукт объясняет сервер, который меняет местами или у которого заканчивается память после увеличения max_connections, которое считается безобидным.

#
Формула

Формула определения размера вики PostgreSQL

В официальной вики-странице проекта PostgreSQL документирована эталонная формула для расчета количества активных соединений , которое ваше оборудование может эффективно обрабатывать параллельно, а не количества открытых соединений в целом (wiki.postgresql.org/wiki/Number_Of_Database_Connections, по состоянию на 24 августа 2026 г.).

Формула

идеальный активный параллелизм = (физические ядра × 2) + эффективные диски. Количество ядер исключает гиперпоточность. Число эффективных дисков в современных SSD-накопителях остается близким к 1, где понятие отдельного физического диска («шпинделя») теряет большую часть своего первоначального значения.

На сервере с 8 физическими ядрами и SSD-накопителем формула дает (8 × 2) + 1 = 17 активных подключений, прежде чем пропускная способность начнет снижаться. Эта цифра часто удивляет: она кажется крохой по сравнению с сотнями соединений, которые приложение открывает на практике. Именно этому посвящен следующий абзац.

Число, рассчитанное по формуле, измеряет параллелизм, который могут обеспечить ЦП и диск, а не количество клиентских подключений, которые необходимо открыть вашему приложению. Группа из 20 прикладных процессов, каждый из которых имеет собственный пул из 10 подключений, открывает 200 одновременных подключений к Postgres, даже если в любой момент времени активно работают только 17 из них. Без пулера max_connections должно охватывать 200, а не 17. Именно этот пробел подталкивает большинство архитектур добавлять пулер в режиме транзакций, даже если это означает выбор того, какой из них (см. наше сравнение PgBouncer, Supavisor и PgCat).

#
Процедура

Как изменить max_connections (и зачем нужна перезагрузка)

max_connections не подлежит горячей замене. Это параметр контекста postmaster: Postgres читает его один раз при запуске, чтобы определить размер своей общей памяти. Перезагрузки конфигурации (pg_reload_conf() или SIGHUP) недостаточно, необходимо перезагрузить сервер.

Сначала проверьте текущее значение и его контекст, чтобы убедиться в необходимости перезагрузки:

psqlsql
SHOW max_connections;

SELECT name, setting, context
FROM pg_settings
WHERE name = 'max_connections';

-- context='postmaster' подтверждает, что требуется перезагрузка

Затем примените новое значение и перезапустите:

psqlsql
ALTER SYSTEM SET max_connections = '300';

-- Написано в postgresql.auto.conf.
-- Никакого эффекта, пока Postgres не будет перезапущен.
terminalbash
# С помощью systemd
sudo systemctl restart postgresql

# Без systemd, напрямую с pg_ctl
pg_ctl restart -D $PGDATA -m fast
Маржа, о которой многие забывают

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

#
Проверено в коде

Как Aurabase распределяет max_connections в своих кластерах Postgres

Определение размера max_connections — это не просто теоретическое упражнение. Вот как Aurabase планирует это в своих управляемых кластерах Postgres:

100
POSTGRES ПО УМОЛЧАНИЮ
max_connections перед любой настройкой
50→400
СПЕЦИАЛЬНЫЕ ПОДШИПНИКИ AURABASE
бесплатно для предприятий, от кластера CNPG
3
СУПЕРПОЛЬЗОВАТЕЛЬ ЗАРЕЗЕРВИРОВАН
superuser_reserved_connections, Postgres по умолчанию

Выделенные кластеры: один кластер Postgres на проект.

На этом уровне (см. наше сравнение выделенной и общей базы) каждый проект получает собственный кластер CloudNativePG и собственный бюджет max_connections, размер которого зависит от размера экземпляра:

бесплатный (выделенный)max_connections 501 экземпляр · 500 млн виртуальных ЦП · 512Mi
про (по умолчанию)max_connections 2002 экземпляра · 1 виртуальный ЦП · 2Gi
командаmax_connections 3003 экземпляра · 2 виртуальных ЦП · 3Gi
бизнесmax_connections 4003 экземпляра · 2 виртуальных ЦП · 4Gi

Общие кластеры: несколько проектов организации, общий бюджет.

По этому второму пути все проекты одной организации подключаются через пул CNPG (PgBouncer, режим transaction) перед общим первичным сервером:

бесплатноmax_connections 50max_client_conn 100max_user_connections 20
проmax_connections 100max_client_conn 200max_user_connections 60
командаmax_connections 200max_client_conn 400max_user_connections 150

Все проекты в организации соединяются через общую роль приложения. Таким образом, max_user_connections ограничивает общее количество подключений к серверу, которые эта роль может открыть во всем кластере: это настоящая глобальная защита кластера, а не max_client_conn, который ограничивает только клиентские подключения к самому пулу.

Однако этот пулер обслуживает только трафик приложений SDK. PostgREST, со своей стороны, остается напрямую подключенным к основному сервису (-rw): объединение в пул в режиме транзакций нарушит механизм перезагрузки схемы, который прослушивает выделенный канал LISTEN с именем pgrst. Поэтому его собственные соединения (2 на реплику на общем уровне, 10 на реплику на выделенном уровне) напрямую учитываются в бюджете max_connections первичного сервера, за пределами какого-либо пулера, именно тот тип «забытого» соединения, который должен включать шаг 1 процедуры ниже.

Цифры, которые в настоящее время калибруются, предполагаются таковыми

Код явно документирует эти общие бюджеты пулеров как начальные значения, подлежащие калибровке в реальных условиях путем измерения pg_stat_activity под нагрузкой, а не как фиксированные значения из опубликованного теста. Это та же самая дисциплина, которая описана в нашей методологии тестирования : измеряйте, прежде чем корректировать, а не гадать, а затем надеяться. Эти кластеры работают на PostgreSQL 16 — выбор, описанный в нашем сравнении Postgres 16, 17 и 18.

#
Метод

5-шаговая процедура определения размера max_connections без объединения в пул

Эта процедура не зависит от какого-либо конкретного инструмента: она применима к любому серверу Postgres, управляемому или локальному.

  1. Подсчитайте количество фактических клиентских подключений. Количество процессов приложения, умноженное на размер их внутреннего пула, плюс инструменты администрирования, репликации и мониторинга. Именно это число, а не формула, устанавливает минимальный уровень max_connections.
  2. Рассчитайте идеальную параллельную работу вашего оборудования по формуле из вики PostgreSQL: (физические ядра × 2) + эффективные диски. Эта цифра показывает, сколько из этих соединений действительно могут работать параллельно без снижения пропускной способности.
  3. Установите max_connections выше фактической потребности для шага 1, с запасом для superuser_reserved_connections и для любых инструментов администрирования, которые открывают свои собственные соединения вне приложения.
  4. Примените изменения с помощью ALTER SYSTEM SET, затем перезапустите сервер. Это параметр postmaster: простой перезагрузки недостаточно, как подробно описано выше.
  5. Мониторинг pg_stat_activity с течением времени. Если количество простаивающих соединений значительно превышает количество активных соединений, это не проблема max_connections: это сигнал о том, что вам нужен пулер перед сервером, а не большее число.

Запрос мониторинга из шага 5, который можно использовать напрямую:

psqlsql
SELECT state, count(*)
FROM pg_stat_activity
GROUP BY state
ORDER BY count(*) DESC;
#
Предупреждающий сигнал

Когда формулы уже недостаточно: признаки того, что вам нужен пулер

Три сигнала систематически возвращаются, когда одного max_connections уже недостаточно, каким бы ни было его значение.

  1. Ошибка FATAL: sorry, too many clients already появляется во время пиковой нагрузки, тогда как большинство подключений, отображаемых pg_stat_activity, находятся в состоянии ожидания.
  2. Приложение работает в бессерверной среде или с эфемерными рабочими процессами (граничными функциями, короткими заданиями), которые открывают и закрывают соединения гораздо быстрее, чем была разработана для модели Postgres «процесс на соединение».
  3. Вышеупомянутая формула и процедура уже были применены, и фактическая потребность в клиентских соединениях продолжает превышать объем доступной памяти, который можно выделить, не ставя под угрозу work_mem или Shared_buffers.

В этих трех случаях правильный ответ почти всегда — это пулер, расположенный между приложением и Postgres, а не более высокий max_connections. В нашем сравнении PgBouncer, Supavisor и PgCat подробно описаны три варианта, а в нашем руководстве по режиму транзакций объясняется наиболее распространенный компромисс после установки пулера. Все настройки Postgres, помимо соединений, см. в нашем контрольном списке настройки производственного Postgres .

#
Часто задаваемые вопросы

Часто задаваемые вопросы

Что такое max_connections по умолчанию в PostgreSQL?+
100, с 3 соединениями, зарезервированными для суперпользователя по умолчанию (superuser_reserved_connections). Это значение по умолчанию подходит для многих приложений, которые проходят через пул, но без объединения в пул быстро становится недостаточным, как только каждый из множества процессов приложения открывает свой собственный пакет подключений.
Можем ли мы изменить max_connections без перезапуска PostgreSQL?+
Нет. max_connections — это параметр контекста postmaster: Postgres считывает его один раз при запуске, чтобы определить размер своей общей памяти. ALTER SYSTEM SET записывает новое значение в postgresql.auto.conf, но оно применяется только при полном перезапуске сервера; перезагрузки или SIGHUP недостаточно.
Сколько памяти потребляет неактивное соединение PostgreSQL?+
Единого официального числа не существует: оно зависит от work_mem,shared_buffers и расширений, загружаемых за сеанс. Однако документально подтверждено, что work_mem выделяется для каждой операции сортировки или хеширования в запросе, а не для каждого соединения: поэтому один сложный запрос может использовать work_mem несколько раз в одном активном соединении.
Должны ли мы всегда предпочитать пулер, такой как PgBouncer, более высокому значению max_connections?+
В большинстве случаев да, как только количество реальных клиентских подключений значительно превышает идеальный параллелизм, рассчитанный по вики-формуле PostgreSQL. Создатель пула в режиме транзакций объединяет небольшое количество физических соединений между гораздо большим количеством логических соединений на стороне приложения. Посмотрите наше сравнение PgBouncer, Supavisor и PgCat, чтобы выбрать какой из них.
Что именно измеряет формула (ядра × 2) + эффективные диски?+
Он оценивает идеальный активный параллелизм: количество запросов, которые процессор и диск данного сервера могут обрабатывать параллельно без снижения пропускной способности, а не общее количество соединений, которые нужно открыть в max_connections. Это отправная точка, которая должна быть проверена путем измерения, задокументированная в официальной вики-странице проекта PostgreSQL, а не жесткое ограничение.
Как узнать, близок ли мой сервер Postgres к лимиту подключений?+
Запросите pg_stat_activity и сравните количество соединений в активном состоянии с количеством соединений в состоянии ожидания. Большое количество простаивающих соединений вблизи ограничения max_connections без активного запроса почти всегда указывает на необходимость объединения, а не на необходимость дальнейшего повышения max_connections.

ГОТОВЫ К РАЗВЕРТЫВАНИЮ?

Ваш бэкэнд за пять минут.

Кредитная карта не требуется · 500 МБ бесплатно · 50 000 MAU