MAATRIX / Блог / Сколько RAM нужно для Kong Gateway

Сколько RAM нужно для Kong Gateway

MAATRIX

Kong Gateway ставят перед микросервисами ради единой точки входа: аутентификация, лимиты запросов, логирование и маршрутизация в одном месте. Проблема в том, что документация Kong почти ничего не говорит про память — только общие фразы вроде «зависит от нагрузки». В итоге кто-то ставит шлюз на 512 МБ и получает OOM при первом всплеске трафика, а кто-то берёт 16 ГБ «на всякий случай» и переплачивает. Разберём, из чего на самом деле складывается потребление RAM у Kong и как посчитать нужный объём под свою конфигурацию.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →

Из чего складывается потребление памяти

Kong построен поверх OpenResty — это nginx со встроенным LuaJIT. Сам процесс Kong запускает несколько worker-процессов nginx, и именно они выполняют весь код: маршрутизацию, плагины, проксирование. Это ключевой момент для расчёта памяти: каждый worker — это отдельный процесс со своей копией Lua-состояния.

Что реально ест память:

  • Базовый процесс nginx/OpenResty — сам по себе занимает немного, порядка нескольких десятков мегабайт на worker в простое (точные цифры зависят от версии Kong и ОС, ориентируйтесь на это как на грубую отправную точку, а не как на гарантию).
  • Конфигурация маршрутов и сервисов — таблицы routes, services, upstreams, plugins загружаются в память каждого worker'а. Чем больше у вас services/routes и чем сложнее конфиги плагинов, тем больше памяти уходит на каждую копию.
  • Shared dict (lua_shared_dict kong_db_cache) — это общая для всех workers область памяти (mmap), используется для кэша ответов БД. Задаётся параметром mem_cache_size (по умолчанию 128m). Она не умножается на число workers, но выделяется целиком независимо от того, используется ли она полностью.
  • Соединения — каждое активное соединение (клиент → Kong, Kong → upstream) держит буферы. При worker_connections в тысячи одновременных соединений это уже заметная величина, особенно с keepalive к апстримам.
  • Плагины — Lua-код плагинов выполняется в контексте worker'а, некоторые плагины держат собственные буферы (логирование, метрики) или локальные кэши (JWT, ключи API).
  • PostgreSQL (если используется) — это отдельный процесс со своим потреблением памяти, который часто забывают посчитать, оценивая только Kong.

Из этого следует главный вывод: память Kong растёт не линейно от «числа юзеров», а от количества worker-процессов, размера конфигурации (routes/plugins) и количества одновременных соединений. Тюнинг чаще всего сводится к работе с этими тремя параметрами.

DB-less vs Kong с PostgreSQL: разница в требованиях

Kong умеет работать в двух принципиально разных режимах, и они по-разному нагружают память.

DB-less (декларативный режим). Конфигурация — это YAML/JSON-файл (kong.yml), который Kong загружает при старте и держит целиком в памяти каждого worker'а. Нет обращений к БД на каждый запрос, нет отдельного процесса Postgres — это минимальный по памяти вариант. Подходит для статичной или редко меняющейся конфигурации маршрутов, для CI/CD-пайплайнов, где конфиг генерируется и деплоится целиком.

Минус: изменения применяются только через полную перезагрузку конфига (kong reload или POST на /config через Admin API), и весь YAML грузится в память каждого worker'а — при очень большом количестве routes (тысячи) это заметная добавка к базовому потреблению.

Режим с БД (PostgreSQL). Конфигурация хранится в PostgreSQL, Kong обращается к БД через Admin API для изменений и кэширует прочитанные данные в shared dict (mem_cache_size). Это гибче — можно менять маршруты на лету через API без перезапуска — но добавляет:

  • отдельный процесс PostgreSQL со своими требованиями к памяти (shared_buffers, work_mem и т.д. — подробнее в статье про тюнинг PostgreSQL);
  • сетевые обращения Kong → Postgres при промахах кэша;
  • необходимость резервировать память под сам Postgres отдельно от Kong, даже если они на одном сервере.

Для большинства небольших и средних проектов, где набор API стабилен и не меняется по десять раз в день, DB-less экономит и память, и одну точку отказа (нет БД — нечему падать). Если нужен self-service через Admin API для десятков команд — режим с Postgres оправдан, но тогда сразу закладывайте память на связку, а не только на Kong.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Сколько RAM закладывать: ориентиры по нагрузке

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

СценарийРежимvCPURAMКомментарий
Разработка/тест, до 10 routesDB-less1512 МБ – 1 ГБХватает с запасом, но без буфера под всплески
Небольшой прод, до ~50 routes, 2-3 плагина на сервисDB-less22 ГБКомфортный минимум для боевого шлюза
Средний прод, Kong + Postgres на одном сервереБД2-44 ГБИз них ~1-1.5 ГБ уходит под Postgres
Средняя нагрузка, много плагинов (auth+rate-limit+logging+CORS), высокий RPSБД, отдельная от Postgres48 ГБPostgres лучше вынести на отдельный сервер
Hybrid-режим, несколько data plane нодБД (control plane)4-88-16 ГБ на нодуControl plane отдельно, data plane масштабируется горизонтально

Это ориентиры, а не гарантированные цифры — реальное потребление зависит от вашего набора плагинов и профиля трафика. Проверяйте фактическое потребление через docker stats или /status эндпоинт Kong в первую неделю после запуска и корректируйте план по факту.

Общее правило: сомневаетесь между двумя тарифами — берите тот, что больше, но по возможности разносите Kong и PostgreSQL по разным серверам уже на среднем прод-масштабе. Общий сервер экономит на старте, но при пиковой нагрузке Postgres и Kong начинают конкурировать за память и I/O одновременно, а понять, кто именно вызвал деградацию, становится сложнее.

Как плагины увеличивают потребление памяти

Плагины — самая недооценённая статья расхода RAM в Kong. Каждый включённый плагин добавляет Lua-код, который выполняется в каждом worker'е на каждый проходящий через него запрос, и часто держит собственное состояние.

Наиболее прожорливые категории:

  • Rate limiting (rate-limiting, rate-limiting-advanced) — если политика local, счётчики хранятся в памяти worker'а (shared dict), что дёшево. Если политика redis — добавляется сетевой клиент к Redis плюс буферы соединений; сам Redis тоже требует памяти под счётчики (см. частые проблемы Redis на сервере, если решите вынести туда состояние лимитов).
  • Аутентификация (jwt, key-auth, oauth2, ldap-auth) — держат кэш ключей/учётных данных в shared dict, декодирование JWT на каждый запрос создаёт временные Lua-таблицы (GC их подчищает, но под нагрузкой это добавляет работу сборщику мусора и пиковое потребление).
  • Логирование (http-log, tcp-log, file-log, datadog, prometheus) — буферизуют записи перед отправкой во внешнюю систему; при батчинге с большими буферами и медленном приёмнике буферы могут расти.
  • Трансформации тела запроса/ответа (request-transformer, response-transformer) — временно держат в памяти тело запроса целиком для модификации, что при больших payload (загрузка файлов через API) заметно увеличивает пиковое потребление на worker.
  • CORS, IP restriction, bot-detection — лёгкие по памяти, минимальный оверхед на запрос.

Практический вывод: если на каждый сервис висит 4-5 плагинов, включая rate-limiting и логирование во внешнюю систему, закладывайте на 30-50% больше базового расчёта — это грубая эвристика, точную добавку даст только нагрузочный тест на вашей конфигурации.

Настройка worker_processes и защита от OOM

Число worker-процессов напрямую умножает часть потребления памяти — конфигурация routes/plugins копируется в каждый worker. По умолчанию Kong ставит nginx_worker_processes: auto, что равно числу доступных ядер CPU.

Если сервер небольшой (2 vCPU), а конфигурация Kong тяжёлая (сотни routes, много плагинов), можно осознанно ограничить число workers, чтобы не плодить лишние копии конфигурации:

# kong.conf
nginx_worker_processes = 2
mem_cache_size = 256m

Или через переменные окружения в Docker:

KONG_NGINX_WORKER_PROCESSES=2
KONG_MEM_CACHE_SIZE=256m

Обратный случай — на мощном сервере с 8+ ядрами и большим RPS, auto даст 8 workers, что увеличит throughput, но и суммарное потребление памяти. Здесь важно смотреть не на «сколько ядер есть», а на «сколько памяти доступно на копию конфигурации», и при необходимости зафиксировать число workers меньше числа ядер.

Второй рычаг — worker_connections (по умолчанию 16384 в свежих версиях Kong). Если у вас нет тысяч одновременных соединений, снижение параметра не даст экономии (память резервируется под структуры соединений лениво), но при десятках тысяч keepalive-соединений к апстримам это отдельная статья расхода.

