Сколько RAM нужно для Paperless-ngx
Архив на 5–10 тысяч документов в Paperless-ngx неделями стоит тихо на 1–1,5 ГБ занятой памяти, а потом вы разом скидываете полсотни сканов из старой коробки с чеками — и сервер уходит в своп или роняет контейнер по OOM. Дело не в объёме архива: сами PDF с текстовым слоем лежат на диске и почти не трогают RAM. Дело в очереди Celery и в том, сколько worker'ов Tesseract одновременно распознают текст. Ниже — по каким контейнерам расходится память, что реально её ест и сколько закладывать под свой темп сканирования.
Содержание
- Короткий ответ: сколько закладывать
- Из чего состоит Paperless-ngx и куда уходит память
- Tesseract и ocrmypdf — главный источник пиков
- PostgreSQL и индекс полнотекстового поиска
- Gotenberg и Tika: когда архив не только про сканы
- Как ограничить и замерить память по контейнерам
- Какой сервер под Paperless-ngx взять в MAATRIX
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →Короткий ответ: сколько закладывать
Ориентир для стандартного стека из docker-compose.postgres.yml (webserver, db, broker/Redis, опционально gotenberg+tika) на Ubuntu 24.04, кириллица + английский в OCR. Цифры — не бенчмарк, а практический запас с учётом пиков при пачечной загрузке.
| RAM | Что реально тянет | Комментарий |
|---|---|---|
| 2 ГБ | Архив в покое, OCR по 1 документу за раз | Хватает для теста и медленной ручной загрузки |
| 4 ГБ | 5–10 тыс. документов, пачки по 10–20 сканов, PAPERLESS_TASK_WORKERS=1-2 | Рабочий минимум для домашнего архива |
| 8 ГБ | Активная семья или малый офис, почтовый импорт, Workflows, изредка большие пачки | Комфортный вариант без нервов при загрузке |
| 16 ГБ | Общий архив на несколько человек, включён Gotenberg/Tika для офисных документов, десятки тысяч страниц | Запас под параллельный OCR и конвертацию форматов |
Правило то же, что и для других self-hosted сервисов: архив растит диск, а не память. Память растёт от того, сколько задач Celery обрабатывает параллельно прямо сейчас, а не от того, сколько документов уже накоплено.
Из чего состоит Paperless-ngx и куда уходит память
Минимальный стек — это webserver (Django + gunicorn + Celery worker внутри одного образа), база данных и брокер очереди. У каждого своя роль в потреблении RAM, и они очень неравномерны.
| Контейнер | Роль | В покое | Под нагрузкой (OCR идёт) |
|---|---|---|---|
webserver | Веб-интерфейс, API, Celery worker, OCR (Tesseract через ocrmypdf) | 300–500 МБ | 600 МБ – 1,5+ ГБ на воркер |
db (PostgreSQL) | Метаданные документов, теги, корреспонденты, индекс полнотекстового поиска | 100–200 МБ | Растёт с shared_buffers, обычно скромно |
broker (Redis) | Очередь задач Celery | 10–30 МБ | Почти не меняется |
gotenberg + tika (опционально) | Конвертация офисных документов (docx, xlsx) в PDF перед OCR | 0 (если не установлены) | 200–400 МБ на конвертацию каждого файла |
Важная особенность: в отличие от многих self-hosted стеков, где OCR или ML вынесены в отдельный сервис, у Paperless-ngx весь Celery worker с распознаванием текста живёт внутри контейнера webserver. Это значит, что веб-интерфейс и OCR-очередь делят один и тот же лимит памяти контейнера — если вы жёстко ограничиваете webserver через deploy.resources.limits, при этом лимите должны уместиться и веб-сессии, и активная обработка сканов одновременно.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверTesseract и ocrmypdf — главный источник пиков
Каждая задача OCR — это не облегчённый скрипт, а полноценный процесс ocrmypdf, который разворачивает PDF постранично, прогоняет через Tesseract, собирает текстовый слой обратно и (по желанию) оптимизирует итоговый файл. На одну задачу типичный расход памяти — 200–500 МБ, но он растёт с разрешением скана и числом страниц в документе: 20-страничный договор, отсканированный в 300 dpi, ощутимо тяжелее пятистраничного чека.
Число одновременных задач задаётся переменной окружения:
# .env или docker-compose.env
PAPERLESS_TASK_WORKERS=2
PAPERLESS_THREADS_PER_WORKER=1
По умолчанию Paperless-ngx пытается угадать разумное число воркеров исходя из числа ядер CPU — на слабом VPS с 2 vCPU это может быть 2 воркера по несколько потоков каждый, и при одновременной загрузке пачки сканов это легко даёт 4–6 параллельных OCR-задач сразу. На сервере с 4 ГБ RAM это перебор: снижайте вручную.
PAPERLESS_OCR_LANGUAGE=rus+eng
PAPERLESS_OCR_LANGUAGES=rus eng
PAPERLESS_OCR_MODE=skip
Языковые пакеты Tesseract сами по себе занимают немного места на диске и почти не влияют на RAM во время работы — тяжелеет не язык, а разрешение картинки и число одновременных задач. Режим skip (OCR не повторяется, если в PDF уже есть текстовый слой) экономит именно CPU и время, а не память — но косвенно снижает и её пиковое потребление, потому что меньше документов одновременно стоят в очереди.
Проверить реальный расход по контейнеру проще всего вживую во время загрузки пачки:
docker stats paperless-webserver-1 --no-stream
Если MEM USAGE скачет к пику и через минуту-две спадает обратно — это нормальная работа Celery worker'ов, не утечка. Если держится на потолке и после — смотрите, не застряла ли задача в очереди на повторных попытках.
Второй источник таких же пиков, помимо ручной загрузки, — IMAP-аккаунт, который Paperless-ngx опрашивает по расписанию (Settings → E-Mail) и вытаскивает вложения. Разовое подключение к почте по памяти незаметно, но если на ящик за ночь упало полсотни счетов от разных поставщиков, все они попадают в очередь Celery одновременно — работает та же логика: пик определяется числом одновременных OCR-задач, а не тем, откуда пришёл файл. Если оба канала активны на небольшом сервере, имеет смысл развести их по времени через расписание опроса почты, а не полагаться на то, что пики не совпадут сами.
PostgreSQL и индекс полнотекстового поиска
Полнотекстовый поиск в Paperless-ngx — не отдельный сервис вроде Elasticsearch или Meilisearch, а встроенные средства PostgreSQL (tsvector/tsquery). Это упрощает стек — не нужно поднимать и синхронизировать отдельный поисковый движок, — но означает, что индекс поиска живёт в той же базе, что и метаданные документов, и растёт вместе с архивом.
На практике для десятков тысяч документов это единицы, а не десятки гигабайт данных, и дефолтных настроек shared_buffers в контейнере обычно достаточно. Если архив перевалил за сотню тысяч страниц и поиск по тексту начал ощутимо тормозить, есть смысл выделить базе больше памяти явно:
# postgresql.conf внутри контейнера db
shared_buffers = 256MB
work_mem = 8MB
maintenance_work_mem = 64MB
Если раньше вы уже считали память под PostgreSQL для другого проекта на том же сервере, логика идентична — можно свериться со статьёй PostgreSQL на VPS: здесь та же база, просто с более скромным объёмом данных, чем у транзакционных приложений.
Gotenberg и Tika: когда архив не только про сканы
Если в архив попадают не только сканы бумаги, а и «нативные» офисные документы — присланные по почте docx-договоры, xlsx-счета, — Paperless-ngx конвертирует их в PDF перед OCR через связку Gotenberg (рендер в PDF через headless LibreOffice/Chromium) и Apache Tika (извлечение метаданных из офисных форматов). Это два дополнительных контейнера в docker-compose.yml, и оба не бесплатны по памяти:
services:
gotenberg:
image: gotenberg/gotenberg:8
restart: unless-stopped
environment:
- GOTENBERG_CHROMIUM_DISABLE_ROUTES=true
tika:
image: apache/tika:latest
restart: unless-stopped
webserver:
environment:
PAPERLESS_TIKA_ENABLED: 1
PAPERLESS_TIKA_GOTENBERG_ENDPOINT: http://gotenberg:3000
PAPERLESS_TIKA_ENDPOINT: http://tika:9998
Gotenberg под капотом гоняет LibreOffice, и конвертация одного docx в PDF может кратковременно занять 200–400 МБ — терпимо при редких запусках, но заметно, если офисные документы прилетают пачками вместе со сканами. Tika легче — Java-процесс, который в покое держит порядка 150–250 МБ и почти не растёт от разовых файлов. Если в архиве только сканы бумаги, эти два сервиса можно вообще не разворачивать — прямая экономия и памяти, и точек отказа.
Как ограничить и замерить память по контейнерам
Если пиковые нагрузки регулярно кладут сервер в своп, порядок действий стандартный для любого self-hosted стека на VPS — своп, earlyoom, приоритеты процессов — разобран в статье что делать при нехватке RAM. А если хочется явно ограничить контейнер, а не гадать по факту, общие принципы cgroup-лимитов для Docker — в статье про ресурсы и лимиты CPU и памяти.
Прежде чем менять тариф, стоит понять, кто из контейнеров реально упирается в потолок:
docker stats --no-stream paperless-webserver-1 paperless-db-1 paperless-broker-1
Если контейнеры не просто тормозят, а падают, ищите в системном логе признаки OOM-killer:
dmesg -T | grep -i "out of memory"
Жёсткий лимит на webserver дисциплинирует Celery worker, не давая ему забрать всю свободную память при пачечной загрузке:
services:
webserver:
deploy:
resources:
limits:
memory: 3g
Здесь тот же принцип, что и для любого контейнера с фоновой обработкой: лимит должен быть выше реального пика, замеренного через docker stats, а не взят с потолка — иначе контейнер начнёт падать по OOM прямо посреди распознавания пачки сканов, и часть документов зависнет в статусе FAILURE вместо того, чтобы просто обработаться медленнее.
Какой сервер под Paperless-ngx взять в MAATRIX
Минимум для личного архива: 2 vCPU, 4 ГБ RAM, от 40 ГБ NVMe. С такой конфигурацией PAPERLESS_TASK_WORKERS лучше держать на 1–2, чтобы OCR-очередь не спорила за память с базой и веб-интерфейсом при пачечной загрузке. Диск важнее, чем кажется на старте: сырые сканы плюс архивные PDF с текстовым слоем занимают место быстрее, чем один документ на первый взгляд.
Комфортный вариант для семьи или малого офиса: 4 vCPU, 8 ГБ RAM, 100–150 ГБ NVMe. При таком запасе можно спокойно держать 2–3 параллельных OCR-задачи, подключить почтовый импорт и включить Gotenberg с Tika для офисных документов без риска упереться в память на регулярной загрузке.
Общий архив с интенсивным сканированием: 6 vCPU, 16 ГБ RAM, от 250 ГБ NVMe. Если документы поступают из нескольких источников одновременно (сканер, почта, мобильное приложение) и архив уже перевалил за десятки тысяч страниц — здесь пригодится запас и под параллельный Celery, и под растущую базу PostgreSQL.
Локация. Документы в архиве — это часто персональные данные (паспорта, договоры, справки с ИНН), и вопрос юрисдикции хранения здесь не абстрактный. Если архив используется только внутри России, российский сервер снимает вопрос трансграничной передачи и даёт стабильную скорость загрузки с домашнего или офисного канала. Для доступа из-за рубежа или когда важна независимость от российской юрисдикции — Лондон или США подходят без разницы в требованиях к RAM, разница будет только в задержке интерфейса при просмотре архива.
Paperless-ngx можно развернуть на сервере из каталога apps.maatrix.io — автоустановка поднимает docker-compose с webserver, базой и брокером очереди, а доступ и пароль администратора появляются в личном кабинете. OCR под кириллицу и подключение Gotenberg/Tika вы уже настраиваете сами под свой поток документов. Оплата — картой российского банка, по СБП, криптовалютой или токеном MAAT, без иностранной карты даже для площадки в Лондоне или США.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверНужны сами нейросети для контента?
Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.
Частые вопросы
Хватит ли 2 ГБ RAM для Paperless-ngx?
Только для теста и очень редкой ручной загрузки по одному документу. Веб-интерфейс и база в покое в 2 ГБ помещаются, но пачка из десятка сканов, запущенная в OCR одновременно, легко выест всю свободную память и уронит контейнер по OOM.
Растёт ли RAM с ростом архива документов?
Незначительно и постепенно. Сами файлы и текстовый слой лежат на диске, а не в памяти, индекс полнотекстового поиска в PostgreSQL растёт линейно, но медленно — на десятках тысяч документов это единицы гигабайт данных на диске, а не скачок в потреблении оперативной памяти. Основной расход памяти определяется не размером архива, а тем, сколько OCR-задач обрабатывается параллельно прямо сейчас.
Нужно ли отдельно ставить Gotenberg и Tika?
Только если в архив попадают офисные документы (docx, xlsx), а не только сканы бумаги. Для чисто скановой домашней бухгалтерии эти два контейнера можно не разворачивать вообще — это экономит и память, и лишний слой конфигурации.
Что делать, если сервер уходит в своп при загрузке большой пачки сканов?
Снизьте PAPERLESS_TASK_WORKERS до 1–2, чтобы OCR-задачи выполнялись последовательно, а не все разом, и настройте своп как страховку на случай редких пиков.
Можно ли обойтись без PostgreSQL и использовать SQLite?
Технически да, проект это поддерживает, но при параллельной обработке нескольких документов и активном полнотекстовом поиске PostgreSQL стабильнее и не создаёт блокировок базы — для чего-то серьёзнее личного теста на паре документов лучше сразу поднимать Postgres.
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →