Коротко — да и нет. SQLite прекрасно подходит для разработки, прототипов и небольших приложений с невысокой интенсивностью записи. Но у него есть ограничения, о которых важно знать, чтобы не получить неприятный сюрприз при росте нагрузки.
Что важно понимать
- Архитектура: SQLite — файловая база (всё хранится в одном файле). Это даёт простоту и скорость на небольших объёмах, но и накладывает ограничения на параллелизм.
- Чтения vs записи: несколько читателей работают параллельно, но запись только одна в момент времени (записи сериализуются). При интенсивных или длительных транзакциях записи будут ждать, возможны ошибки "database is locked".
- Мультипроцессность: если у вас несколько воркеров/инстансов бэкенда (горизонтальное масштабирование), конкуренция за файл усиливается. На NFS/сетевых файловых системах SQLite работать ненадёжно.
- IO и блокировки: при резком всплеске запросов возможны задержки IO, увеличение времени ожидания блокировок и отказ API, если не обрабатывать ретраи.
- Надёжность/функционал: SQLite ACID и очень стабильна, но не даёт репликации, масштабирования и сложных СУБД-фич (параллельная репликация, продвинутые индексы, плана выполнения и т. п.).
Когда SQLite подходит
- Небольшой проект/прототип/локальная разработка.
- Небольшое число пользователей, преимущественно чтения и редкие короткие записи.
- Однопроцессный деплой (один экземпляр FastAPI, либо только один воркер).
- Требуется простая конфигурация, минимум операций администрирования.
Когда лучше выбирать серверную СУБД (Postgres/MySQL)
- Ожидается рост числа пользователей и частые записи.
- Планируется горизонтальное масштабирование приложения (несколько инстансов).
- Нужны репликация, резервирование, мониторинг нагрузки, сложные транзакции/конкурентность.
- Требуется высокая устойчивость под пиками.
Практические рекомендации, если хотите остаться на SQLite
- Используйте WAL: PRAGMA journal_mode=WAL; это улучшает параллельность чтений и записей.
- Установите busy_timeout, чтобы избегать мгновенных ошибок при блокировках: PRAGMA busy_timeout=5000 (мс) или эквивалент в драйвере.
- Не держите долгие транзакции; делайте короткие атомарные коммиты.
- Для FastAPI: если вы используете асинхронные эндпоинты, не вызывайте синхронный sqlite в event loop — либо используйте aiosqlite, либо выполняйте операции в ThreadPoolExecutor.
- Не храните файл БД на сетевых томах (NFS) — используйте локальное хранилище.
- Для многопроцессного запуска (gunicorn/uvicorn с несколькими воркерами) тестируйте нагрузку; понимайте, что записи будут конкурировать.
- Обрабатывайте ошибки блокировок и делайте ретраи с экспоненциальной задержкой.
- Подумайте о кэше (Redis) для снижения нагрузки на БД по частым чтениям.
Переход на Postgres позднее
- Если вы используете ORM (SQLAlchemy/SQLModel), переход часто — просто смена connection string + некоторый рефакторинг SQL. Поэтому для проекта, который вы хотите масштабировать, разумно спроектировать абстракцию доступа к данным заранее.
Что может случиться при резком росте нагрузки
- Медленные ответы из-за ожидания блокировок.
- Ошибки "database is locked" (если нет ретраев).
- Увеличение IO — может привести к деградации производительности и отказам API.
- В случае распределённого деплоя — некорректное поведение или повышенная конкуренция.
Итог / совет
- Для первого проекта и стадии разработки — SQLite хорош и удобен.
- Для продакшена: если приложение остаётся малонагруженным и с преимущественно чтением — можно оставить SQLite, но с вышеуказанными настройками и мониторингом.
- Если вы ожидаете рост или собираетесь запускать несколько инстансов сервиса — лучше сразу взять PostgreSQL/MySQL (или вынести write-heavy части туда), чтобы не столкнуться с проблемами в пик.
Если хотите, могу:
- Просмотреть ваш репозиторий и подсказать конкретные места (настройки подключения, использование ORM) и подходящую конфигурацию для FastAPI + SQLite.
- Подготовить краткий список команд PRAGMA и пример настройки в SQLAlchemy / aiosqlite / SQLModel.