Чтобы Kong не «съел» сервер целиком при утечке или всплеске трафика, ставьте hard-лимит на контейнер — это не даст Docker OOM killer убить произвольный процесс на хосте, а завершит именно контейнер Kong, который потом поднимет restart: unless-stopped. Подробно про лимиты CPU и памяти в Docker — в статье про лимиты ресурсов Docker.

Пример docker-compose с адекватными лимитами

Рабочий пример для DB-less режима на небольшом-среднем проекте — Kong с явными лимитами памяти и ограниченным числом workers:

services:
  kong:
    image: kong:3.8
    restart: unless-stopped
    environment:
      KONG_DATABASE: "off"
      KONG_DECLARATIVE_CONFIG: /kong/declarative/kong.yml
      KONG_PROXY_ACCESS_LOG: /dev/stdout
      KONG_ADMIN_ACCESS_LOG: /dev/stdout
      KONG_PROXY_ERROR_LOG: /dev/stderr
      KONG_ADMIN_ERROR_LOG: /dev/stderr
      KONG_ADMIN_LISTEN: 0.0.0.0:8001
      KONG_NGINX_WORKER_PROCESSES: "2"
      KONG_MEM_CACHE_SIZE: "128m"
    volumes:
      - ./kong.yml:/kong/declarative/kong.yml:ro
    ports:
      - "8000:8000"
      - "8443:8443"
      - "127.0.0.1:8001:8001"
    deploy:
      resources:
        limits:
          cpus: "2.0"
          memory: 2g
        reservations:
          memory: 512m

Если добавляете PostgreSQL (режим с БД), вынесите его в отдельный сервис с собственным лимитом и, по возможности, на отдельный диск:

  kong-database:
    image: postgres:16
    restart: unless-stopped
    environment:
      POSTGRES_USER: kong
      POSTGRES_DB: kong
      POSTGRES_PASSWORD: "замените-на-свой-пароль"
    volumes:
      - kong_pg_data:/var/lib/postgresql/data
    deploy:
      resources:
        limits:
          memory: 1.5g
        reservations:
          memory: 512m

volumes:
  kong_pg_data:

Порт Admin API (8001) вынесен на 127.0.0.1, чтобы не торчал наружу — вопрос безопасности, а не памяти, но раз пример боевой, отметить стоит.

После первой недели под реальным трафиком подключите мониторинг, чтобы видеть не гипотетические, а реальные цифры и вовремя пересмотреть лимиты — например, связкой Prometheus + Grafana, как описано в статье про настройку Grafana и Prometheus на Ubuntu 24.04. Плагин prometheus для Kong отдаёт метрики по каждому worker'у, включая память Lua VM — это точнее, чем любые прикидки.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Нужны сами нейросети для контента?

Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.

Частые вопросы

Хватит ли Kong на VPS с 1 ГБ RAM?

Для теста или разработки с DB-less режимом и небольшим числом routes — да, но без запаса на всплески трафика. Для боевого шлюза даже с минимальной нагрузкой закладывайте от 2 ГБ, особенно если планируете добавлять плагины позже.

Нужно ли выносить PostgreSQL на отдельный сервер?

На старте можно держать вместе, но при среднем и высоком RPS — да, выносите. Postgres и Kong оба чувствительны к задержкам диска и CPU, и на одном сервере они начинают конкурировать за ресурсы именно в момент пиковой нагрузки, когда это больнее всего.

DB-less или режим с БД — что выбрать для старта?

Если конфигурация маршрутов меняется редко (раз в дни/недели) — берите DB-less: меньше памяти, меньше точек отказа, конфиг версионируется в git. Режим с Postgres нужен, когда изменения должны применяться на лету через Admin API без деплоя.

Как понять, что Kong не хватает памяти?

Растущее время ответа под нагрузкой, ошибки 502/504 от самого Kong (не от апстрима), частые рестарты контейнера по OOM в логах Docker (docker inspect покажет OOMKilled: true). Первый шаг — посмотреть docker stats и логи, второй — поднять лимит и подключить Prometheus-метрики Kong для точной картины.

Влияет ли количество апстримов на память?

Да, но меньше, чем число routes и плагинов — в основном через keepalive-пул соединений к каждому апстриму. Если апстримов много (десятки-сотни) и держится keepalive, это заметная, но не доминирующая статья расхода по сравнению с плагинами.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →