- Menerapkan Durable Execution tidak selalu membutuhkan infrastruktur kompleks tersendiri; yang terpenting adalah menyimpan status workflow dengan aman
- SQLite menyediakan status persisten berbasis transaksi tanpa layanan database terpisah, sehingga status progres workflow dapat dijaga dengan aman tanpa network hop maupun control plane tambahan
- Dengan memanfaatkan Litestream untuk melakukan streaming perubahan SQLite secara asinkron ke object storage yang kompatibel dengan S3, status dapat tetap dekat dengan runtime sekaligus bisa disalin untuk keperluan backup, migrasi, dan inspeksi
- Untuk workflow yang bursty dan eksperimental seperti agen AI, arsitektur micro VM atau container di mana tiap agen memiliki unit status SQLite kecil yang independen lebih sederhana, lebih murah, dan lebih baik untuk isolasi kegagalan dibanding satu sistem bersama besar
- Jika membutuhkan high availability atau skalabilitas bersama yang luas, Postgres lebih cocok; namun banyak sistem workflow tidak memerlukan tingkat infrastruktur seperti itu pada tahap awal
Inti dari eksekusi persisten
- Eksekusi persisten sering dibahas seolah memerlukan infrastruktur persisten, tetapi yang benar-benar penting adalah workflow state, sementara compute bisa tetap murah dan bersifat sementara
- Di Obelisk, status progres workflow disimpan dalam execution log, direplay dari riwayat yang telah dipersistenkan, dan activity dapat dicoba ulang
Mengapa SQLite cocok
- SQLite menyediakan status persisten berbasis transaksi tanpa perlu menambahkan layanan database terpisah
- Status progres workflow dapat dijaga dengan aman tanpa network hop, control plane tambahan, atau beban operasional baru
- Pada banyak sistem, file database lokal adalah tingkat infrastruktur yang tepat
Mendapatkan portabilitas dengan Litestream
- Litestream melakukan streaming perubahan SQLite secara asinkron ke object storage yang kompatibel dengan S3, sehingga status tetap dekat dengan runtime sambil mendukung salinan untuk backup, migrasi, dan inspeksi
- Catatan: Replikasi Litestream bersifat asinkron, jadi jika volume SQLite hilang sebelum penulisan lokal terbaru yang belum tersalin dipindahkan, data itu bisa hilang saat pemulihan
- Ini dapat diterima untuk banyak workflow AI dan eksperimental, tetapi merupakan model yang berbeda dari shared database dengan high availability
- Model operasional yang praktis: jalankan server Obelisk bersama database SQLite, backup dengan Litestream, lalu bila perlu observer melakukan pull database — file yang sama bisa dipakai ulang untuk replay lokal, debugging, dan analisis perilaku agen
Mengapa ini sangat menguntungkan untuk agen AI
- Agen AI dan workflow yang dihasilkan AI memiliki karakter bursty dan eksperimental; memiliki unit status kecil yang mandiri untuk setiap agen atau tenant memudahkan penalaran sistem
- Arsitektur yang menjalankan database SQLite independen dan backup object storage pada armada server kecil berbasis micro VM atau container lebih sederhana, lebih murah, dan lebih baik untuk isolasi kegagalan dibanding satu sistem bersama besar yang selalu aktif
Kapan sebaiknya memakai Postgres
- Obelisk juga mendukung Postgres, dan itu menjadi pilihan jika Anda membutuhkan high availability, skalabilitas bersama yang luas, atau karakteristik deployment yang lebih cocok dengan database jaringan
- Postgres juga lebih sesuai jika replikasi object storage asinkron bukan model durability yang Anda inginkan
- Banyak sistem workflow tidak perlu memulai dengan infrastruktur yang melebihi kebutuhan status sebenarnya pada tahap awal
- Dengan kombinasi SQLite lokal + backup S3 via Litestream + worker murah, Anda sudah bisa membangun sistem persisten dengan infrastruktur minimal, dan ini bisa menjadi default paling masuk akal di lingkungan agen AI
1 komentar
Komentar Hacker News
Saya mulai menyusun workflow dengan Temporal, dan untuk aplikasi lokal ini bisa di-deploy dengan cukup ringan; pada instalasi lokal yang terisolasi saya memakai SQLite
Penanganan retry API, perapian workflow dan task jadi sangat sederhana, jadi saya merekomendasikan untuk mencobanya. Secara filosofis, arahnya persis sama dengan yang diusulkan artikel ini, tetapi ditambah antarmuka yang sangat kaya dan fleksibel yang ramah untuk agen. Mudah juga meninjau workflow lewat web UI dan memeriksa eksekusi agen
Temporal memberi sistem tingkat keandalan yang jauh lebih tinggi hampir seperti gratis. Sistem terdistribusi dan andal itu sulit, jadi menurut saya lebih baik tidak menemukan kembali roda
Jika Anda ingin bisa dengan mudah menginspeksi database SQLite, memahami apa yang terjadi di workflow, menggabungkan task individual, dan membuat workflow bisa dipanggil dengan sederhana, Temporal layak dilihat
Seiring itu, saya juga hampir tidak lagi memakai file untuk agen. Markdown dan JSON memang bagus, tetapi saat membuat aplikasi lokal kecil terasa seperti jebakan. LLM menangani SQLite dengan baik, dan dari sana bisa dirender ke bentuk apa pun yang diinginkan seperti Markdown atau JSON. Jika agen bisa mengkueri baris tertentu alih-alih menjalankan jq atau grep pada Markdown, token juga bisa sangat dihemat. Anda juga mendapatkan sistem pengelolaan data mandiri yang portabel, yang mendorong struktur data menjadi lebih disiplin dibanding banyak file. Jika proyek lokal kecil berkembang atau menjadi lebih formal, ini juga bisa dilanjutkan ke MySQL/Postgres, dan Anda sudah memiliki skema serta disiplin data sejak awal
Temporal menjadi jauh lebih rumit saat skala membesar. Mengoperasikan Cassandra tidak menyenangkan, dan Ringpop serta TChannel sulit di-debug saat ada masalah. Dukungan backend SQL juga tidak mendukung replika scale-out horizontal karena persyaratan konsistensi, jadi hanya memungkinkan satu instance
Bergantung pada cara Anda menulis kode, memperbaiki kode yang tertanam di workflow juga menjadi rumit. Perubahan yang mengubah urutan event histori akan merusak determinisme worker yang sudah ter-deploy
Kami banyak memakai Temporal, dan semua orang yang memulainya untuk scripting atau otomasi sederhana menyukainya, sedangkan semua yang membangun sistem produksi nyata di atasnya membencinya. Mungkin ini karena kurang matang secara operasional, tetapi gambaran serba indah yang terlihat di komentar-komentar sini tidak cocok dengan pengalaman saya
Saya belum mencobanya sendiri, tetapi ingin mendengar lebih banyak pengalaman nyata
Saya tidak paham obsesi untuk memakai SQLite di aplikasi produksi nyata. SQLite adalah database embedded, jadi sama sekali tidak cocok untuk mengelola konkurensi
Untuk pekerjaan seperti ini, sudah ada server database seperti Postgres dan MySQL. Seluruh peran mereka adalah memungkinkan banyak proses memodifikasi data secara bersamaan dari mesin yang berbeda
Ini prinsip dasar ilmu komputer, jadi pihak yang meneriakkan “SQLite untuk segalanya” terlihat agak kurang berpengalaman
SQLite adalah database produksi yang sangat bagus untuk banyak beban kerja nyata, dan hal ini sudah terdokumentasi luas. Karena sangat berbeda dari Postgres, Anda memang perlu mempelajari seperangkat teknik yang benar-benar berbeda
Salah satu sudut pandang adalah bahwa SQLite bisa sangat cocok untuk bagian-bagian sistem yang secara alami memiliki partisi kuat
net/httpmilik Go, sering kali sebuah layanan sudah bisa menangani seluruh beban yang bisa dibayangkan. Apalagi jika seiring waktu Anda bisa meningkatkan perangkat keras; SQLite bahkan bisa diskalakan dengan sederhana hingga ratusan ribu TPSYang benar-benar dikorbankan adalah high availability/failover dan pemulihan bencana, tetapi untuk ini pun ada solusinya. Sistem server tunggal umumnya sangat tangguh, sering kali secara mengejutkan. Sebab tanpa control plane yang rumit, uptime justru sering menurun ketika sistem makin bertambah besar
Saya suka mengevaluasi ulang “praktik terbaik” lama berdasarkan perubahan teknologi, terutama jika arahnya meningkatkan kesederhanaan. Menjalankan situs media sosial keluarga dengan satu SQLite DB di satu VPS itu sangat bagus. Penggunanya sekitar 15 orang dan hampir tidak butuh perawatan. Saya juga menjalankan instance FreshRSS dan halaman “now” dengan SQLite
Di tempat kerja juga, selama beberapa dekade terakhir saya telah memakai SQLite untuk berbagai macam keperluan. Saya memakainya untuk antrean kerja sementara, cara memuat dan mengueri banyak log lokal dengan cepat, lalu menampilkan dan memfilternya secara real-time dengan https://github.com/simonw/datasette yang luar biasa dari simonw
Menurut saya ini lebih dekat ke “SQLite di jauh lebih banyak tempat daripada yang Anda kira” daripada “SQLite untuk segalanya”
Pekerjaan kentonv/Cloudflare pada edge SQLite mungkin membuat gagasan ini sedikit lebih populer, tetapi ini sudah menjadi arus yang ada sejak lama. https://blog.cloudflare.com/sqlite-in-durable-objects/
Ingin mengetahui dan memanfaatkan kasus-kasus kecil namun berguna seperti ini bukanlah tanda kurang pengalaman, melainkan justru bisa menjadi tanda pengalaman
SQLite kemungkinan digunakan lebih luas daripada gabungan semua mesin database lainnya. Ada miliaran salinan SQLite di dunia nyata. SQLite ada di perangkat Android, iPhone dan perangkat iOS, Mac, instalasi Windows 10/11, Firefox/Chrome/Safari, Skype, iTunes, klien Dropbox, TurboTax dan QuickBooks, PHP dan Python, sebagian besar TV dan set-top box, sebagian besar sistem multimedia mobil, dan tak terhitung banyaknya aplikasi lainnya
https://sqlite.org/mostdeployed.html
Dengan cara ini, skalabilitas jauh lebih mudah dipahami. Tinggal pecah, lalu pecah lagi. Tambahkan satu shard lagi untuk setiap N pengguna
Sebagai gantinya, Anda mendapatkan masalah lain seperti kueri lintas-shard, misalnya untuk analitik, serta bagaimana meratakan beban ketika pengguna pergi atau menjadi usang
Tetapi Anda bisa menghindari seluruh masalah penskalaan indeks bersama yang muncul dari insert/update pada jumlah pengguna besar
Ini menjadi lebih mirip database hierarkis daripada database relasional
Semua hal berikut diganti sepenuhnya dengan Go + SQLite: Intercom, Zendesk, pemasaran email, Kanban, Todo, stack pembayaran, issue tracker, forum, pemantau uptime, klon PagerDuty
Karena produk yang dijual ada puluhan, saya jadi berpikir kenapa tidak buat semuanya sendiri
Semuanya berjalan di server yang sama dan memakai memori sangat sedikit. Semua alat SaaS yang sebelumnya dipakai diganti dengan ini
Setelah dipindahkan ke server dedicated, biayanya turun menjadi sekitar 1/10 dari yang sebelumnya dibayarkan ke solusi cloud terkelola, sambil tetap mempertahankan high availability yang sama dan bahkan menurunkan latensi. Salah satu alasannya juga karena noisy neighbor di VPS memperburuk tail latency
Dulu saya menghabiskan banyak uang untuk hal-hal seperti ini, tapi sekarang sudah 4 bulan berjalan di produksi dan hanya perlu pembaruan kecil
Deployment-nya benar-benar sederhana. Tanpa Docker maupun Kubernetes, hanya service systemd dan binary yang di-build di mesin pengembangan lalu di-deploy
Saya juga dulu membayar layanan seperti MaxMind atau IPData, tapi kemudian membuat sendiri layanan geolokasi IP, dan dalam pengujian performanya lebih baik daripada kebanyakan solusi yang sudah ada
Awalnya dimulai sebagai pengganti Uptime Robot, lalu setelah lebih percaya diri saya mengganti PagerDuty. Setelah itu mengganti Intercom
Terakhir, saya selalu mendengar "jangan membangun stack pembayaran sendiri", tapi saya pikir YOLO dan memutuskan untuk melakukan kesalahan itu sendiri. Saya mempelajari solusi pembayaran yang ada, mengembangkan dan men-deploy-nya sendiri, dan sejauh ini sama sekali belum ada masalah
Di bagian depan saya menaruh Caddy
Saya menyadari bahwa dari fitur yang ditawarkan kebanyakan produk SaaS, sebenarnya saya hanya memakai 1~5%-nya, dan fitur yang benar-benar dibutuhkan justru makin terkubur di dalam platform “kelas enterprise” seperti itu sehingga workflow jadi lebih sulit
Produk komersialnya tidak akan saya tunjukkan karena partner dan pelanggan mungkin tidak akan suka mengetahui betapa murahnya saya, tapi saya menyebut ini akal-akalan yang cerdas
Aplikasi gratisnya bisa saya tunjukkan. Baru dirilis belakangan ini dan sudah punya lebih dari 20 ribu pengguna: https://macrocodex.app/
Aplikasi ini hanya memakai klon Zendesk. Email ditangani lewat routing Cloudflare sehingga biaya operasionalnya nyaris nol
Ada jurang besar antara file dan database multi-partisi. Menjalankan database di dalam container saat produksi nyata bergantung padanya bukan selera saya
Secara pribadi, banyak ETL bisa diproses secara lokal tanpa menarik database enterprise. Dalam kasus seperti itu, DuckDB 5~10 kali lebih baik daripada SQLite, dan jauh lebih sederhana serta lebih cepat daripada menjalankan database Postgres dedicated
Untuk scripting umum, skrip awk 20 baris tidak ada bandingannya dengan skrip SQL setara berbasis DuckDB yang jauh lebih bersih, tangguh, dan mudah dirawat
Semoga MotherDuck tidak berada dalam situasi harus melakukan pump and dump demi IPO. Akan sedih kalau kita kehilangan alat ini karena keserakahan korporat yang terlalu umum terjadi
Menarik soal skrip awk 20 baris itu. Kemarin saya membuat argumen yang hampir sama di Ubuntu Summit. Pada titik tertentu, menulis shell script dengan GNU coreutils menjadi tidak realistis, dan skrip SQL DuckDB jauh lebih baik dalam hal kompleksitas, maintainability, dan sering kali juga performa saat skalanya membesar. Slide-nya ada di sini: https://blobs.duckdb.org/slides/duckdb-ubuntu-summit-2026.pd... halaman 32~36
Selain itu MotherDuck mengembangkan DBaaS closed-source di atas DuckDB. Mereka membangun di atas DuckDB, dan terhubung ke MotherDuck dengan DuckDB, tetapi itu adalah perusahaan terpisah yang didanai VC dan berbasis di Seattle
DuckDB dikembangkan oleh DuckLabs, perusahaan bootstrap berbasis pendapatan di Amsterdam. Kekayaan intelektual proyek ini dimiliki oleh organisasi ketiga, yaitu DuckDB Foundation, lembaga nirlaba di Belanda. Detailnya bisa dilihat di https://duckdb.org/faq#how-are-duckdb-the-duckdb-foundation-...
Saya membuat library yang memungkinkan update konkuren secara aman pada SQLite DB yang ada di S3[0]
Saya menggunakan ekstensi SQLite sessions yang kurang dikenal dan compare-and-swap S3 pada file metadata kecil agar bisa bekerja dengan cukup efisien dan aman. Saya senang memakainya di berbagai proyek kecil yang butuh DB stateful di fungsi Lambda tetapi tidak ingin membayar biaya instance database penuh
[0]: https://github.com/psanford/s3db
SQLite punya performa yang mengejutkan bagusnya untuk aplikasi single-node, bahkan dibandingkan Postgres
Postgres memakai memori jauh lebih banyak, dan I/O harus melewati komunikasi antarproses. Sementara SQLite bisa menaruh semuanya di dalam proses lewat shared connection pool
Saya sedang menguji beberapa storage engine untuk agent harness, dan dengan SQLite saya bisa mencapai 7,5 ribu sesi konkuren pada satu vCPU tunggal, sedangkan Postgres crash atau kehabisan koneksi
[0] https://github.com/impalasys/talon/pull/23#issuecomment-4577...
Begitu Anda keluar dari thread saat ini, dari sisi latensi itu sudah jadi permainan yang kalah. Jika Anda tidak memaksa komunikasi antarthread, SQLite bisa beroperasi pada skala waktu mikrodetik
Dalam konteks single-node, Postgres itu berlebihan. Tidak semestinya diharapkan bersaing dengan SQLite
Ini hampir seperti membandingkan HashMap yang nyaris in-memory dengan Redis, lalu terkejut karena HashMap tampil baik dalam kondisi ideal
Selama bertahun-tahun membaca pembahasan tentang SQLite, lalu mencobanya untuk proyek pribadi, saya kaget karena sistem tipenya sangat minim setelah terbiasa memakai Postgres
Rasanya benar-benar inferior, jadi saya tidak paham kenapa begitu banyak dipuji
https://sqlite.org/datatype3.html
https://www.postgresql.org/docs/current/datatype.html
Cara menangani tanggal/waktu terasa seperti memakai basis data berusia 30 tahun, dan saat insert tidak ada yang benar-benar dipaksakan. Seseorang harus menjelaskan kenapa begitu banyak orang menyukainya
PRAGMA journal_mode = WAL
PRAGMA foreign_keys = ON
Something non-null
PRAGMA busy_timeout = 1000This is fine for most applications, but see the manual
PRAGMA synchronous = NORMALIf you use it as a file format
PRAGMA trusted_schema = OFFBergantung pada binding-nya, opsi tambahan mungkin diperlukan. Misalnya, aplikasi Python seharusnya tidak memakai nilai default modul sqlite3. Default itu memang salah. Sebelum 3.12 bahkan tidak ada alternatif selain memakai binding di luar standard library: https://docs.python.org/3/library/sqlite3.html#transaction-c...
Anda juga harus memakai strict table. https://www.sqlite.org/stricttables.html
Dari sisi ergonomi jelek, tapi constraint CHECK juga bisa dipakai. Misalnya, ini mungkin dilakukan dengan dukungan tanggal bawaan SQLite, tetapi terasa canggung:
CHECK (
date(my_date_col) IS NOT NULL
AND my_date_col = date(my_date_col)
)
Alasan IS NOT NULL diperlukan adalah karena date mengembalikan NULL untuk tanggal yang tidak valid. Pemeriksaan lainnya ada karena itu juga menerima Julian day, jadi date('2026') menjadi suatu waktu pada tahun 4707 SM
Saya setuju bahwa ini mengecewakan, terutama sebelum strict table ada
Anda sebaiknya melihat DuckDB. Ini mendekati SQLite dengan tipe data yang benar. Hanya saja, bukan OLTP, yaitu array of structs, melainkan OLAP, yaitu struct of arrays, jadi performanya bisa lebih buruk untuk beban SQLite yang umum. Meski begitu, untuk aplikasi yang benar-benar mempertimbangkan salah satu dari keduanya, sepertinya perbedaannya tidak akan besar
Setelah memakai beberapa cluster Postgres besar, saya pindah ke SQLite, dan layanan dengan pengguna aktif bulanan 7 digit sekarang sepenuhnya ditopang oleh SQLite durable objects
Pola aksesnya memang harus dipikirkan secara berbeda, tetapi keuntungannya sangat sepadan
Ini framing yang bagus. Jika masalah utamanya adalah menyimpan state workflow secara durable, membuatnya bisa diinspeksi, dan mudah dipulihkan, SQLite sering kali sudah cukup
Saya ingin segera melihat iterasi berikutnya dari ide ini: “workflow durable hanya butuh log”
Salah satu alasan solusi bergaya “hanya butuh log” bisa gagal adalah ketika log yang tidak tepercaya menjadi serangan injeksi[1]
Periksa SBOM, dan jangan lupa memasukkan pipeline CI/CD juga[2]
[1] https://news.ycombinator.com/item?id=48315440
[2] https://github.com/jqwik-team/jqwik/issues/708#issuecomment-...
Kalau serius, menjadi ahli berarti memakai alat yang tepat untuk pekerjaan yang tepat