Тюнинг PostgreSQL: shared_buffers, work_mem, effective_cache_size

Наша компания занимается разработкой, поддержкой и обслуживанием сайтов любой сложности. От простых одностраничных сайтов до масштабных кластерных систем построенных на микро сервисах. Опыт разработчиков подтвержден сертификатами от вендоров.

Разработка и обслуживание любых видов сайтов:

Информационные сайты или веб-приложения
Сайты визитки, landing page, корпоративные сайты, онлайн каталоги, квиз, промо-сайты, блоги, новостные ресурсы, информационные порталы, форумы, агрегаторы
Сайты или веб-приложения электронной коммерции
Интернет-магазины, B2B-порталы, маркетплейсы, онлайн-обменники, кэшбэк-сайты, биржи, дропшиппинг-платформы, парсеры товаров
Веб-приложения для управления бизнес-процессами
CRM-системы, ERP-системы, корпоративные порталы, системы управления производством, парсеры информации
Сайты или веб-приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, конструкторы сайтов, порталы предоставления электронных услуг, видеохостинги, тематические порталы

Это лишь некоторые из технических типов сайтов, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента

Услуги, которые мы предлагаем
Показано 1 из 1Все 2062 услуг
Тюнинг PostgreSQL: shared_buffers, work_mem, effective_cache_size
Сложный
~2-3 дня
Часто задаваемые вопросы

Наши компетенции:

Этапы разработки

Последние работы

  • image_website-b2b-advance_0.webp
    Разработка сайта компании B2B ADVANCE
    1360
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1251
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    957
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1188
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    929
  • image_bitrix-bitrix-24-1c_fixper_448_0.webp
    Разработка веб-сайта для компании ФИКСПЕР
    948

Дефолтная конфигурация PostgreSQL рассчитана на скромное железо и неэффективна на современных серверах. shared_buffers = 128MB, work_mem = 4MB — эти параметры оставляют 95% памяти неиспользованной. Например, сервер с 32 ГБ RAM и дефолтными настройками использует лишь 128 МБ для кэша — база простаивает, а запросы тормозят. Правильный тюнинг даёт прирост производительности минимум 30% и снижает нагрузку на дисковую подсистему. Мы выполняем настройку под ваш профиль: OLTP, аналитика или смешанная нагрузка. Опыт команды — 50+ успешных проектов, гарантия результата.

Тюнинг PostgreSQL — это не просто «поставить цифры побольше», а понимание, как планировщик использует память, как устроен кэш и как избежать проблем с вводом-выводом. Настройка shared_buffers, work_mem и effective_cache_size — базовая, но критически важная задача. Неправильная конфигурация ведёт к свопингу или недогрузке ОЗУ. Наши инженеры анализируют ваш сервер и нагрузку, чтобы подобрать оптимальные значения.

Проблемы, которые решаем

Нехватка work_mem для аналитики

Медленные отчёты из-за сброса сортировок на диск. Типичная ситуация: запрос с ORDER BY по большой таблице выполняется минуты, хотя план показывает сортировку на диске. Это решается увеличением work_mem для конкретных запросов или созданием покрывающих индексов.

Неверный effective_cache_size

Планировщик выбирает последовательные сканирования вместо индексных, потому что думает, что кэш мал. Установка effective_cache_size в 75% RAM сразу увеличивает количество index scan.

Конфликт shared_buffers с кэшем ОС

Слишком большой shared_buffers (более 25% RAM) приводит к конкуренции с кэшем операционной системы и снижает cache hit ratio. Проверка через pg_buffercache помогает найти оптимум.

Как мы это делаем

Используем проверенную методику: аудит текущей конфигурации, анализ планов запросов, подбор параметров под нагрузку. Пример: интернет-магазин с нагрузкой 10 000 запросов в минуту. После настройки время выполнения отчётов сократилось с 5 минут до 20 секунд, cache hit ratio вырос с 97% до 99,8%.

Стек инструментов

  • PostgreSQL 14–17
  • pgtune для начальной оценки
  • pg_buffercache для мониторинга буферов
  • EXPLAIN ANALYZE для анализа запросов
  • pg_stat_statements для выявления тяжёлых запросов

