- Struktur penulis tunggal dan sifat embedded SQLite terbukti lewat eksperimen justru menjadi faktor yang meningkatkan skalabilitas dan performa
- Dalam kondisi yang sama, Postgres turun hingga 348 TPS saat ada latensi jaringan, sedangkan SQLite mencapai 44.096 TPS setelah jaringan dihilangkan
- Dengan memanfaatkan model penulis tunggal melalui pemrosesan batch dan transaksi terperinci berbasis SAVEPOINT, tercatat hingga 186.157 TPS, dan 102.545 TPS pada konfigurasi yang stabil
- Hukum Amdahl menjelaskan bottleneck pada database berbasis jaringan, dan SQLite mempertahankan efisiensi tinggi dengan menghindarinya
- Hasil ini menekankan potensi penggunaan SQLite di lingkungan lokal dan pentingnya menghilangkan bottleneck jaringan
Struktur SQLite dan lingkungan eksperimen
- SQLite tidak memiliki MVCC dan hanya mengizinkan satu penulis, tetapi struktur ini justru memungkinkan skalabilitas yang tinggi
- Sebagai database embedded, tidak ada overhead jaringan
- Benchmark dijalankan pada MacBook Pro (2021) dengan Apple M1 Pro dan memori 16GB
- Eksperimen ini bukan ditujukan untuk optimasi sempurna, melainkan untuk menunjukkan bahwa throughput tulis yang tinggi dapat dicapai bahkan dalam kondisi umum
Definisi TPS dan contoh transaksi
- TPS bukan sekadar kecepatan tulis, melainkan transaksi interaktif (Interactive Transaction)
- Contoh: saat mentransfer dana antar rekening, beberapa query dan kode aplikasi dijalankan dalam satu transaksi
- Transaksi dapat melakukan rollback saat terjadi kesalahan, sehingga berperan penting dalam menjaga konsistensi
Konfigurasi benchmark
- Menggunakan virtual threads berbasis Clojure untuk mensimulasikan permintaan serentak dalam skala besar
- Postgres dikonfigurasi dengan connection pool berbasis HikariCP, sedangkan SQLite menggunakan satu penulis dan koneksi baca sebanyak jumlah core
- Kedua database menggunakan tabel
accountsederhana dengan field id, balance, dan memasukkan 1 miliar baris - Aktivitas pengguna mengikuti distribusi hukum pangkat (0,9995), dengan sekitar 100 ribu pengguna aktif
Kinerja database jaringan (Postgres)
- Pada server yang sama, Postgres mencapai 13.756 TPS
- Saat ditambahkan latensi jaringan 5ms, performanya turun tajam menjadi 1.214 TPS, dan pada 10ms menjadi 702 TPS
- Setelah menerapkan tingkat isolasi serializable, turun menjadi 660 TPS, dan dengan query tambahan menjadi 348 TPS
- Ini menunjukkan, sesuai Hukum Amdahl, bahwa bottleneck jaringan membatasi performa keseluruhan
- Saat latensi jaringan meningkat, kompetisi lock transaksi makin parah sehingga tidak dapat diskalakan
Keunggulan embedded SQLite
- Setelah jaringan dihilangkan, SQLite mencapai 44.096 TPS
- Karena bottleneck jaringan hilang, dampak Hukum Amdahl diminimalkan
- Dengan memanfaatkan struktur penulis tunggal dan menerapkan pemrosesan batch, performa naik hingga 186.157 TPS
- Penyesuaian ukuran batch secara dinamis otomatis mengoptimalkan latency dan throughput
Transaksi terperinci dengan SAVEPOINT
- Untuk mencegah kegagalan transaksi individual di dalam batch, diterapkan transaksi bertingkat menggunakan SAVEPOINT
- Jika gagal, hanya transaksi tersebut yang di-rollback, sementara batch keseluruhan tetap dipertahankan
- Dengan cara ini, sistem tetap mempertahankan 121.922 TPS
Uji beban campuran baca/tulis
- Total permintaan terdiri dari 75% baca dan 25% tulis
- Menggunakan thread pool baca terpisah agar permintaan baca tidak mengganggu tulis
- Hasilnya, tercapai 102.545 TPS
Ringkasan perbandingan performa
| Kondisi | Postgres | SQLite |
|---|---|---|
| Tanpa jaringan | 13.756 | 44.096 |
| Latensi 5ms | 1.214 | n/a |
| Latensi 10ms | 702 | n/a |
| 10ms + serializable | 660 | n/a |
| Pemrosesan batch | n/a | 186.157 |
| Batch + SAVEPOINT | n/a | 121.922 |
| Batch + SAVEPOINT + baca | n/a | 102.545 |
Kesimpulan
- SQLite mencapai TPS yang jauh lebih tinggi dibanding database berbasis jaringan berkat model penulis tunggal dan struktur embedded
- Efisiensi dimaksimalkan dengan menghindari batas bottleneck jaringan yang dijelaskan oleh Hukum Amdahl
- Seluruh kode telah dipublikasikan di GitHub, dan materi terkait seperti Hukum Amdahl, hukum pangkat, serta contoh skalabilitas SQLite juga disertakan
- SQLite adalah pilihan yang sangat efektif untuk pemrosesan transaksi berkinerja tinggi di lingkungan lokal
2 komentar
Kalau hanya akan dipakai di lingkungan lokal tanpa pergi ke server eksternal, berarti tidak perlu membayar pajak bernama jaringan, ya. (VFS vs Socket)
Komentar Hacker News
Saya sedang membuat server ORM/CRUD protobuf hibrida berbasis SQLite
Kode dan penjelasannya ada di GitHub - accretional/collector
Saat backup real-time, downtime 5–15ms, antrean ratusan permintaan baca/tulis, latensi CRUD total sekitar 1ms, bahkan memungkinkan streaming backup berbasis WAL
Dulu saya hanya memakai Postgres dan Spanner, tetapi jika fitur partisi ditambahkan ke Collector, rasanya saya tidak akan memakai Postgres lagi
Kekurangannya adalah semua data dan operasi harus muat di satu mesin
Jika memakai instance AWS u-24tb1.112xlarge (448 vcore, RAM 24TB, EBS 64TB), ruangnya cukup lega
Tulisan itu menekankan efisiensi SQLite, tetapi terasa tidak jelas tolok ukurnya
Karena awalnya diasumsikan arsitektur server terpisah, lalu yang diukur justru performa DB embedded lokal
Dalam kondisi yang sama, tuning Postgres lokal juga bisa menghasilkan performa serupa
Membatasi koneksi Postgres ke 8 mungkin menjadi bottleneck
Akan bagus jika penggunaan CPU dan thread juga dipublikasikan, lalu diuji ulang dengan connection pool yang lebih besar
Jika ditingkatkan ke 64 koneksi, throughput bisa naik 8 kali lipat. Konfigurasi klien perlu diperluas sampai mencapai batas
Intinya adalah menyadari apakah latensi jaringan menjadi bottleneck
Pada banyak workload, DB lokal biasa saja bisa lebih cepat daripada DB remote yang hebat
Yang penting bukan “DB mana yang terbaik”, melainkan “apakah kita perlu melintasi batas jaringan”
DB berbasis jaringan punya kelebihan karena memudahkan redeploy aplikasi
Anda bisa menyalakan instance baru lalu mematikan yang lama, sehingga deployment hampir tanpa downtime bisa dilakukan
Jika SQLite berada di instance yang sama, saat penggantian DB harus dinaikkan lagi sehingga lebih rumit. Saya penasaran apakah Anda pernah mengalami masalah seperti ini di operasi nyata
Saat migrasi bisa terjadi downtime. Berkat Litestream, sekarang replikasi dan backup jauh lebih mudah
Penulis mengatur
PRAGMA synchronous="normal", yang berarti fsync tidak dijalankan setiap saatUntuk perbandingan yang adil, seharusnya diatur ke
"full""normal"juga cukup baik. Saat listrik padam, durabilitas memang hilang, tetapi konsistensi transaksi tetap terjagaSaya penasaran seperti apa konfigurasi HA (high availability) untuk SQLite
Setidaknya harus sampai pada tingkat yang memungkinkan failover otomatis
Saat ini saya sedang menimbang antara Postgres dan SQLite (termasuk litestream).
Aplikasi saya bisa mentoleransi sedikit downtime, jadi scale-up vertikal di satu box lebih sederhana dan murah
Di Marmot GitHub baru ditambahkan mekanisme replikasi berbasis gossip
Saya penasaran apakah benar ada kasus mendorong SQLite sampai batasnya di production
Saya ingin tahu kira-kira seperti apa batas jumlah pengguna untuk SQLite vs Postgres dalam web app atau lingkungan commerce pada umumnya
Dalam update terbaru, SQLite memungkinkan pembacaan serentak tetapi tetap hanya mengizinkan satu penulisan
Dalam kasus seperti apa ini menjadi masalah, dan jika mempertimbangkan skalabilitas, apakah lebih baik mulai dari Postgres?