2026-05-25 · 6 min
SQLite + Litestream: Database untuk SaaS Kecil dengan Budget 0
Saya punya SaaS kecil — alat invoice untuk freelancer Indonesia. Pelanggan: 47 aktif, ARR ~$3500. Margin tipis. Setiap pengurangan biaya infrastructure langsung jadi profit.
Enam bulan lalu, biaya database saya: $25/month untuk Hetzner managed Postgres. Tidak banyak tapi tidak nol.
Sekarang: $0. Migrasi ke SQLite + Litestream untuk replication ke Cloudflare R2.
Setup
# Dependencies
bun add better-sqlite3
brew install litestream # macOS dev
# Production: download binary dari litestream.io
# litestream.yml
dbs:
- path: /var/lib/myapp/data.db
replicas:
- type: s3
bucket: myapp-backup
endpoint: https://xxx.r2.cloudflarestorage.com
path: data.db
retention: 720h # 30 days
sync-interval: 10s
// Application code
import { Database } from 'bun:sqlite';
const db = new Database('/var/lib/myapp/data.db');
db.exec('PRAGMA journal_mode = WAL;');
db.exec('PRAGMA synchronous = NORMAL;');
db.exec('PRAGMA cache_size = -64000;'); // 64MB cache
db.exec('PRAGMA temp_store = MEMORY;');
db.exec('PRAGMA mmap_size = 268435456;'); // 256MB
export default db;
# systemd service
[Unit]
After=network.target
[Service]
ExecStart=/usr/local/bin/litestream replicate
Restart=always
User=myapp
[Install]
WantedBy=multi-user.target
Total: ~30 lines of config. Done.
6 bulan production stats
Database size: 240MB (47 aktif customer, 12K invoice). Read throughput: ~150 req/sec sustained, peak 800 req/sec. Write throughput: ~12 req/sec sustained. Replication lag to R2: 10-15 detik avg (sesuai sync-interval). Downtime: 0 (sekali server reboot, app continue setelah systemd restart).
Memory footprint: 80MB (vs Postgres ~250MB). Disk I/O: 30% dari Postgres yang sama.
Yang TIDAK bisa SQLite
-
Multiple writers concurrent: WAL mode allows multi-reader + single-writer. Untuk OLTP heavy write: bukan match. Saya hanya 12 write/sec, fine.
-
Network access: SQLite is in-process. App harus di-server yang sama. Tidak bisa “connect to database server”.
-
Complex JSON query: SQLite JSON1 OK untuk dasar. Tapi tidak sebagus Postgres jsonb dengan GIN index. Untuk app yang heavily query nested JSON: stuck dengan Postgres.
-
Stored procedures: SQLite has no procedural language. Logic must be di app code.
Yang Litestream beri
- Point-in-time recovery (PITR): bisa restore ke timestamp manapun dalam retention window (30 days untuk saya).
- Disaster recovery: kalau VPS hancur, restore dari R2 ke server baru ~5 menit.
- Read replica?: Litestream support replica server (
litestream restore+read-onlymode). Saya belum perlu, tapi opsi terbuka.
Cost breakdown
| Item | Old (Postgres) | New (SQLite + Litestream) |
|---|---|---|
| Database compute | $25/mo (Hetzner managed) | $0 (in-process) |
| Storage | Included | $0.015/mo (240MB R2) |
| Bandwidth | Included | $0 (R2 egress free) |
| Backup tool | $0 | $0 (Litestream OSS) |
| Total | $25/mo | ~$0.02/mo |
Saving: $24.98/mo = $300/year.
Untuk SaaS dengan ARR $3500, $300/year savings ~9% margin gain.
Kapan SQLite bukan match
- Multi-region deploy yang butuh latency rendah dari berbagai benua.
- App OLTP dengan > 100 writes/sec sustained.
- Tim besar yang butuh DBA workflow (migration, schema review).
Saran
Kalau Anda jalankan SaaS kecil yang stuck dengan biaya managed DB: migrasi ke SQLite layak dipertimbangkan. 30 menit setup. Komitmen rendah untuk rollback (export SQLite ke Postgres adalah trivial).
Kalau klien Anda demand “real database” — kasih dia Postgres untuk peace of mind, tapi internal dashboard / project pribadi: SQLite cukup.
Yang killer fitur SQLite: WAL mode + Litestream + R2 = setup 30 menit, biaya nyaris nol, durability acceptable untuk most use case.
Ditulis oleh Reza Pradipta