MAATRIX / Блог / PocketBase обещает бэкенд за вечер: что выясняется на второй неделе

PocketBase обещает бэкенд за вечер: что выясняется на второй неделе

MAATRIX

Обещание PocketBase звучит слишком хорошо: скачал один бинарник, запустил, через десять минут у вас есть база данных, REST и realtime API, авторизация с email-подтверждением и OAuth, файловое хранилище и админка с UI — без Docker, без отдельной СУБД, без конфигов на полсотни строк. Для пет-проекта, MVP или внутреннего инструмента это действительно так и работает. Вопрос в другом: что происходит через две недели, когда в проекте появляются реальные пользователи, параллельные записи и запросы сложнее, чем «выбрать всё из одной таблицы».

Что такое PocketBase на самом деле

PocketBase — это Go-приложение, скомпилированное в один исполняемый файл, внутри которого зашиты: HTTP-сервер, SQLite как база данных, слой аутентификации (email/пароль, OAuth2 у популярных провайдеров, one-time password), файловое хранилище (локальный диск или S3-совместимое) и realtime-подписки поверх Server-Sent Events. Плюс встроенная админ-панель — статический SPA, который раздаётся тем же бинарником и позволяет создавать коллекции, настраивать правила доступа и смотреть данные без единой строчки кода.

Идея в основе — «коллекции» (по сути таблицы SQLite с JSON-схемой полей поверх них) и API-правила доступа, которые пишутся как строка-выражение прямо в настройках коллекции, например @request.auth.id = user. Это не полноценный язык политик уровня PostgreSQL Row Level Security, но для типовых сценариев «пользователь видит только свои записи» хватает с запасом.

Технически PocketBase можно использовать и как библиотеку — импортировать pocketbase в свой Go-проект и навесить кастомные HTTP-хендлеры и хуки на события (OnRecordCreate, OnRecordAfterUpdateSuccess и десятки других). Но на практике большинство берут готовый бинарник и не пишут ни строчки Go — этот сценарий и разберём.

Установка на VPS выглядит буквально так:

mkdir -p /opt/pocketbase && cd /opt/pocketbase
curl -L https://github.com/pocketbase/pocketbase/releases/download/vX.Y.Z/pocketbase_X.Y.Z_linux_amd64.zip -o pb.zip
unzip pb.zip && rm pb.zip
./pocketbase serve --http=0.0.0.0:8090

(Версию подставляйте актуальную с релизов проекта на GitHub — здесь принципиально не фиксируем номер, потому что PocketBase обновляется часто и быстро.) Дальше — systemd-юнит, чтобы процесс поднимался после ребута и не умирал при OOM, и nginx или Caddy спереди как reverse proxy с TLS. Никакого docker-compose с пятью сервисами, никакого отдельного контейнера под базу — вот в чём и заключается всё обаяние PocketBase для маленького проекта.

Что он честно закрывает из коробки

Прежде чем переходить к ограничениям, стоит признать: список того, что PocketBase решает без единой строчки бэкенд-кода, реально длинный.

  • Аутентификация. Регистрация по email с подтверждением, вход по паролю, восстановление пароля, OAuth2 (Google, GitHub, Discord и другие популярные провайдеры настраиваются через админку без кода), опционально MFA. Токены — JWT, refresh через API.
  • CRUD с правилами доступа. Каждая коллекция получает REST-эндпоинты (GET/POST/PATCH/DELETE /api/collections/{name}/records) автоматически, правила listRule, viewRule, createRule, updateRule, deleteRule фильтруют доступ на уровне записи.
  • Realtime. Подписка на изменения коллекции через SSE — фронтенд получает события create/update/delete без отдельного вебсокет-сервера и без Redis pub/sub.
  • Файлы. Загрузка файлов как поля записи, thumbnails «на лету» по query-параметрам, хранение локально или в S3-совместимом бакете.
  • Админка. Полноценный UI для просмотра и редактирования данных, настройки коллекций и правил — то, ради чего иначе пришлось бы поднимать отдельный admin-panel builder.
  • Бэкапы. Встроенная команда бэкапа всей базы и файлов в zip, можно дёргать по расписанию через cron или встроенный планировщик.

Для прототипа, лендинга с формой обратной связи, внутреннего трекера задач на 5 человек, MVP, который нужно показать инвестору через три дня — это буквально «бэкенд за вечер», и здесь маркетинговое обещание PocketBase не врёт.

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

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

Арендовать VPS

Где начинает жать: параллельная запись в SQLite

Первая и самая частая точка боли — не «PocketBase плохой», а «SQLite — не тот инструмент для этой нагрузки». SQLite физически не умеет несколько параллельных писателей: даже в WAL-режиме (Write-Ahead Logging, который PocketBase включает по умолчанию) в любой момент времени в базу пишет ровно один процесс, остальные писатели встают в очередь и ждут блокировку. Чтения при этом не блокируются писателями — WAL для того и придуман, — но сама запись остаётся строго последовательной.

Для типичного пет-проекта с несколькими одновременными пользователями это незаметно: запись занимает миллисекунды, очередь рассасывается мгновенно. Проблема проявляется, когда:

  • растёт число одновременных пишущих запросов (не читающих — именно пишущих: создание заказов, апдейт статусов, логирование событий);
  • в приложении есть длинные транзакции, которые держат блокировку записи дольше обычного;
  • сервер стоит на медленном диске (сетевые тома некоторых облаков дают заметно бо́льшую задержку fsync, чем локальный NVMe, а WAL требует частых fsync при чекпоинтах).

Симптом на практике — не крах, а деградация: запросы на запись отвечают всё медленнее, в логах появляются database is locked, если busy_timeout выставлен слишком низко. PocketBase задаёт разумные дефолты, но при росте нагрузки это первое, что стоит проверить — и первый сигнал, что вы приближаетесь к потолку архитектуры, а не к багу конкретного приложения. Мы отдельно разбирали, сколько параллельных писателей выдерживает SQLite до появления заметных тормозов — цифры сильно зависят от диска и профиля нагрузки, но порядок величины понятен уже там.

Важно: PocketBase не «внезапно ломается» на каком-то конкретном числе пользователей. Деградация плавная, и для многих проектов её вообще не заметят — SaaS с сотней активных пользователей и умеренной частотой записи прекрасно живёт на SQLite годами. Речь именно про рост: e-commerce с пиковыми нагрузками, real-time-аналитику с частой записью событий, что-то с высокочастотными вебхуками — вот там потолок нащупывается быстро.

Сложные запросы: чего SQL PocketBase не умеет из коробки

Второе ограничение — не про производительность, а про выразительность. API-фильтры PocketBase (filter=status="active" && created>="2026-01-01") прекрасно работают для плоских условий по полям одной коллекции. Но как только нужно что-то из следующего списка, готового решения через стандартный REST-эндпоинт нет:

  • АгрегацииCOUNT, SUM, AVG, GROUP BY по коллекциям через стандартный API недоступны напрямую; для дашборда «сколько заказов в день по неделям» придётся либо тянуть все записи на клиент и считать там, либо писать кастомный Go-хендлер с сырым SQL через app.DB().
  • JOIN между произвольными коллекциями за пределы «связанное поле» (relation field) — PocketBase умеет раскрывать один уровень связей через expand, но многотабличные джойны с условиями по нескольким таблицам одним запросом не сделать без кастомного кода.
  • Window-функции, CTE, сложная аналитика — доступны на уровне «голого» SQLite движка (он их поддерживает), но не через публичный REST API — нужен прямой доступ к БД из Go-кода расширения.
  • Полнотекстовый поиск ограничен тем, что даёт SQLite (LIKE, при желании — FTS5-модуль, который придётся подключать вручную), не сравним по возможностям с Elasticsearch или даже полнотекстовым поиском PostgreSQL из коробки.

Формально всё это решаемо — PocketBase как Go-библиотека даёт прямой доступ к dbx-обёртке над SQLite, и через кастомные роуты можно писать любой SQL. Но тогда теряется главное преимущество — «без бэкенд-кода»: первый же кастомный Go-хендлер с ручным SQL переводит проект из режима «бэкенд за вечер» в обычную Go-разработку с удобной обвязкой вокруг авторизации и CRUD.

Экосистема и зрелость плагинов

PocketBase — маленький проект в сравнении с Django, Rails или даже Supabase по числу контрибьюторов и накопленных решений задач сообществом. Практические следствия:

  • Готовых интеграций меньше. Хотите Stripe webhooks, отправку email через конкретного провайдера, интеграцию с очередью задач — во многих экосистемах есть готовый плагин «из коробки», у PocketBase чаще придётся писать хук самому (благо API для хуков простой и документированный).
  • JS Extend через Goja — PocketBase позволяет писать хуки не только на Go, но и на JavaScript (движок Goja, встроенный интерпретатор ES5+ с частичной поддержкой ES6). Это снижает порог входа, но у Goja есть нюансы совместимости с современным JS и Node-экосистемой — не всякий npm-пакет туда возьмёт и заработает, это не Node.js runtime.
  • Миграции схемы есть и работают неплохо (JS-файлы миграций, применяются автоматически при старте), но инструментов уровня Prisma Migrate или Django ORM migrations с автогенерацией диффа схемы нет.
  • Мониторинг и observability — придётся собирать самостоятельно: встроенных интеграций с Prometheus/Grafana из коробки нет, логи пишутся в SQLite же (отдельная таблица) с ограниченным сроком хранения по умолчанию.

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

PocketBase vs Supabase: разные весовые категории

Сравнение возникает часто, потому что оба проекта продают себя как «Firebase-альтернатива с открытым кодом». На деле это разные инструменты для разных задач.

PocketBaseSupabase
База данныхSQLite (один файл)PostgreSQL (полноценный сервер)
Развёртываниеодин бинарник, без зависимостейнабор контейнеров: Postgres, GoTrue, PostgREST, Realtime, Storage, Kong и другие
Параллельная записьпоследовательная (ограничение SQLite)полноценная MVCC-параллельность PostgreSQL
Сложные запросыограничены API-фильтрами, для остального — кастомный кодполный SQL через PostgREST, представления, хранимые процедуры
Ресурсы на стартеминимальные, тянет и на 1 vCPU / 512 МБ-1 ГБ RAMзаметно больше — очереди с несколькими сервисами просят от 2 ГБ RAM и выше
Порог входаминутычасы (настройка docker-compose, переменных окружения по каждому сервису)
Потолок ростанебольшие и средние проектыощутимо выше за счёт PostgreSQL под капотом

Проще говоря: PocketBase — это «нужен рабочий бэкенд без возни с инфраструктурой», а Supabase — «нужна PostgreSQL-мощь с готовым REST/realtime поверх, и я готов администрировать несколько контейнеров». Выбор — не «что лучше», а «что соответствует масштабу задачи сейчас». Тащить Supabase под лендинг с формой заявки — как ставить дизельный генератор, чтобы зарядить телефон. И наоборот: удерживать на PocketBase интернет-магазин с десятками параллельных заказов в минуту — значит упереться в SQLite и API-фильтры раньше, чем хотелось бы.

Когда PocketBase — правильный выбор, а когда — нет

Сводим сказанное выше в практический критерий.

PocketBase подходит, если:

  • прототип, MVP, внутренний инструмент, pet-проект — нужно быстро, а не «на вырост»;
  • нагрузка на запись умеренная: десятки, максимум низкие сотни одновременных пишущих операций в пике, а не тысячи;
  • схема данных плоская или с неглубокими связями, аналитика — простая (фильтры, сортировки, пагинация);
  • команда — один-два человека, время дороже, чем возможность гибко всё кастомизировать;
  • проект можно будет мигрировать позже, если он «выстрелит» — а не наоборот, закладываться на масштаб, которого может и не случиться.

Стоит присмотреться к альтернативе (Supabase, самостоятельно поднятый PostgreSQL + свой API-слой, или классический фреймворк), если:

  • заранее известно, что параллельных пишущих пользователей будут сотни-тысячи одновременно;
  • нужны сложные отчёты, агрегации, аналитика по многим таблицам как часть основного API, а не разовая выгрузка;
  • в требованиях — сложная модель прав доступа за пределами простых @request.auth-выражений;
  • команда уже умеет администрировать PostgreSQL и не видит в этом дополнительной сложности.

Здесь же стоит вспомнить более общий принцип: для стартапа на самом старте вообще не обязательно тащить тяжёлую инфраструктуру — подробнее в материале про минимальный набор инфраструктуры для стартапа без выделенного администратора. PocketBase туда вписывается естественно как один из вариантов «минимального набора», а не как компромисс.

И если проект всё же перерос SQLite — это не катастрофа и не повод переписывать всё с нуля: данные можно перенести, схему коллекций PocketBase достаточно легко транслировать в обычные таблицы PostgreSQL, а бизнес-логика (правила доступа, хуки) переносится в код нового бэкенда постепенно. Мы отдельно писали про признаки того, что SQLite упёрся в потолок, и пошаговый план переезда на «взрослую» базу — тот же план применим и к проекту на PocketBase, когда придёт время.

Чек-лист перед запуском на проде

Несколько вещей, которые стоит сделать сразу, а не когда уже станет больно:

  1. Вынести бэкапы за пределы сервера. Встроенная команда кладёт zip рядом с данными — на том же диске при его отказе бэкап пропадёт вместе с базой. Настройте выгрузку в S3-совместимое хранилище или на другой сервер по cron.
  2. Настроить systemd с ограничением памяти и автоперезапуском — юнит с Restart=on-failure и разумным MemoryMax избавит от ночного вызова при всплеске нагрузки.
  3. Мониторить database is locked в логах с первого дня — ранний индикатор приближения к потолку параллельной записи, а не сюрприз в проде.
  4. Не хранить файлы пользователей на том же диске, что и SQLite, если их объём ощутимый — сразу в S3-совместимый бакет, переносить позже дороже.
  5. Разнести dev и prod через отдельные pb_data каталоги — состояние живёт в одной директории, склеить окружения по ошибке легко, откатывать больно.

Диск и стабильность fsync под WAL — то место, где сказывается качество VPS: на медленном сетевом томе PocketBase будет тормозить на записи раньше, чем на честном NVMe. При развёртывании под реальный проект стоит сразу смотреть на конфигурацию сервера под нагрузку — в материале про ресурсы VPS для стартапа на старте разобрано, сколько CPU и RAM закладывать, чтобы не упереться в диск раньше, чем в код.

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

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

Арендовать VPS

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

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

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

Можно ли на PocketBase запустить полноценный интернет-магазин?

Технически да, для магазина с невысоким трафиком на первые месяцы — вполне. Но при десятках одновременных заказов в минуту и сложной аналитике продаж закладывайтесь на миграцию заранее.

Что будет, если данные перерастут один SQLite-файл?

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

PocketBase поддерживает горизонтальное масштабирование?

Из коробки нет: SQLite-файл живёт на одном диске одного сервера, шардирования и репликации архитектура не предусматривает. Вертикальное масштабирование (сервер помощнее, диск побыстрее) работает и часто отодвигает потолок надолго.

Нужен ли Docker для PocketBase?

Нет — это осознанное отличие от Supabase, один бинарник запускается напрямую через systemd. Docker-образ существует для тех, кому нужна контейнеризация по другим причинам, но не как необходимость.

Насколько сложно перейти с PocketBase на что-то другое?

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

Стоит ли использовать PocketBase в проде, а не только для прототипов?

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

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

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

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