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

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

MAATRIX

Если вы устали от того, что Pocket закрывается, а закладки в браузере превращаются в кладбище мёртвых ссылок, Wallabag — логичный выбор: open-source read-it-later сервис, который сохраняет статью целиком (текст, картинки, иногда PDF), а не просто ссылку на неё. Вопрос в том, какой VPS под него брать — и здесь Wallabag заметно прожорливее, чем кажется на первый взгляд, потому что построен на Symfony, а не на паре простых PHP-скриптов. Разберём, из чего складывается расход памяти и сколько реально закладывать под личный архив и под команду.

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

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

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

Что за нагрузку создаёт Wallabag

Wallabag — PHP-приложение на фреймворке Symfony, и это ключевое отличие от лёгких RSS-читалок вроде FreshRSS: Symfony сам по себе тяжелее из-за DI-контейнера, роутинга, Doctrine ORM и Twig-шаблонов, которые нужно скомпилировать и закешировать при первом запуске. Даже в простое, без единого пользователя, PHP-процесс Wallabag ест заметно больше памяти, чем условный «прочитал файл — отдал HTML» скрипт.

Вторая, и самая тяжёлая по памяти операция — это не веб-интерфейс, а сохранение статьи. Когда вы добавляете URL (через веб-форму, браузерное расширение, мобильное приложение или API), Wallabag не просто копирует ссылку: он сам ходит на сайт-источник, скачивает HTML, прогоняет его через библиотеку graby (обёртка над несколькими алгоритмами извлечения контента вроде Readability), выкидывает рекламу и навигацию, опционально скачивает и перекодирует изображения себе на диск. Это разовый, но ресурсоёмкий процесс — на «тяжёлых» страницах с большим DOM и множеством картинок один такой запрос может на несколько секунд занять заметно больше памяти, чем обычная отдача страницы из архива.

Третий источник нагрузки — массовый импорт. Если вы переезжаете с Pocket, Instapaper или Readability и загружаете экспортированный JSON с тысячами статей разом, Wallabag обрабатывает их либо синхронно (что долго и рискованно на слабом VPS), либо через очередь на Redis/RabbitMQ (что требует дополнительного сервиса, но не убивает основной процесс одним запросом).

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

Реальный расход RAM на сервере с Wallabag — это сумма нескольких компонентов:

  • PHP-FPM воркеры под Symfony — каждый активный воркер держит 40-80 МБ (заметно больше, чем у лёгких PHP-приложений, из-за размера автозагружаемых классов Symfony и Doctrine). При пуле из 3-5 воркеров это 150-350 МБ.
  • Веб-сервер — nginx перед PHP-FPM берёт 5-15 МБ базово плюс 1-3 МБ на воркер-процесс.
  • Процесс сохранения статьи (graby) — на время скачивания и парсинга одной страницы отдельный PHP-процесс кратковременно занимает 30-100 МБ в зависимости от размера исходной страницы, освобождается сразу после сохранения.
  • База данных — SQLite не создаёт отдельного процесса (база — файл на диске). MySQL/MariaDB или PostgreSQL — это отдельный демон, который в простое держит 150-300 МБ вне зависимости от объёма архива.
  • Redis (опционально, для async-импорта) — базовый redis-server в простое занимает 5-15 МБ, но под очередь из тысяч импортируемых статей может временно вырасти до 50-100 МБ.
  • ОС и системные службы — минимальный Ubuntu/Debian без графики съедает 100-200 МБ на ядро, systemd, cron, sshd.

Итог: даже минимальная конфигурация Wallabag на SQLite ощутимо тяжелее, чем FreshRSS или другие «лёгкие» self-hosted читалки, — Symfony-накладные расходы никуда не деваются даже без нагрузки.

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

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

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

Сколько RAM закладывать по сценариям

Для одиночного личного архива (сохраняете статьи для себя, до 1000-2000 сохранённых) минимально рабочий вариант — VPS с 1 ГБ RAM: Debian/Ubuntu minimal (~120-150 МБ), nginx + PHP-FPM с пулом на 3 воркера (~150-250 МБ), Wallabag на SQLite без отдельного процесса БД, и запас на пиковые операции сохранения тяжёлых страниц. На 512 МБ Wallabag формально запускается, но при первом же сохранении статьи с большим DOM или при компиляции Symfony-кеша после обновления версии высок риск упереться в OOM — это не тот случай, где стоит экономить последние 512 МБ.

