Сколько коннектов нужно выставлять в пуле и почему?
Что проверяют
Понимаете ли, что размер пула считается от пропускной способности базы, а не подбирается на глаз, и знаете ли, что соединений больше не значит быстрее. Заодно смотрят, представляете ли вы, как пул умножается на процессы приложения.
Как отвечать
Отталкивайтесь от базы. В PostgreSQL каждое соединение это отдельный процесс со своей памятью, и активных запросов больше, чем ядер, база параллельно всё равно не выполнит: дальше растёт не пропускная способность, а очередь и время отклика. Рабочая отправная точка это единицы соединений на ядро сервера базы, дальше подбор по замерам.
Второй ориентир, закон Литтла: нужная конкурентность равна целевой пропускной способности, умноженной на среднее время запроса. Двести запросов в секунду по десять миллисекунд дают всего два одновременных соединения, и пул на сто штук тут лишний.
Третье, про что забывают: считать нужно суммарно по всем процессам. Итог это размер пула, умноженный на число воркеров и на число подов, и он должен уместиться в max_connections с запасом на обслуживание.
engine = create_engine(dsn, pool_size=5, max_overflow=5,
pool_timeout=3, pool_recycle=300, pool_pre_ping=True)Скажите, что будете мерить: время ожидания в пуле, состояния в pg_stat_activity, долю idle in transaction. Если процессов много и они короткоживущие, ставится PgBouncer в транзакционном режиме, а пул приложения делается маленьким.
Где спотыкаются
Ставят большой максимум «с запасом». База захлёбывается на конкуренции за блокировки и переключении контекста, задержка хвостовых запросов растёт, а пул при этом наполовину пуст. Очередь лучше держать на стороне приложения с коротким таймаутом.
Забывают про умножение. Локально пул на двадцать соединений, в проде те же двадцать на четыре воркера и на пять подов, и база отказывает в новых подключениях раньше, чем нагрузка станет заметной.
Держат соединение дольше запроса: открывают транзакцию и внутри идут в чужой HTTP API. Пул кончается не от нагрузки, а от висящих транзакций, и лечится это сокращением транзакции, а не увеличением пула.