Найти в Дзене
Цифровая Переплавка

Rails на SQLite: простота, которая может дорого стоить

SQLite всегда ассоциировалась с «маленькой, но удобной» базой данных. Один файл — и у вас полноценное хранилище. В 2025-м, с появлением Rails 8 и таких решений как Solid Cable, Solid Cache и Solid Queue, эта простота стала ещё привлекательнее: можно развернуть приложение без отдельного Postgres, Redis и S3. Но вместе с удобством приходит новый класс рисков — неожиданные падения и потери данных. Главное отличие SQLite — всё приложение работает с одним файлом, который лежит рядом с процессом. Это убирает целый класс проблем:
🔌 нет ошибок соединения с базой,
🛠️ не нужны отдельные сервисы,
🚀 деплой получается невероятно лёгким. Но если этот файл хранится на временном диске контейнера (Heroku, Fly.io), он просто исчезает при перезапуске. Решение очевидное — использовать постоянные тома (EBS, Fly Volumes) и настраивать автоматические бэкапы. По умолчанию:
🗂️ ActiveRecord,
🧰 Rails.cache,
📨 ActiveJob — всё лежит в одном SQLite-файле. Это удобно для маленьких проектов, но при росте запрос
Оглавление
Описание: иллюстрации в винтажном стиле показывают символы SQLite и Rails, окружённые предупреждающими знаками, облаками с молниями и шестерёнками. Образ подчёркивает уязвимость архитектуры и риск сбоев при использовании SQLite в Rails-приложениях.
Описание: иллюстрации в винтажном стиле показывают символы SQLite и Rails, окружённые предупреждающими знаками, облаками с молниями и шестерёнками. Образ подчёркивает уязвимость архитектуры и риск сбоев при использовании SQLite в Rails-приложениях.

SQLite всегда ассоциировалась с «маленькой, но удобной» базой данных. Один файл — и у вас полноценное хранилище. В 2025-м, с появлением Rails 8 и таких решений как Solid Cable, Solid Cache и Solid Queue, эта простота стала ещё привлекательнее: можно развернуть приложение без отдельного Postgres, Redis и S3. Но вместе с удобством приходит новый класс рисков — неожиданные падения и потери данных.

📂 Одна база = один файл

Главное отличие SQLite — всё приложение работает с одним файлом, который лежит рядом с процессом. Это убирает целый класс проблем:
🔌 нет ошибок соединения с базой,
🛠️ не нужны отдельные сервисы,
🚀 деплой получается невероятно лёгким.

Но если этот файл хранится на временном диске контейнера (Heroku, Fly.io), он просто исчезает при перезапуске. Решение очевидное — использовать постоянные тома (EBS, Fly Volumes) и настраивать автоматические бэкапы.

🔄 Всё в одном: модели, кеш, очередь

По умолчанию:
🗂️ ActiveRecord,
🧰 Rails.cache,
📨 ActiveJob

— всё лежит в одном SQLite-файле. Это удобно для маленьких проектов, но при росте запросов появляется блокировка: даже чтение ждёт завершения записи.

Частично проблему решает WAL (Write-Ahead Log):
📝 записи пишутся в отдельный журнал,
📖 чтения не блокируются,
⚡ несколько процессов могут читать параллельно.

Но теперь у вас уже не один файл, а связка «основная база + WAL», и их нужно бэкапить синхронно.

📈 Масштабирование: вертикаль вместо горизонтали

С PostgreSQL или MySQL мы привыкли к «горизонтали» — добавил новых воркеров, контейнеров, реплик, и всё работает. С SQLite это невозможно: база — это файл, который не умеют одновременно видеть разные машины.

Поэтому остаётся только вертикальное масштабирование: больше CPU, больше RAM, больше потоков в одном сервере. Да, можно собрать монстра на 128 ядер и терабайт памяти, но предел в один файл остаётся.

Альтернативные трюки:
🔹
разделить базы: отдельно для моделей, кеша, очередей,
🔹
шардировать — вплоть до отдельного файла SQLite на каждого клиента.

Звучит дико, но на практике это работает и снижает конкуренцию.

🌍 Распределение и бэкапы

Для отказоустойчивости на помощь приходят:

☁️ Litestream — стримит WAL в S3-совместимое хранилище, позволяя восстановиться до любого момента.
🗄️
LiteFS — экстремальный вариант: SQLite в FUSE-файловой системе, с репликацией в стиле MySQL/Postgres. Это почти «мечта о глобальном SQLite-кластерe», но с классическими оговорками распределённых систем: задержки, возможные потери данных.

🤔 Моё мнение

SQLite в Rails — это как швейцарский нож: невероятно удобен для маленьких сервисов (например, с нагрузкой до 1 млн запросов в месяц). Пример Андре Арко с проектом feedyour.email показывает, что можно держать реальный сервис за $14/мес без лишней боли.

Но чем дальше, тем больше SQLite становится «ловушкой удобства»: простота оборачивается узким горлышком, где каждое вертикальное улучшение рано или поздно упрётся в один-единственный файл.

Я вижу SQLite в Rails как идеальный инструмент для прототипов, стартапов и pet-projects. Но для серьёзных продакшенов нужен либо переход на Postgres/MySQL, либо гибрид с LiteFS/Litestream. Иначе одна перезагрузка контейнера может превратить ваш проект в чистый лист.

📖 Источник: Rails on SQLite: exciting new ways to cause outages — André Arko