Цифры ниже — практический ориентир, у вас может отличаться в зависимости от версии PHP, числа PHP-модулей, размера архива статей и частоты сохранений — считайте это отправной точкой, а не гарантией.

СценарийПользователейСтатей в архивеБДИмпорт больших архивовRAM VPSCPU
Личный архив1до 1000-2000SQLiteнет/разово1 ГБ1 vCPU
Активное использование13000-10000+SQLite/MySQLиногда2 ГБ1-2 vCPU
Семья/малая группа2-5по 1000-3000 на каждогоMySQL/MariaDBредко2 ГБ2 vCPU
Команда с async-импортом5-15десятки тысяч суммарноPostgreSQL/MySQL + Redisрегулярно4 ГБ2-4 vCPU
Команда + доп. сервисы на том же сервере15+десятки тысяч+PostgreSQL + Redisрегулярно4-8 ГБ4 vCPU

Ключевой параметр здесь — не число пользователей, а частота операций сохранения и импорта. Один человек, который методично сохраняет по 50-100 статей в день через браузерное расширение, создаёт больше пиковой нагрузки, чем несколько пользователей, заходящих просто почитать уже сохранённое. Если планируете разовый перенос многотысячного архива из Pocket — на время самого импорта закладывайте запас сверху, а не постоянную конфигурацию.

SQLite vs MySQL/PostgreSQL для Wallabag

При установке Wallabag сам спрашивает, какую СУБД использовать. Разница ощутимая:

SQLite — база в одном файле, никакого отдельного процесса. Плюсы: минимальный постоянный расход RAM, простой бэкап (скопировал файл — перенёс весь архив статей, тегов и аннотаций). Минусы: при активном одновременном использовании несколькими людьми (или при синхронном сохранении статей во время активного чтения) блокировки на уровне файла становятся заметны — для личного использования это почти никогда не проблема.

MySQL/MariaDB — привычный выбор, если на сервере уже крутится MySQL под другие проекты. Отдельный процесс mysqld добавляет 150-300 МБ постоянного расхода даже без запросов.

PostgreSQL — официально рекомендуемая Wallabag СУБД для серьёзных нагрузок (лучше работает с полнотекстовым поиском и большими архивами). По памяти сопоставим с MySQL — postgres-процессы в простое держат порядка 100-200 МБ, но каждое активное соединение добавляет свои 5-10 МБ, если не настроен пул соединений (PgBouncer имеет смысл только при действительно большом числе одновременных пользователей).

Практический вывод: для личного архива берите SQLite и не переплачивайте за память под пустующий демон СУБД. PostgreSQL или MySQL имеют смысл, если заводите Wallabag на команду или если на сервере уже есть СУБД для других сервисов — тогда Wallabag просто заводит свою базу в существующем инстансе.

Docker Compose и лимиты памяти

Официальный образ wallabag/wallabag включает встроенный nginx, PHP-FPM и, при желании, отдельные контейнеры для БД и Redis. Базовый вариант с SQLite:

services:
  wallabag:
    image: wallabag/wallabag
    container_name: wallabag
    restart: unless-stopped
    ports:
      - "8080:80"
    environment:
      - SYMFONY__ENV__DATABASE_DRIVER=pdo_sqlite
      - SYMFONY__ENV__DOMAIN_NAME=https://read.example.com
    volumes:
      - ./data:/var/www/wallabag/data
      - ./images:/var/www/wallabag/web/assets/images
    deploy:
      resources:
        limits:
          memory: 512M
        reservations:
          memory: 200M

Для варианта с PostgreSQL и Redis (нужен для асинхронного импорта больших архивов) добавляются отдельные контейнеры:

  postgres:
    image: postgres:16
    restart: unless-stopped
    environment:
      POSTGRES_DB: wallabag
      POSTGRES_USER: wallabag
      POSTGRES_PASSWORD: change_me
    volumes:
      - ./pg-data:/var/lib/postgresql/data
    deploy:
      resources:
        limits:
          memory: 384M

  redis:
    image: redis:7-alpine
    restart: unless-stopped
    deploy:
      resources:
        limits:
          memory: 128M

С такой связкой (Wallabag + PostgreSQL + Redis) закладывайте VPS от 2 ГБ, чтобы под ОС и Docker-демон оставалось хотя бы 400-500 МБ — сама контейнеризация добавляет 50-100 МБ накладных расходов сверх голых процессов. Если вы впервые настраиваете прод-окружение с Docker Compose, общий порядок с сетями, restart-политиками и лимитами памяти разобран в статье про пошаговую установку Docker Compose на Ubuntu 24.04, а базовые принципы mem_limit/reservations — в материале про лимиты CPU и памяти в Docker.

Импорт архивов, OPcache и мониторинг

Перенос архива из Pocket, Instapaper или из другого Wallabag выполняется через bin/console wallabag:import или через веб-интерфейс с загрузкой JSON-экспорта. На маленьком VPS с синхронным импортом (без Redis) многотысячный архив стоит заводить порциями по 500-1000 записей, а не одним файлом — иначе PHP-процесс либо упрётся в memory_limit из php.ini, либо в max_execution_time. Если импорт регулярный (например, вы постоянно мигрируете команду с других сервисов), связка с Redis и bin/console wallabag:import --async разгружает основной процесс, разбивая работу на очередь фоновых джоб — но требует держать запущенным consumer-процесс, который сам по себе съедает 30-60 МБ постоянно.

Отдельный рычаг экономии — OPcache. Symfony-приложения без включённого и правильно настроенного OPcache компилируют PHP-файлы в байткод заново на каждый запрос, что и медленнее, и прожорливее по памяти при пиковой нагрузке. В php.ini минимально разумная настройка:

opcache.enable=1
opcache.memory_consumption=128
opcache.max_accelerated_files=20000
opcache.validate_timestamps=0

validate_timestamps=0 означает, что после изменения кода (обновления Wallabag) нужно вручную сбрасывать кеш (systemctl reload php8.3-fpm) — это ускоряет работу и снижает нагрузку на CPU/RAM, но требует не забывать об этом шаге при апдейтах.

Проверить реальное потребление перед апгрейдом тарифа:

free -h
docker stats --no-stream   # если через Docker
tail -f var/logs/prod.log  # лог самого Symfony/Wallabag

Типичные признаки нехватки памяти: сохранение статей с крупных сайтов регулярно обрывается или зависает, dmesg показывает killed-процессы PHP-FPM через OOM killer в момент импорта, страница администрирования тегов и статей начинает открываться заметно дольше обычного при росте архива. Если это ваш случай — сначала снизьте pm.max_children, разбейте импорт на меньшие порции и проверьте, включён ли OPcache, и только затем переходите на VPS с большим объёмом RAM.

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

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

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

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

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

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

Хватит ли 512 МБ RAM для Wallabag?

Формально запускается, но рискованно: первое же сохранение тяжёлой страницы или компиляция Symfony-кеша после обновления может упереться в OOM. Для стабильной работы берите минимум 1 ГБ.

Почему Wallabag ест больше памяти, чем FreshRSS или другие простые PHP-читалки?

Wallabag построен на Symfony — полноценном фреймворке с DI-контейнером, ORM и шаблонизатором Twig, а не на наборе простых скриптов. Накладные расходы фреймворка есть даже без активной нагрузки.

Нужен ли Redis обязательно?

Нет, только если делаете регулярный асинхронный импорт больших архивов. Для личного использования и разового переноса из Pocket можно обойтись синхронным импортом порциями.

SQLite выдержит большой архив статей?

Да, для одиночного или семейного использования SQLite нормально работает с тысячами статей — узкое место там не размер файла, а параллельные записи при активном одновременном сохранении несколькими пользователями.

Сколько памяти реально экономит SQLite по сравнению с PostgreSQL или MySQL?

Ориентировочно 150-300 МБ — именно столько постоянно держит процесс СУБД в простое, даже с пустой базой. Для VPS с 1 ГБ это существенная доля общего объёма.

Что тяжелее для памяти — веб-интерфейс или сохранение статей?

Сохранение статей: пока вы просто читаете сохранённое, нагрузка минимальна, но каждое добавление новой ссылки запускает загрузку и парсинг чужой страницы через graby — это и есть основной источник пиковой нагрузки.

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

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

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