Sebuah benchmark komprehensif terhadap sembilan driver SQLite yang berbeda untuk bahasa pemrograman Go telah mengungkap beberapa karakteristik performa yang tidak terduga, khususnya menyoroti pendekatan tidak konvensional yang menggunakan komunikasi stdin/stdout dengan subprocess. Evaluasi ini menguji berbagai driver di beberapa skenario, mulai dari operasi bulk sederhana hingga beban kerja concurrent yang kompleks.
Driver SQLite yang Diuji:
- bvinc: Berbasis CGO, tidak kompatibel dengan database/sql
- cznic: Berbasis CGO, tidak kompatibel dengan database/sql
- eaton: Berbasis CGO, tidak kompatibel dengan database/sql
- gwenn: Pure Go, kompatibel dengan database/sql
- mattn: Berbasis CGO, kompatibel dengan database/sql (standar de-facto)
- modernc: Pure Go, kompatibel dengan database/sql (kode C yang ditranspilasi ke Go)
- numine: Pure Go, kompatibel dengan database/sql (berbasis WASM)
- sqinn: Pure Go, tidak kompatibel dengan database/sql (subprocess stdin/stdout)
- zombie: Pure Go, tidak kompatibel dengan database/sql (penulisan ulang berbasis modernc)
Solusi Pure Go Menantang Pendekatan CGO Tradisional
Hasil benchmark menunjukkan bahwa implementasi pure Go seperti modernc.org/sqlite kini menjadi alternatif yang layak untuk solusi berbasis CGO tradisional. Perkembangan ini mengatasi masalah yang sudah lama dihadapi oleh developer Go yang perlu melakukan cross-compile aplikasi untuk platform yang berbeda. Persyaratan CGO sering kali memperumit proses build, terutama ketika menargetkan sistem operasi atau arsitektur yang berbeda.
Beberapa developer di komunitas telah melaporkan kesuksesan dengan driver modernc di lingkungan produksi, memuji keandalan dan kemudahan deploymentnya. Driver ini bekerja dengan mentranspile kode C SQLite langsung ke Go, menghilangkan kebutuhan akan CGO sambil mempertahankan kompatibilitas dengan interface database/sql standar.
CGO: Sebuah fitur di Go yang memungkinkan program Go memanggil kode C, tetapi memerlukan compiler C selama proses build.
Pemenang Tak Terduga: Pendekatan stdin/stdout
Mungkin hasil paling mengejutkan datang dari sqinn, sebuah library yang berkomunikasi dengan SQLite melalui subprocess terpisah menggunakan stream stdin dan stdout. Pendekatan ini secara konsisten mengungguli banyak implementasi tradisional di berbagai benchmark, meskipun ada overhead yang tampak dari komunikasi proses.
Keunggulan performa kemungkinan berasal dari cara sistem operasi menangani buffer stream dibandingkan dengan overhead alokasi memori dalam panggilan API langsung. Ketika menggunakan stdin/stdout, sistem mengelola buffer kirim dan terima secara otomatis, berpotensi mengurangi siklus alokasi dan dealokasi yang terjadi dengan binding CGO tradisional.
Namun, pendekatan ini memiliki trade-off. Aplikasi yang menggunakan sqinn memerlukan distribusi binary SQLite terpisah bersama dengan executable Go, yang agak menghilangkan keunggulan Go dalam distribusi single-binary. Selain itu, akses database concurrent akan memerlukan pengelolaan beberapa subprocess.
Performa Dunia Nyata Bervariasi Berdasarkan Use Case
Benchmark menguji enam skenario berbeda, mulai dari bulk insert sederhana hingga operasi concurrent yang kompleks. Hasil bervariasi secara signifikan tergantung pada jenis beban kerja, tanpa ada satu driver yang mendominasi semua kategori. Variasi ini menekankan pentingnya menguji driver terhadap persyaratan aplikasi spesifik daripada hanya mengandalkan benchmark umum.
Untuk developer yang menghadapi tantangan cross-compilation, solusi pure Go menawarkan alternatif yang menarik. Salah satu anggota komunitas mencatat kesuksesan mereka beralih dari library berbasis CGO ke implementasi pure Go khusus untuk mengatasi masalah cross-compilation FreeBSD di macOS.
Kategori Benchmark:
- Simple: 1M insert pengguna dalam transaksi tunggal + query semua
- Real: 100 pengguna, 20 artikel per pengguna, 20 komentar per artikel (transaksi terpisah)
- Complex: 200 pengguna, 20K artikel, 400K komentar dengan query JOIN besar
- Many: N pengguna insert + 1000 pengulangan query (simulasi read-heavy)
- Large: 10K pengguna dengan konten N bytes (simulasi database besar)
- Concurrent: 1M pengguna + N goroutine melakukan query (simulasi concurrent read)
Adopsi SQLite yang Berkembang di Produksi
Di luar diskusi performa teknis, benchmark ini telah memicu percakapan yang lebih luas tentang peran SQLite di lingkungan produksi. Banyak developer melaporkan deployment yang sukses menggunakan SQLite untuk aplikasi yang secara tradisional mungkin menggunakan PostgreSQL atau MySQL.
SQLite kurang dihargai. Saya setuju bahwa dalam kasus tertentu mungkin bukan yang terbaik, tetapi lebih sering daripada tidak saya melihat bahwa SQLite sudah lebih dari cukup sebagai database. Menggunakan Postgres atau MySQL demi menjadi production grade bukanlah ide yang baik.
Kunci deployment SQLite yang sukses sering melibatkan pengaktifan mode Write-Ahead Logging (WAL), yang memungkinkan concurrent reader dan writer. Fitur ini mengatasi kekhawatiran tradisional tentang perilaku locking SQLite di lingkungan multi-process.
Write-Ahead Logging (WAL): Sebuah fitur SQLite yang meningkatkan concurrency dengan memungkinkan reader mengakses database sementara writer sedang membuat perubahan.
Lingkungan Pengujian:
- OS: Debian GNU/Linux 12.11 (amd64)
- CPU: Intel Core i7-1165G7 @ 2.80GHz (8 cores)
- RAM: 32GB
- Storage: 1TB NVMe SSD
- Versi Go: 1.24.5
- Tanggal Pengujian: 17 Agustus 2025
Kesimpulan
Hasil benchmark menunjukkan bahwa lanskap driver SQLite Go telah berkembang secara signifikan, dengan solusi pure Go kini menawarkan alternatif yang layak untuk pendekatan berbasis CGO tradisional. Meskipun pendekatan stdin/stdout menunjukkan angka performa yang mengesankan, pilihan driver pada akhirnya harus bergantung pada persyaratan aplikasi spesifik, batasan deployment, dan karakteristik performa yang paling penting untuk setiap use case.
Untuk developer yang memprioritaskan kemudahan deployment dan cross-compilation, driver pure Go seperti modernc.org/sqlite mewakili pilihan yang menarik. Mereka yang mencari performa maksimum mungkin mempertimbangkan pendekatan sqinn yang tidak konvensional, meskipun kompleksitas deploymentnya. Driver mattn/go-sqlite3 tradisional tetap menjadi pilihan yang solid untuk aplikasi di mana dependensi CGO dapat diterima.
Referensi: Benchmarks for Golang SQLite Drivers