Сколько RAM нужно для Windmill
Windmill превращает скрипты на Python, TypeScript, Go и Bash во внутренние инструменты и workflow — но при самостоятельном хостинге быстро выясняется, что документация даёт скорее общие ориентиры, чем чёткий ответ на вопрос «сколько RAM закладывать». Windmill — это не один процесс, а связка сервера, очереди в Postgres и воркеров, каждый из которых запускает ваш код в отдельном изолированном окружении. Разбираемся, из чего складывается реальный расход памяти и какой сервер брать, чтобы скрипт с pandas не укладывал контейнер по OOM в первую же неделю.
Содержание
- Короткий ответ: сколько RAM нужно для Windmill
- Из чего состоит Windmill и куда уходит память
- Почему воркер — это не фиксированный расход, а переменная нагрузка
- Docker Compose: рабочая конфигурация и что реально экономит память
- Тяжёлые джобы: Python с pandas/ML и headless-браузер
- Какой сервер взять в MAATRIX под Windmill
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →Короткий ответ: сколько RAM нужно для Windmill
Цифры ниже — не измеренный бенчмарк конкретной версии, а оценка по архитектуре стека (Rust-сервер, воркеры на изолированных процессах-исполнителях, PostgreSQL как база данных и очередь одновременно). Точное потребление у вас будет отличаться в зависимости от языков скриптов, тяжести библиотек и числа параллельных запусков.
| Сценарий | RAM | vCPU | Диск | Риск на шаг ниже |
|---|---|---|---|---|
| Тест, пара скриптов на Bash/TypeScript, редкие запуски | 2 ГБ | 1–2 | 25 ГБ NVMe | Postgres + сервер + один воркер уже съедают большую часть 1 ГБ на старте |
| Рабочий инстанс: 10–20 workflow, вебхуки и расписания | 4 ГБ | 2 | 40 ГБ NVMe | параллельные Python-джобы с тяжёлыми библиотеками начинают конкурировать за память |
| Продакшен: несколько воркеров, команда в редакторе | 8 ГБ | 4 | 80 ГБ NVMe | всплеск параллельных Python-джобов (pandas, requests, ML-пакеты) даёт OOM у воркера |
| Много воркеров, ML-скрипты, headless-браузер (Playwright) | 16 ГБ и выше | 6–8 | 120–160 ГБ NVMe | браузерные джобы и загрузка тяжёлых моделей дают резкие пики поверх базовой нагрузки |
Главный вывод из таблицы: сам сервер Windmill в простое лёгкий — это первые 200–400 МБ. Основной расход памяти определяют не количество workflow, а язык и библиотеки скриптов внутри них, а также сколько джобов выполняется параллельно.
Из чего состоит Windmill и куда уходит память
При self-hosted установке через docker-compose вы поднимаете несколько разных сервисов, и у каждого своя роль в потреблении RAM:
| Компонент | Роль | Ориентировочный расход |
|---|---|---|
| windmill_server | API, веб-интерфейс, авторизация | 150–250 МБ в покое |
| windmill_worker (контейнер) | Забирает джобы из очереди, запускает рантайм под каждый скрипт | 100–200 МБ база + пики на джобу |
| windmill_lsp (опционально) | Автодополнение в редакторе кода | 100–200 МБ, только для UI-редактора |
| PostgreSQL | Хранит скрипты и историю, служит очередью через LISTEN/NOTIFY | 200–400 МБ на дефолте, растёт с историей |
| caddy / nginx | Реверс-прокси | 10–30 МБ |
Важная особенность архитектуры: Postgres в Windmill — не просто хранилище, а ещё и очередь заданий. Это упрощает стек (не нужен отдельный Redis, как у части конкурентов), но означает, что база нагружается сильнее при частых коротких джобах, которые постоянно пишут и читают статус.
Официальный docker-compose поднимает несколько реплик воркера сразу (обычно 2–3). Если урезаете память сервера, уменьшите число реплик до одной-двух под свою нагрузку, а не оставляйте дефолт «на всякий случай».
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверПочему воркер — это не фиксированный расход, а переменная нагрузка
Ключевая вещь, которую нужно понять про Windmill: воркер в состоянии простоя занимает немного, но при получении джобы поднимает изолированный процесс-исполнитель под конкретный язык, и именно этот процесс определяет реальный аппетит по памяти:
- Bash-скрипты — самые лёгкие джобы, обычно укладываются в десятки мегабайт сверх базового веса воркера.
- TypeScript/Deno-скрипты — рантайм Deno стартует быстро и держит умеренный footprint, обычно заметно легче, чем Python с тяжёлыми зависимостями.
- Python-скрипты — самый непредсказуемый случай. Простой скрипт с
requests— это одно, скрипт, импортирующийpandas,numpyили ML-библиотеку, — совсем другое: загрузка самих библиотек в память может занимать сотни мегабайт ещё до того, как скрипт начал реально работать с данными. - Go-скрипты — компилируются перед выполнением, потребление памяти в момент компиляции может кратковременно превышать потребление во время самого выполнения.
Практический вывод: если несколько джобов на Python с тяжёлыми зависимостями срабатывают параллельно (например, по расписанию в одну и ту же минуту), каждая тянет свою копию загруженных библиотек — память не переиспользуется между изолированными процессами. Это тот же принцип, что и у песочниц в Activepieces или у выполнения кода в n8n: платформы для автоматизации изолируют выполнение по соображениям безопасности, и это осознанная плата памятью за то, что чужой код не может уронить основной процесс.
Ограничение конкурентности — не опциональная настройка, а обязательная на сервере с ограниченной памятью. В Windmill это делается через worker_group и max_concurrency в UI администратора: без лимита всплеск параллельных срабатываний по расписанию способен выесть всю доступную RAM за секунды, и dmesg -T | grep -i "out of memory" покажет классический OOM-килл по cgroup-лимиту.
Docker Compose: рабочая конфигурация и что реально экономит память
Официальный self-hosted вариант Windmill разворачивается docker-compose с сервером, воркерами и Postgres. Ниже упрощённый каркас — конкретные переменные окружения и версию образа сверяйте с актуальным docker-compose.yml в репозитории проекта на момент установки, между релизами они меняются:
services:
db:
image: postgres:16-alpine
restart: unless-stopped
mem_limit: 768m
shm_size: 1g
environment:
- POSTGRES_PASSWORD=${DB_PASSWORD}
- POSTGRES_DB=windmill
volumes:
- db_data:/var/lib/postgresql/data
windmill_server:
image: ghcr.io/windmill-labs/windmill:main
restart: unless-stopped
mem_limit: 512m
environment:
- DATABASE_URL=postgres://postgres:${DB_PASSWORD}@db/windmill?sslmode=disable
- MODE=server
- BASE_URL=https://your-domain.example
depends_on:
- db
windmill_worker:
image: ghcr.io/windmill-labs/windmill:main
restart: unless-stopped
mem_limit: 1g
environment:
- DATABASE_URL=postgres://postgres:${DB_PASSWORD}@db/windmill?sslmode=disable
- MODE=worker
- WORKER_GROUP=default
deploy:
replicas: 2
depends_on:
- db
volumes:
db_data:
Реверс-прокси (caddy или nginx) добавьте отдельным сервисом с mem_limit: 64m — на общий расход RAM он почти не влияет.
Что реально снижает потребление на практике:
- Число реплик воркера под реальную нагрузку. На сервере до 4 ГБ начните с одной реплики вместо дефолтных 2–3 и добавляйте по мере необходимости, следя за очередью джобов в UI.
mem_limitна каждом сервисе. Без лимита один воркер, поймавший тяжёлый Python-скрипт, может выесть память у Postgres — а вместе с ним упадёт вся очередь задач, а не только одна джоба.max_concurrencyна уровне worker group. Лимит одновременных джобов на воркер защищает от одновременного срабатывания нескольких cron-триггеров с тяжёлыми Python-скриптами.- LSP-контейнер только при необходимости. Если команда редактирует скрипты через локальный IDE и синхронизирует их CLI или через Git, отключите
windmill_lsp— освобождает 100–200 МБ без потери функциональности выполнения. - Регулярная чистка истории выполнений. Таблицы логов в Postgres растут с каждым запуском джобы — настройте retention в политике хранения completed jobs, иначе база начнёт просить больше памяти под кеш планов запросов.
Отдельный момент — Postgres в Windmill одновременно хранилище и очередь заданий через LISTEN/NOTIFY, поэтому на неё стоит смотреть внимательнее, чем на «обычную» базу под CRUD-приложение: при частых коротких джобах (например, десятки cron-задач раз в минуту) растёт число транзакций и обновлений статуса, а не только объём данных. Отправная точка для shared_buffers — около четверти RAM сервера, но если Postgres на 8 ГБ живёт рядом с двумя-тремя воркерами, часть этой доли стоит сдвинуть в пользу приложений. Проверьте и shm_size контейнера — дефолтные 64 МБ у Docker могут ограничивать параллельные сортировки при заметной истории выполнений, в примере выше он расширен до 1 ГБ.
Тяжёлые джобы: Python с pandas/ML и headless-браузер
Если в workflow есть Python-скрипты с анализом данных (pandas, numpy, scikit-learn) или задачи с headless-браузером через Playwright, закладывайте память отдельно от базового расчёта по количеству workflow:
- Импорт тяжёлых библиотек сам по себе занимает память ещё до обработки данных — это фиксированная плата за каждый запуск такого скрипта, и она не уменьшается от того, что датасет маленький.
- Playwright-джобы поднимают отдельный процесс браузера внутри воркера — это кратно тяжелее обычного скрипта, ориентируйтесь минимум на несколько сотен мегабайт на одну активную сессию и не запускайте больше одной-двух параллельно на воркере с 1 ГБ лимита.
- Кеширование зависимостей между запусками экономит время и диск, но не RAM — сами библиотеки всё равно загружаются в память процесса при каждом выполнении джобы.
Практическая рекомендация: если часть скриптов в проекте — тяжёлые Python/ML или браузерные джобы, вынесите под них отдельную worker group с собственным mem_limit и жёстким max_concurrency, отдельно от лёгких Bash/TypeScript-скриптов, — это не даёт одному тяжёлому workflow ронять всю очередь лёгких задач при пике нагрузки.
Какой сервер взять в MAATRIX под Windmill
Честный минимум для рабочего инстанса — 2 vCPU, 4 ГБ RAM, 40 ГБ NVMe. На таком сервере Windmill держит десяток-другой несложных workflow, но при первом всплеске параллельных Python-джобов с тяжёлыми зависимостями стоит заранее выставить max_concurrency, иначе воркер уйдёт в OOM.
Комфортный вариант для продакшена с несколькими воркерами и активной командой в редакторе — 4 vCPU, 8 ГБ RAM, 80 ГБ NVMe. Такой запас держит Postgres с растущей историей выполнений, пару воркеров с разумной конкурентностью и оставляет место под ночные cron-пики без постоянного мониторинга. Если в проекте много ML-скриптов или Playwright-джобов — смотрите в сторону 16 ГБ и выше; похожая логика разбора нагрузки есть в статье про требования к RAM для n8n — архитектурно это близкий класс задач.
Локация зависит от того, куда смотрят ваши workflow. Если скрипты дёргают зарубежные API (платёжные шлюзы, SaaS-интеграции, модели через внешние API) — берите Лондон или США: прямые соединения без прокси и без риска, что зависший внешний запрос будет держать память воркера дольше из-за таймаутов на нестабильном канале. Если workflow работают с российскими сервисами и обрабатывают персональные данные — оправдан российский дата-центр под требования 152-ФЗ.
Оплата — картами российских банков, по СБП, криптовалютой или токеном MAAT, доступна на всех локациях без иностранной карты. Про правильный расчёт запаса памяти в целом — в статье сколько RAM закладывать с запасом, про настройку лимитов контейнеров — в разборе лимитов CPU и памяти в Docker. Не уверены, какая конфигурация нужна — напишите, сколько workflow и какие языки скриптов используете, подберём сервер под нагрузку.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверНужны сами нейросети для контента?
Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.
Частые вопросы
Хватит ли 2 ГБ RAM для Windmill?
Для теста с парой лёгких скриптов — да, запустится. Для рабочей нагрузки с Python-джобами и параллельными срабатываниями — нет: Postgres, сервер и воркер вместе уже занимают большую часть памяти в простое, и первый же всплеск параллельных джобов приведёт к OOM.
Почему Windmill ест больше памяти, чем ожидалось, при небольшом числе workflow?
Дело почти всегда не в количестве workflow, а в языке и зависимостях скриптов внутри них и в параллельности запуска. Один workflow с тяжёлым Python-скриптом на pandas способен занять больше памяти, чем десять простых Bash-скриптов вместе.
Нужен ли отдельный сервер под Postgres, если он служит и очередью?
На нагрузке уровня 10–20 workflow — нет, всё нормально уживается на одной машине с mem_limit на каждый контейнер. Разносить базу имеет смысл, когда джобы становятся настолько частыми, что Postgres сам становится узким местом по диску и CPU.
Сколько воркеров запускать по умолчанию?
Меньше, чем в дефолтном docker-compose (обычно 2–3 реплики). На сервере до 4 ГБ начните с одного воркера и добавляйте по мере роста очереди — простаивающие реплики просто занимают базовую память без пользы.
Спасёт ли swap от редких падений на тяжёлых Python-джобах?
Как разовая страховка от единичного пика — да. Как постоянный режим — нет: свопинг во время загрузки тяжёлых библиотек резко увеличивает время выполнения джобы, и вы получите таймауты вместо честного падения по памяти. Подробнее — в статье про правильный размер swap для VPS.
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →