Menjalankan SQLite di Produksi dengan Litestream

Foto oleh Forest Wander from Cross Lanes via Wikimedia Commons (CC BY-SA 2.0)
SQLite siap produksi untuk bentuk beban kerja yang tepat: aplikasi single-node yang read-heavy, kira-kira di bawah sepuluh ribu pengguna aktif harian. Celah utama selalu durabilitas di satu disk, dan Litestream menutupnya dengan men-streaming perubahan ke object storage. Untuk banyak layanan kecil ia lebih cepat dan lebih murah daripada database terkelola.
Ia berjalan sebagai proses latar belakang, mengendalikan checkpointing WAL, dan menangkap halaman database baru saat aplikasi Anda melakukan commit tulis. Ia secara berkala mengambil snapshot penuh dan men-streaming perubahan inkremental di antara snapshot ke object storage seperti S3, R2, atau B2. Untuk restore, ia mengunduh snapshot dan memutar ulang perubahan yang dicatat setelahnya.
Ya. Perintah restore menerima timestamp dan membangun ulang database seperti yang ada pada momen persis itu, selama masih dalam jendela retensi yang Anda konfigurasi. Ini adalah jalur pemulihan untuk migrasi buruk, bulk update yang kacau, atau delete tidak sengaja. Tanpa timestamp Anda mendapat keadaan terbaru yang direplikasi.
Rilis 0.5.0 mengganti WAL segment dengan format LTX yang sadar-transaksi dan menambahkan kompaksi hierarkis melintasi jendela 30 detik, 5 menit, dan per jam, sehingga restore menyentuh sekitar selusin file alih-alih ribuan. Ia juga menghapus konsep generations demi ID transaksi monoton dan membuang dependensi CGO dengan beralih ke build SQLite murni-Go.
Tidak. Litestream adalah disaster recovery, bukan high availability. Replikasi bersifat asinkron, jadi kegagalan disk bisa kehilangan sekitar satu detik terakhir tulisan, dan versi 0.5.0 hanya mengizinkan satu tujuan replika per database. Jika Anda butuh nol kehilangan data, failover otomatis, atau banyak penulis bersamaan, gunakan Postgres.

Foto oleh Forest Wander from Cross Lanes via Wikimedia Commons (CC BY-SA 2.0)
Ringkasan Utama
Litestream adalah proses latar belakang yang men-streaming write-ahead log database SQLite ke object storage seperti S3, memberi Anda backup berkelanjutan dan restore point-in-time tanpa server database. Untuk aplikasi single-node yang read-heavy di bawah sekitar sepuluh ribu pengguna harian, ia mengubah file SQLite biasa menjadi penyimpanan produksi yang tahan lama dan dapat dipulihkan.
Selama bertahun-tahun refleksnya otomatis: produksi berarti Postgres, dan SQLite untuk tes dan prototipe. Saya berhenti mempercayai itu setelah menjalankan beberapa layanan kecil di mana satu file SQLite di VPS lebih cepat, lebih murah, dan lebih sederhana daripada database terkelola yang saya bayar per jam. Satu hal yang selalu menahan saya adalah durabilitas. Satu file di satu disk hanya berjarak satu volume rusak dari hilang. Litestream adalah alat yang menutup celah itu, dan rilis 0.5.0-nya di akhir 2025 membuatnya jauh lebih baik.
Ini adalah panduan praktis tentang cara kerja Litestream, cara menghubungkannya di samping aplikasi nyata, bagaimana restore point-in-time berperilaku ketika terjadi masalah, dan — sama pentingnya — beban kerja di mana saya masih akan memilih Postgres. Tidak ada sihir, hanya proses latar belakang yang menyalin byte yang tepat ke bucket yang tepat.
Litestream berjalan sebagai proses terpisah di samping aplikasi Anda. Ia membuka koneksi baca berumur panjang ke database SQLite Anda sehingga checkpointing WAL dikendalikan oleh Litestream daripada terjadi secara acak. Saat aplikasi Anda melakukan commit tulis, SQLite menambahkannya ke write-ahead log; Litestream mengawasi log itu, menangkap halaman baru, dan menyalinnya ke object storage pada interval singkat. Ia secara berkala mengambil snapshot penuh lalu men-streaming perubahan inkremental di antara snapshot. Untuk membangun ulang database di mana saja, Anda mengunduh snapshot dan memutar ulang perubahan yang dicatat setelahnya.
Versi 0.5.0 mengganti model WAL-segment lama dengan format sadar-transaksi bernama LTX dan menambahkan kompaksi hierarkis. File perubahan kecil dari jendela 30 detik dikompaksi menjadi jendela 5 menit, dan itu menjadi jendela per jam. Manfaat praktisnya adalah restore hanya perlu menyentuh sekitar selusin file rata-rata alih-alih memutar ulang ribuan segmen kecil — restore yang dulu terasa lambat kini selesai cepat. Rilis ini juga membuang konsep generations yang membingungkan demi ID transaksi yang naik secara monoton, dan menghapus dependensi CGO dengan beralih ke implementasi SQLite murni-Go, yang membuat binary-nya mudah dimasukkan ke image Docker scratch.
Seluruh penyiapan adalah satu file YAML yang mencantumkan setiap database dan di mana replikanya berada. Arahkan ke endpoint apa pun yang kompatibel dengan S3 — AWS asli, Cloudflare R2, Backblaze B2, atau bucket MinIO yang Anda host sendiri. Saya menjalankan sebagian besar milik saya ke R2 karena egress-nya gratis, yang penting saat restore menarik seluruh dataset.
# /etc/litestream.yml
access-key-id: ${LITESTREAM_ACCESS_KEY_ID}
secret-access-key: ${LITESTREAM_SECRET_ACCESS_KEY}
dbs:
- path: /data/app.db
replicas:
- type: s3
bucket: my-app-backups
path: app.db
endpoint: https://<account>.r2.cloudflarestorage.com
region: auto
# snapshot on a schedule so restores stay fast
snapshot-interval: 6h
# keep 30 days of history for point-in-time restore
retention: 720hAnda memulai replikasi dengan satu perintah yang berjalan lama. Di produksi saya membiarkan systemd atau Docker mengawasinya agar ia restart jika mati.
# run as a supervised service
litestream replicate -config /etc/litestream.yml
# verify what has actually been replicated
litestream snapshots /data/app.db
litestream wal /data/app.dbLetakkan file database Anda di path yang TIDAK terhapus saat redeploy, dan beri Litestream waktu untuk menyelesaikan snapshot pertamanya sebelum Anda mengirim trafik produksi. Jalankan perintah snapshots di pemeriksaan deploy Anda — jika tidak mengembalikan apa pun, replikasi sebenarnya tidak terjadi dan Anda punya celah diam-diam di backup Anda.
Alasan Anda menjalankan Litestream adalah hari ketika Anda perlu membatalkan sesuatu. Restore membaca snapshot ditambah perubahan setelahnya dan membangun ulang file. Tanpa timestamp Anda mendapat keadaan terbaru; dengan timestamp Anda mendapat database seperti yang ada pada momen persis itu, selama masih dalam jendela retensi Anda. Ini adalah pintu darurat untuk migrasi buruk, bulk update yang kacau, atau delete-tanpa-klausa-where pada pukul tiga pagi.
# restore the latest state to a fresh path
litestream restore -o /data/app-restored.db /data/app.db
# restore to a specific point in time (UTC, RFC3339)
litestream restore \
-timestamp 2026-07-10T14:30:00Z \
-o /data/app-recovered.db \
/data/app.db
# bootstrap on a brand-new server straight from the bucket
litestream restore -config /etc/litestream.yml /data/app.dbBentuk terakhir itu adalah kekuatan super yang tenang. Di VPS baru dengan volume data kosong, Litestream memulihkan database langsung dari object storage sebelum aplikasi dimulai. Deploy Anda menjadi: tarik binary, restore dari bucket, mulai replikasi, mulai aplikasi. Tidak ada runbook backup-restore terpisah karena restore adalah bootstrap-nya.
Litestream adalah disaster recovery, bukan high availability. Replikasi bersifat asinkron, jadi jika disk mati Anda bisa kehilangan sekitar satu detik terakhir tulisan yang belum terkirim. Dan 0.5.0 menegakkan satu tujuan replika per database — ini pipeline backup, bukan cluster langsung dengan failover otomatis. Jika Anda butuh nol kehilangan data atau failover instan, ini alat yang salah.
Dengan durabilitas terpecahkan, argumen untuk SQLite menjadi kuat untuk bentuk beban kerja tertentu. Database adalah file dalam proses yang sama dengan aplikasi Anda, jadi baca adalah pemanggilan fungsi, bukan perjalanan jaringan. Tidak ada connection pool untuk disetel, tidak ada server terpisah untuk dipatch, dan tidak ada tagihan per jam. Dalam mode WAL pembaca tidak pernah memblokir penulis dan penulis tidak pernah memblokir pembaca.
Batas kerasnya adalah penulis tunggal. SQLite men-serialkan tulisan, jadi beban kerja dengan banyak proses independen yang menghantam tulisan secara bersamaan — worker latar belakang, ingesti fan-out tinggi, ratusan penulis simultan — persis untuk itulah Postgres dan penguncian MVCC tingkat-baris ada. Di NVMe modern penulis SQLite tunggal masih mendorong throughput yang mengejutkan, tetapi jika hambatan Anda adalah konkurensi tulis daripada volume tulis, jangan lawan modelnya. Pilih database yang cocok dengan bentuk tulisan Anda.
| Pertimbangan | SQLite + Litestream | Postgres Terkelola |
|---|---|---|
| Penulis bersamaan | Satu per satu (di-serialkan) | Banyak, MVCC tingkat-baris |
| Latensi baca | Dalam-proses, tanpa lompatan jaringan | Perjalanan jaringan per kueri |
| Model durabilitas | Replikasi async ke object storage | WAL sinkron + replika |
| Failover | Restore manual (DR, bukan HA) | Otomatis dengan standby |
| Biaya operasional | Satu binary + satu bucket | Layanan terkelola ditagih per jam |
Di VPS saya sendiri, saya menjalankan Litestream sebagai proses kedua dalam stack Docker Compose yang sama dengan aplikasi, berbagi volume data. Entrypoint container melakukan restore dari bucket jika file hilang, lalu memulai replicate. Saya menjaga retensi 30 hari dan interval snapshot enam jam, yang menyeimbangkan kecepatan restore dengan biaya penyimpanan, dan saya menguji restore ke path sekali-pakai secara berkala — backup yang belum pernah Anda restore adalah rumor, bukan backup. Loop tunggal itu telah mengubah SQLite dari kemudahan prototyping menjadi sesuatu yang nyaman saya jalankan dengan trafik nyata.