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

Сколько RAM нужно для Grist

MAATRIX

Grist выглядит как обычная таблица, но под капотом у каждой колонки может быть формула на Python, а у каждого документа — своя SQLite-база и свой изолированный процесс для расчётов. Это удобно и безопасно, но именно эта архитектура определяет требования к памяти — и они не такие, как у типовых self-hosted инструментов, где один процесс обслуживает все данные разом. Разберём, куда уходит RAM в Grist, что на неё сильнее всего влияет и какой сервер брать под личный проект или команду.

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

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

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

Короткий ответ: сколько RAM нужно для Grist

Главный фактор — не объём данных, а число одновременно открытых документов. Каждый открытый документ поднимает отдельный процесс-песочницу для формул, и память считается по сумме этих процессов, а не по общему размеру базы на диске.

СценарийRAMvCPUДискЧто случится на шаг ниже
Личный проект, 1–2 документа, изредка открываются1–2 ГБ120 ГБ NVMeсервер поднимется, но первый же импорт CSV на пару тысяч строк ощутимо подтормозит
Небольшая команда, 3–5 активных документов одновременно2–4 ГБ230 ГБ NVMeпараллельное открытие нескольких документов разными людьми начинает конкурировать за память
Рабочий инстанс: 10+ документов, тяжёлые формулы, справочники между таблицами4–8 ГБ2–450–80 ГБ NVMeпересчёт больших формул на нескольких документах разом упирается в CPU и RAM одновременно
Команда с десятками пользователей и документами, активная работа целый день8–16 ГБ4100+ ГБ NVMeбез ограничения числа одновременных песочниц процессы начинают конкурировать за память сильнее, чем сама СУБД

Из таблицы видно ключевую разницу с классическими БД-инструментами вроде NocoDB или Baserow: там память в основном уходит в СУБД, а в Grist — в песочницы формул, которые запускаются на каждый открытый документ независимо.

Из чего складывается память Grist

Grist — приложение на Node.js (сервер, API, раздача фронтенда), но расчёт формул делает не Node, а отдельный песочницированный Python-процесс на каждый открытый документ. Это осознанное архитектурное решение: формулы пользователей — это произвольный код, и его нельзя выполнять в основном процессе сервера без изоляции.

Из чего набирается расход памяти:

Что грузитсяВклад в памятьКогда
Node.js-сервер, API, раздача статикибазовый процесс, обычно первые сотни мегабайтвсегда, сразу после старта
Песочница формул на документ (Python-интерпретатор + данные колонок, участвующих в формулах)отдельный процесс на каждый открытый документ, растёт с числом формул и объёмом задействованных данныхпока документ открыт хотя бы одной вкладкой
SQLite-файл документасам файл на диске не грузится в RAM целиком — читается постранично через SQL-движокпри любом обращении к документу
Импорт CSV/Excel в документпарсинг файла и построение структуры таблицы происходят в памяти до записи в SQLiteна импорт
Ссылки между документами (Reference на другую таблицу того же документа)пересчитываются вместе с остальными формулами, отдельного заметного вклада не даютна пересчёт формул
Домашний сервер (метаданные организаций, пользователей, прав доступа)лёгкий SQLite или PostgreSQL, вклад некритичный на фоне песочницвсегда

Вывод из таблицы простой: если у вас один документ и его открывает один человек — Grist лёгкий. Как только документов, открытых одновременно, становится десять — вы фактически получаете десять параллельных Python-процессов, и считать память нужно именно по ним, а не по «размеру базы».

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

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

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

Песочница для формул: от неё зависит половина потребления

У Grist есть несколько вариантов исполнения песочницы, которые задаются переменной окружения GRIST_SANDBOX_FLAVOR:

  • gvisor — используется по умолчанию в официальном Docker-образе на Linux amd64. Каждый документ получает процесс, изолированный через gVisor (user-space реализация части системных вызовов ядра). Даёт хорошую изоляцию, но у самого gVisor есть базовый оверхед на процесс — если у вас много одновременно открытых документов с небольшими формулами, часть памяти уходит именно на инфраструктуру песочницы, а не на сами вычисления.
  • pyodide — Python, скомпилированный в WebAssembly и запущенный внутри Node.js-процесса. Не требует поддержки gVisor со стороны ядра (актуально для части облачных окружений и не-amd64 архитектур), но платит за это тем, что WASM-рантайм сам по себе не бесплатен по памяти.
  • unsandboxed — формулы выполняются без изоляции, напрямую. Экономит память и CPU, но подходит только тогда, когда вы полностью доверяете всем, кто может писать формулы в документах — по сути, отключает одну из линий защиты. Для инстанса, доступного нескольким пользователям с разным уровнем доверия, брать не стоит.