Процесс настройки

  1. Аудит текущей конфигурации и профиля нагрузки
  2. Сбор метрик: cache hit ratio, использование буферов, план запросов
  3. Настройка shared_buffers — 25% RAM для выделенного сервера
  4. Настройка work_mem — от 4 МБ до 64 МБ для OLTP, 256 МБ – 1 ГБ для аналитики
  5. Установка effective_cache_size — 75% RAM
  6. Оптимизация планировщика: random_page_cost для SSD, параметры параллельных запросов
  7. Настройка checkpoint и WAL под диск (SSD/HDD)
  8. Мониторинг hit rate и pg_buffercache после изменений
  9. Документация внесённых изменений
  10. Гарантия 30 дней: если производительность не улучшилась — пересмотрим настройки бесплатно

Тюнинг параметров памяти

Как настроить shared_buffers для OLTP?

Общий кэш страниц базы для всех процессов. Для выделенного сервера — 25% RAM. На сервере с 32 ГБ это 8 ГБ. Больше 25% может привести к конфликту с кэшем ОС. Проверить, хватает ли shared_buffers, можно по hit rate: если cache_hit_ratio < 99% — либо shared_buffers мал, либо рабочий набор не помещается в память. Используйте pg_buffercache, чтобы увидеть, какие таблицы и индексы занимают буфер. Увеличивайте shared_buffers до 25% RAM, но не более 8 ГБ на Linux из-за архитектурных ограничений.

Что делать при низком cache hit ratio?

Если cache_hit_ratio ниже 99%, это сигнал к тюнингу. Проверьте shared_buffers — возможно, нужно увеличить. Также может помочь добавление индексов. Для аналитических запросов рассмотрите увеличение work_mem. Используйте запрос из code-блока для проверки hit rate.

Почему маленькое work_mem часто лучше большого

work_mem — память для каждой сортировки / hash join в одном запросе. Если запрос имеет 3 sort node, он может занять 3 × work_mem. При 100 параллельных соединениях с тяжёлыми запросами потребление может быть 100 × 3 × work_mem. Слишком большое значение вызовет swap. Типичная ошибка — установить 64 МБ глобально, тогда как 100 соединений с 4 сортировками = 100 × 4 × 64 МБ = 25,6 ГБ. Начинайте с 16 МБ, увеличивайте для конкретных запросов через SET LOCAL. Для OLTP-нагрузки высокое work_mem ведёт к перерасходу памяти и падению производительности из-за свопинга. Наша методика: анализируем планы запросов, выявляем сортировки на диске, увеличиваем work_mem только для проблемных запросов.

effective_cache_size: простая подсказка планировщику

Подсказка планировщику о доступном кэше ОС + shared_buffers. Для сервера с 32 ГБ: 24 ГБ. Влияет на выбор между index scan и seq scan. Не резервирует память, но критически важен для правильного выбора плана. Более детально — в официальной документации PostgreSQL. Рекомендуемая установка — 75% от RAM.

maintenance_work_mem: для операций обслуживания

Для VACUUM, CREATE INDEX, ALTER TABLE. Повышайте только во время обслуживания. Значение 2 ГБ подходит для большинства задач. Не держите высоким постоянно — это спасёт память.

Как настроить планировщик и мониторинг производительности

Стоимостные параметры и параллельные запросы

# Cost model for SSD
random_page_cost = 1.1    # SSD: 1.1, HDD: 4.0 (дефолт)
seq_page_cost    = 1.0

# Parallel queries (PostgreSQL 9.6+)
max_parallel_workers_per_gather = 4
max_parallel_workers = 8
parallel_tuple_cost  = 0.1
parallel_setup_cost  = 1000.0

Мониторинг hit rate и буферного кэша

-- Cache hit ratio
SELECT
    sum(heap_blks_hit)  AS heap_hit,
    sum(heap_blks_read) AS heap_read,
    round(
        sum(heap_blks_hit)::numeric /
        nullif(sum(heap_blks_hit) + sum(heap_blks_read), 0) * 100, 2
    ) AS cache_hit_ratio
FROM pg_statio_user_tables;

-- Buffer usage details
CREATE EXTENSION IF NOT EXISTS pg_buffercache;
SELECT c.relname, count(*) AS buffers,
       round(count(*) * 8192.0 / 1024 / 1024, 1) AS size_mb
FROM pg_buffercache b
JOIN pg_class c ON b.relfilenode = c.relfilenode
GROUP BY c.relname
ORDER BY buffers DESC
LIMIT 20;

Если cache_hit_ratio < 99% — требуется тюнинг shared_buffers или добавление индекса.

Тюнинг под нагрузку: OLTP, аналитика, смешанная

Checkpoint и WAL

checkpoint_completion_target = 0.9
checkpoint_timeout = 15min
max_wal_size = 4GB
fsync = on
synchronous_commit = on

Профили нагрузки: сравнение настроек

Параметр Web OLTP Аналитика Смешанная
work_mem 4–16 МБ 256 МБ – 1 ГБ 16–64 МБ
shared_buffers 25% RAM 15% RAM 20% RAM
max_parallel_workers_per_gather 2 4+ 2–4
Дополнительно PgBouncer Реплика для отчётов PgBouncer + реплика

Практический пример: оптимизация сортировки

Запрос медленно выполняет ORDER BY по большой таблице — сортировка идёт через временный файл на диске:

EXPLAIN (ANALYZE, BUFFERS, FORMAT TEXT)
SELECT * FROM events
WHERE user_id = 1
ORDER BY created_at DESC
LIMIT 100;

Если в выводе "Sort Method: external merge Disk: 45678kB" — нужен индекс или больше work_mem.

CREATE INDEX CONCURRENTLY idx_events_user_date
  ON events(user_id, created_at DESC)
  INCLUDE (id, event_type, payload);

Применение изменений

Параметр Требует перезапуска
shared_buffers Да
max_connections Да
work_mem Нет (RELOAD)
effective_cache_size Нет
checkpoint_timeout Нет
random_page_cost Нет
max_parallel_workers Нет

После изменения параметров выполните SELECT pg_reload_conf(); для применения.

Типичные ошибки при настройке PostgreSQL

Ошибка Последствия Решение
Слишком высокий work_mem глобально Swap, падение производительности Начинать с 16 МБ, увеличивать для конкретных запросов
shared_buffers > 25% RAM Конфликт с кэшем ОС Держать не более 25% RAM
Неверный random_page_cost для SSD Планировщик недооценивает index scan Установить 1.1 для SSD
Игнорирование autovacuum Bloat, ухудшение производительности Настроить autovacuum параметры

Заключение

Правильная настройка PostgreSQL даёт значительный прирост производительности и экономию на инфраструктуре. Мы гарантируем улучшение не менее 30% или бесплатно пересмотрим конфигурацию в течение 30 дней. Свяжитесь с нами для консультации и закажите профессиональный тюнинг PostgreSQL.

Услуги бэкенд-разработки: Laravel, Node.js, Go, Django, PostgreSQL

На production-сервере в 3:14 ночи очередь Laravel Jobs перестала обрабатываться. 40 000 необработанных задач в Redis. Причина: worker упал из-за memory leak в одном из Jobs (утечка через статическую переменную в Eloquent observer), supervisor не перезапустил его из-за misconfigured stopwaitsecs. Это не гипотетический сценарий — это вторник. Мы разбирали такой инцидент на проекте с нагрузкой 500 RPS: диагностика заняла 4 часа, фикс — 20 минут. Чтобы вы не теряли деньги на простоях, предлагаем услуги бэкенд-разработки с акцентом на production-grade надёжность. Оценим ваш проект за 2 дня.

Backend — это то, что работает когда никто не смотрит. Или не работает. Гарантируем, что у вас будет первый вариант.

Что мы делаем с первого дня правильно

Service Layer поверх Fat Controllers. Controller получает HTTP-запрос, валидирует его через Form Request, передаёт данные в Service, возвращает ответ. Бизнес-логика в Service, не в Controller. Это звучит банально, но большинство legacy-проектов — это контроллеры по 500 строк с SQL-запросами внутри.

Repository Pattern используем осторожно. Если вы просто оборачиваете Model::where(...) в метод репозитория — это бойлерплейт без пользы. Repository оправдан когда: нужно абстрагироваться от источника данных (БД + кеш + внешний API) или когда логика запросов достаточно сложна для изоляции.

Jobs, Events, Listeners. Всё, что можно сделать асинхронно — делаем асинхронно. Отправка email, генерация PDF, синхронизация с внешним API, пересчёт агрегатов — в Queue. Laravel Horizon для мониторинга очередей в Redis: видно throughput, failed jobs, время обработки по очередям.

Как Octane справляется с высокой нагрузкой

Laravel Octane с RoadRunner или Swoole держит приложение в памяти между запросами — убирает overhead bootstrap (загрузка конфигов, автозагрузка классов) на каждый HTTP-запрос. Прирост: 3–8x на синтетических бенчмарках, 2–4x на реальных приложениях. Важно: нельзя хранить состояние между запросами в статических переменных — это приводит именно к таким инцидентам, как в начале. Применяем это в проектах с >1000 RPS.

Что делать с N+1 запросами

N+1 — самая распространённая причина медленных страниц в Laravel-приложениях. Стандартная история: страница работала нормально на dev с 10 записями, на production с 10 000 — 8-секундная загрузка.

Laravel Debugbar в dev-окружении показывает количество запросов на страницу. Более 20 запросов на одну страницу — сигнал для audit.

Model::preventLazyLoading(! app()->isProduction());

Telescope для профилирования в staging: логирует все запросы, jobs, mail, notifications с детализацией по времени. Цифры: после внедрения eager loading время загрузки страницы падает с 8 с до 0.3 с — в 27 раз.

PostgreSQL: индексы, которые реально нужны

PostgreSQL 14+ — основная БД на всех проектах. Используем связку PgBouncer + PostgreSQL. Опыт 10+ лет, более 50 backend-проектов, 5 лет на рынке.

Как PostgreSQL помогает избежать медленных запросов

Composite indexes для частых WHERE + ORDER BY. Если у вас WHERE user_id = ? AND status = ? ORDER BY created_at DESC — нужен (user_id, status, created_at DESC). Индекс по (user_id) отдельно плохо помогает с сортировкой.

Partial indexes. Если 95% запросов идут по WHERE status = 'active':

CREATE INDEX idx_orders_active ON orders (created_at DESC)
WHERE status = 'active';

Индекс маленький, быстрый, покрывает основную нагрузку.

GIN-индексы для JSONB и массивов. @> оператор без GIN-индекса — seq scan. С индексом — быстро даже на миллионах записей.

GIN для full-text search. to_tsvector + GIN вместо LIKE '%query%'. LIKE без индекса — всегда seq scan. С pg_trgm extension и gin_trgm_ops — поддержка LIKE с индексом, полезно для CRM-поиска по частичному совпадению.

Connection pooling: почему важнее чем кажется

Rails, Laravel, Django открывают новое соединение с PostgreSQL на каждый PHP/Python процесс. На 100 воркерах — 100 соединений. PostgreSQL начинает деградировать от 200–300 активных соединений — overhead на управление соединениями становится значительным.

PgBouncer — connection pooler перед PostgreSQL. Режим transaction pooling: соединение с PostgreSQL занято только на время транзакции, между запросами возвращается в пул. 1000 приложений-воркеров → 20–50 реальных соединений к PostgreSQL. Это снижает latency на 40% и уменьшает затраты на хостинг на 30%.

Node.js с Fastify: когда это лучше Laravel

Node.js оправдан для:

  • Realtime: WebSocket-серверы, Server-Sent Events, чат, live-обновления
  • Streaming: большие файлы, видео, данные потоком
  • High I/O concurrency: много параллельных запросов к внешним API без тяжёлой бизнес-логики
  • Serverless: Lambda/Cloud Functions — Node.js стартует быстрее PHP

Fastify вместо Express: в 2–3 раза быстрее на benchmarks, встроенная JSON Schema валидация, лучшая TypeScript поддержка, plugin-архитектура.

Типичная архитектура realtime: Laravel — основная бизнес-логика и REST API. Node.js + Socket.io или ws — WebSocket сервер. Laravel публикует события в Redis Pub/Sub, Node.js подписывается и транслирует клиентам. Это разделение позволяет масштабировать WebSocket-сервер независимо от основного приложения.

Go: микросервисы и высокая нагрузка

Go используем для:

  • Высоконагруженных микросервисов (> 10 000 RPS)
  • Фоновых воркеров с жёсткими требованиями к latency
  • Инструментов DevOps и CLI
  • gRPC-сервисов в микросервисной архитектуре

Goroutines — дешевле OS-потоков в тысячи раз. 10 000 конкурентных соединений на Go — норма на одном сервере.

Но Go — не волшебная таблетка. Разработка медленнее чем на Laravel: больше бойлерплейта, нет ORM уровня Eloquent, обработка ошибок через if err != nil везде. Оправдан только когда производительность — реальное требование, не предположение.

Django и Python backend

Django с DRF (Django REST Framework) — для задач где нужен Python: ML-пайплайны, обработка данных, интеграции с AI-инструментами.

Celery для фоновых задач — аналог Laravel Queue, но сложнее в конфигурации. Celery Beat для cron-задач.

Django ORM vs raw SQL: ORM удобен для CRUD. Для аналитических запросов с несколькими JOIN, оконными функциями и CTE — connection.execute() с raw SQL читаемее и предсказуемее.

Redis: не только кеш

Redis в наших проектах выполняет несколько ролей:

Роль Детали
Кеш Кеширование результатов тяжёлых запросов, фрагментов HTML
Очереди Backend для Laravel Queue / Celery
Session store Distributed sessions в multi-instance окружении
Pub/Sub Realtime события между сервисами
Rate limiting Sliding window counters для API throttling
Leaderboards Sorted Sets для рейтингов

Redis Cluster для горизонтального масштабирования. Sentinel для автоматического failover на standalone установках.

Деплой и инфраструктура

Docker + docker-compose — стандарт для локальной разработки и production. Каждый сервис в контейнере: PHP-FPM/Octane, Nginx, PostgreSQL, Redis, Queue Worker, Scheduler.

CI/CD через GitHub Actions:

  1. Прогон тестов (PHPUnit / Pest, Vitest, Playwright)
  2. Сборка Docker-образа
  3. Push в Container Registry
  4. Deploy: docker pull → docker-compose up -d на сервере, или Kubernetes rolling update

Zero-downtime deploy для Laravel: php artisan down --secret=TOKEN не нужен при правильной настройке. Стратегия: новый контейнер стартует рядом со старым, Nginx переключает трафик после health check, старый контейнер останавливается.

Мониторинг: Sentry для exception tracking с alerting в Slack/Telegram. Grafana + Prometheus (или Grafana Cloud) для метрик: CPU, memory, request rate, queue depth, database connection count. Алерт на: error rate > 1%, p99 latency > 2s, queue depth > 1000 jobs.

Что входит в работу под ключ

  • Архитектурное проектирование (документация API, схема БД, диаграмма сервисов)
  • Реализация по согласованному ТЗ с code review
  • Настройка CI/CD, мониторинга, алертинга
  • Нагрузочное тестирование (k6, wrk) с отчётом
  • Передача исходников, доступов, инструкция по деплою
  • Обучение команды заказчика (2-3 сессии)
  • Гарантийная поддержка 1 месяц после сдачи

Ориентиры по срокам

Задача Срок
REST API для мобильного/SPA (средняя сложность) 6–12 недель
Backend со сложной бизнес-логикой + интеграции 12–20 недель
Высоконагруженный сервис на Go 8–16 недель
Миграция legacy PHP на Laravel 16–32 недели

Стоимость рассчитывается индивидуально после анализа требований к нагрузке, интеграциям и бизнес-логике. Типичный бюджет backend-проекта — от 500 000 до 2 000 000 рублей в зависимости от сложности. Свяжитесь с нами для бесплатного аудита вашего текущего backend — получите план оптимизации за 2 дня. Закажите консультацию.