Если сервер тянет несколько документов с тяжёлыми формулами (например, справочники с Reference-связями на тысячи строк и пересчётом по цепочке), закладывайте память с запасом именно под песочницы — это первое, что упрётся в лимит, раньше, чем сам Node-процесс или SQLite.

SQLite на документ: плюс и ограничение одновременно

В отличие от инструментов, где все таблицы живут в одной общей PostgreSQL или MySQL, Grist хранит каждый документ в своём файле SQLite. У этого решения есть прямые следствия для памяти и эксплуатации:

  • Документы не конкурируют за один и тот же файл на запись — блокировка SQLite актуальна в пределах одного документа, а не всего инстанса.
  • Резервное копирование становится проще: документ — это один файл, который можно скопировать, versioned бэкапом или синхронизировать отдельно, без дампа целой СУБД.
  • Обратная сторона: SQLite не умеет параллельно выполнять несколько тяжёлых запросов на запись в один документ так же хорошо, как клиент-серверная СУБД — если несколько человек одновременно правят большой документ с активными формулами, пересчёт может стать узким местом раньше, чем закончится память.
  • Память под сам SQLite-движок на документ небольшая — основная нагрузка всё равно приходится на Python-песочницу формул, а не на чтение файла.

Для сравнения: в NocoDB или Baserow все таблицы обычно лежат в одной внешней PostgreSQL, и там память в основном определяется размером кэша страниц СУБД. В Grist эта логика не работает — большой документ с простыми формулами может занимать меньше памяти, чем маленький документ с тяжёлыми формулами на связанных таблицах.

Docker Compose и переменные, которые держат память под контролем

Базовый рабочий конфиг для self-hosted Grist с ограничением памяти на контейнер:

services:
  grist:
    image: gristlabs/grist:latest
    restart: unless-stopped
    mem_limit: 4g
    environment:
      - PORT=8484
      - APP_HOME_URL=https://grist.example.com
      - GRIST_SANDBOX_FLAVOR=gvisor
      - GRIST_SESSION_SECRET=${GRIST_SESSION_SECRET}
      - GRIST_DEFAULT_EMAIL=admin@example.com
      - TYPEORM_DATABASE=/persist/home.sqlite3
    volumes:
      - grist-data:/persist
    ports:
      - "8484:8484"

volumes:
  grist-data:

Нюансы, о которые реально спотыкаются на практике:

  • mem_limit стоит выставлять сразу и с запасом — если открыть больше документов, чем закладывали, лишние песочницы упрутся в лимит контейнера, и Grist начнёт их выгружать или падать по OOM вместо аккуратной деградации. Общий подход к лимитам — в статье про лимиты CPU и памяти в Docker.
  • Если сервер не на Linux amd64 (например, ARM-инстанс) или gVisor недоступен в вашем окружении, GRIST_SANDBOX_FLAVOR=gvisor не запустится — переключайтесь на pyodide и проверяйте это до продакшена, а не после первого падения.
  • Том /persist обязателен — там лежат домашняя SQLite-база (TYPEORM_DATABASE) и файлы самих документов. Без volume пересоздание контейнера означает потерю всех документов.
  • Секреты вроде GRIST_SESSION_SECRET держите в .env-файле, а не в открытом docker-compose.yml, который может попасть в репозиторий.

Пошаговый разворот на чистом сервере — по общей схеме из статьи «Docker Compose для продакшена на Ubuntu 24.04», специфика Grist добавляется поверх неё.

Сколько документов реально держать открытыми одновременно

Прямой практический вопрос при планировании сервера: сколько документов Grist может обслуживать одновременно на заданном объёме RAM. Точной универсальной цифры тут нет — она зависит от сложности формул в каждом документе, но общий принцип такой:

  • Документ, который никто не открывал последнее время, не держит активную песочницу — Grist освобождает ресурсы неактивных документов, и заметный расход памяти идёт именно от тех документов, что открыты прямо сейчас хотя бы одной вкладкой.
  • Простой документ-таблица без формул или с парой лёгких вычислений почти не отличается по памяти от статичного файла — узкое место там, где формулы пересчитываются по цепочке ссылок на другие таблицы.
  • Планируя сервер под команду, ориентируйтесь не на общее число документов в организации, а на реалистичный пик — сколько документов будет одновременно открыто в рабочий час.

Если типичная нагрузка — редкие проверки и разовые правки, 2–4 ГБ хватает с запасом. Если Grist используется весь день как рабочий инструмент нескольких отделов с документами-справочниками на тысячи строк — закладывайте 8 ГБ и больше, и мониторьте docker stats в первую неделю, чтобы скорректировать лимит по факту, а не по ощущениям.

Какой сервер взять в MAATRIX под Grist

Честный минимум для знакомства и личного использования — 1 vCPU, 2 ГБ RAM, 20 ГБ NVMe. Этого достаточно, чтобы поднять Grist, создать несколько документов и попробовать формулы — но команда из нескольких человек с документами, открытыми параллельно, упрётся в память в первую же рабочую неделю.

Для рабочего использования небольшой командой (3–7 человек, документы открыты в течение дня, есть формулы со связями между таблицами) — 2 vCPU, 4 ГБ RAM, 40 ГБ NVMe. Это покрывает и Node-сервер, и несколько одновременных песочниц формул с запасом.

Если Grist — рабочий инструмент отдела с десятками документов и активной параллельной работой, берите 4 vCPU, 8 ГБ RAM, 80 ГБ NVMe и явно ограничивайте mem_limit, чтобы всплеск открытых документов не укладывал сервер по OOM. Общий подход к выбору сервера под нагрузку, где память определяет предел раньше диска, разобран в статье «Лучший VPS для базы данных» — логика оттуда переносится и на Grist, хотя формально это не классическая СУБД.

Локация — по составу команды и требованиям к данным: если в документах персональные данные сотрудников или клиентов из РФ, разумнее российская площадка под 152-ФЗ; для команды, разбросанной по миру, — Лондон или США с меньшей задержкой до остальных участников. Оплата на MAATRIX — картами российских банков, по СБП, криптовалютой или токеном MAAT, без необходимости в иностранной карте для разворота через Docker.

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

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

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

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

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

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

Хватит ли 1 ГБ RAM для Grist?

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

Grist ест память пропорционально числу строк в таблице?

Не напрямую. SQLite читает данные постранично, и сам факт хранения большой таблицы не означает большой расход RAM. Память растёт от того, сколько документов открыто одновременно и насколько тяжёлые в них формулы — документ на 500 тысяч строк без формул может есть меньше памяти, чем документ на 5 тысяч строк с длинной цепочкой пересчётов.

Можно ли отключить песочницу, чтобы сэкономить память?

Да, через GRIST_SANDBOX_FLAVOR=unsandboxed, формулы будут выполняться без изоляции. Экономия памяти и CPU реальная, но это осмысленный компромисс безопасности — подходит для личного сервера, где вы единственный, кто пишет формулы, и не подходит для инстанса, открытого нескольким пользователям с разным уровнем доверия.

Как понять, что памяти не хватает именно из-за песочниц формул?

Смотрите docker stats при открытии нескольких документов подряд — если память контейнера растёт скачками с каждым новым открытым документом, а не плавно с ростом данных, дело в количестве параллельных песочниц, а не в объёме базы.

Нужна ли Grist внешняя PostgreSQL, как NocoDB или Baserow?

Нет, это не обязательно — домашний сервер Grist по умолчанию использует SQLite для метаданных, и сами документы тоже хранятся как отдельные SQLite-файлы. Внешняя СУБД для типового self-hosted сценария не требуется, в отличие от Baserow, где чаще используют PostgreSQL для собственных таблиц.

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

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

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