- Workflow durable melakukan checkpoint status eksekusi ke database sehingga dapat dipulihkan dari langkah terakhir yang selesai setelah crash
- Orkestrasi eksternal ala Temporal, Airflow, dan AWS Step Functions menambah orkestrator pusat dan penyimpanan sehingga kompleksitas meningkat
- Arsitektur berbasis Postgres memungkinkan server aplikasi mem-polling tabel workflow dan menyimpan output langkah secara langsung agar bisa dipulihkan
- Banyak server mencegah eksekusi ganda dengan lock dan integrity constraint, serta menangani masalah skalabilitas, ketersediaan, dan observabilitas dengan solusi Postgres
- Satu instance Postgres dapat diskalakan secara vertikal hingga puluhan ribu workflow per detik, sambil tetap memanfaatkan replikasi, multi-AZ, dan analisis SQL
Model dasar workflow durable
- Workflow durable adalah pendekatan yang secara berkala menyimpan status kemajuan selama eksekusi program sebagai checkpoint di database, sehingga setelah crash atau kegagalan dapat dipulihkan dari langkah terakhir yang selesai
- Seperti save dan load dalam video game, ini bisa dilihat sebagai model yang secara berkala “menyimpan” progres program lalu “memuatnya” kembali dari checkpoint terakhir setelah crash
- Implementasi yang umum adalah sistem orkestrasi eksternal seperti Temporal, Airflow, dan AWS Step Functions
- Dalam orkestrasi eksternal, program durable ditulis sebagai workflow yang terdiri dari beberapa langkah, lalu orkestrator pusat mengoordinasikan eksekusinya
Cara kerja orkestrasi eksternal
- Saat klien mengirim workflow, orkestrator membuat record di data store lalu mendistribusikannya ke worker untuk dieksekusi
- Setiap kali worker menyelesaikan suatu langkah, hasilnya dikirim ke orkestrator, lalu orkestrator melakukan checkpoint output tersebut ke data store sebelum mendistribusikan langkah berikutnya
- Jika worker crash atau gagal, orkestrator mengirim ulang workflow itu ke worker lain dan memulainya dari langkah checkpoint terakhir
- Struktur ini menambah server orkestrator terpisah ke ide inti menyimpan status workflow di database, sehingga kompleksitas meningkat
Arsitektur yang menggunakan Postgres sebagai orkestrator
- Jika inti dari workflow durable adalah melakukan checkpoint status program ke database, maka menggunakan database itu sendiri sebagai orkestrator tanpa server orkestrator terpisah lebih sederhana dan efisien
- Postgres adalah pilihan yang cocok untuk membangun workflow durable karena popularitasnya, skalabilitasnya, dan ekosistemnya yang kaya
- Dalam sistem workflow durable berbasis Postgres, server aplikasi berkomunikasi langsung dengan Postgres tanpa melalui orkestrator pusat untuk menjalankan workflow
- Klien mengirim eksekusi dengan membuat entri di tabel workflow Postgres, lalu server aplikasi mem-polling tabel tersebut untuk dequeue dan mengeksekusi workflow
- Saat menjalankan workflow, server melakukan checkpoint output tiap langkah ke Postgres, dan jika server yang sedang berjalan crash atau gagal, server lain memulihkan workflow dari checkpoint
Mengapa orkestrator pusat menjadi tidak diperlukan
- Server aplikasi dapat berkoordinasi melalui Postgres, sehingga orkestrator pusat tidak perlu mendistribusikan workflow ke worker
- Server dapat secara kooperatif dequeue workflow dari tabel Postgres, dan dengan mekanisme seperti klausa lock dapat menjamin setiap workflow hanya di-dequeue oleh tepat satu worker
- Checkpoint output langkah juga ditulis langsung ke Postgres oleh worker, bukan oleh orkestrator
- Jika beberapa worker mencoba menjalankan workflow yang sama secara bersamaan, integrity constraint Postgres dapat mendeteksi pekerjaan duplikat pada saat checkpoint dan memaksa salah satunya mundur
- Dengan mengganti orkestrator pusat menggunakan Postgres atau database lain, masalah seperti skalabilitas, ketersediaan, observabilitas, dan keamanan dapat ditangani dengan solusi native Postgres yang sudah mapan
Skalabilitas dan ketersediaan
- Skalabilitas dan ketersediaan sistem workflow durable berbasis database pada dasarnya ditentukan oleh database yang mendasarinya
- Karena server worker dapat ditambah untuk scale out secara horizontal, kapasitas maksimum bergantung pada seberapa cepat database dapat memproses workflow
- Worker dapat saling menggantikan dan memulihkan status satu sama lain, sehingga sistem tetap tersedia selama database yang mendasarinya tersedia
- Saat menggunakan Postgres, keunggulannya adalah skalabilitas dan ketersediaan merupakan masalah yang sudah lama diteliti dan memiliki solusi yang kuat
- Satu server Postgres dapat diskalakan secara vertikal untuk menangani puluhan ribu workflow per detik
- Skalabilitas tambahan dapat dicapai dengan menggunakan Postgres terdistribusi seperti CockroachDB atau Postgres yang di-shard
- Postgres mendukung streaming replication dengan failover otomatis, dan layanan terkelola menyediakan deployment multi-AZ serta SLA high availability secara bawaan
- Rekayasa dan riset selama puluhan tahun yang terakumulasi untuk mengoperasikan Postgres dalam skala besar juga dapat langsung dimanfaatkan untuk mengoperasikan workflow durable
Observabilitas
- Dalam eksekusi durable berbasis Postgres, workflow dan langkah di-checkpoint ke tabel Postgres, sehingga checkpoint tersebut dapat dipindai untuk memantau workflow secara real time dan memvisualisasikan eksekusi
- Postgres unggul karena hampir semua query observabilitas workflow dapat diekspresikan dengan SQL
- Tugas analisis dan filtering yang kompleks, seperti query untuk menemukan semua workflow yang mengalami error selama sebulan terakhir, dapat dinyatakan secara deklaratif dengan SQL
- Hal ini dimungkinkan karena memanfaatkan model relasional Postgres dan puluhan tahun riset optimisasi query
- Banyak sistem dengan model data yang lebih sederhana, seperti key-value store yang digunakan oleh orkestrator eksternal populer, tidak dapat memberikan dukungan analisis berbasis SQL pada tingkat yang sama
- Dengan menyimpan data workflow dan langkah di tabel Postgres serta menambahkan indeks sekunder untuk query analisis yang cepat, kita bisa memperoleh observabilitas yang efisien dalam eksekusi durable
Keandalan dan keamanan
- Dalam eksekusi durable yang menggunakan orkestrator eksternal, orkestrator dan data store-nya sama-sama menjadi single point of failure
- Karena orkestrator dan data store langsung mengoordinasikan eksekusi workflow, jika salah satunya down maka seluruh aplikasi menjadi tidak dapat digunakan
- Keduanya juga menangani dan menyimpan workflow serta checkpoint langkah, sehingga berpotensi mengakses data aplikasi yang sensitif dan perlu diperkeras, dikontrol aksesnya, serta diaudit seperti infrastruktur sensitif lainnya
- Dalam eksekusi durable berbasis Postgres, satu-satunya titik kegagalan adalah Postgres itu sendiri, dan semua data workflow disimpan langsung di Postgres tanpa melewati sistem lain
- Jika aplikasi sudah bergantung pada Postgres, maka mengadopsi eksekusi durable tidak menambah titik kegagalan baru maupun menciptakan permukaan serangan baru yang perlu dilindungi
- Karena database sudah menjadi infrastruktur inti, lebih masuk akal untuk menggunakan kembali database yang ada daripada menambahkan infrastruktur inti baru khusus untuk orkestrasi
Pelajari lebih lanjut
1 komentar
Komentar Hacker News
absurdkarya Armin Ronacher adalah implementasi workflow tahan lama untuk Postgreshttps://lucumr.pocoo.org/2025/11/3/absurd-workflows/
https://github.com/earendil-works/absurd
https://earendil-works.github.io/absurd/
Saya belum mencobanya sendiri, tetapi ini layak dibandingkan dengan opsi lain
absurddan turunan implementasi Rust bernamadurablemenurut saya adalah pilihan bagus yang menjaga sisi klien tetap sangat sederhanaKarena ringan, agen coding bisa dengan mudah memahami seluruh strukturnya, dan bila perlu statusnya bisa dicek lewat query
Saya memakai dbos.dev, restate.dev, dan cf workflows, dan di Agents.md kami tertulis seperti ini
Restate.dev dipakai untuk integrasi pembayaran northflank. Lebih cepat daripada cf workflows, independen dari Cloudflare dan gangguannya, serta bisa self-hosted sehingga tidak ada vendor lock-in
Cloudflare workflows dipakai untuk tugas yang kurang penting seperti pembuatan laporan CSV/PDF. Alasannya karena sangat murah
DBOS.dev dipakai untuk workflow yang butuh messaging atomik yang terikat dengan transaksi Postgres, sehingga memerlukan keandalan/daya tahan 100%. Contohnya mengisi materialized row atau mengirim email/push penting ke merchant
DBOS dan Restate terlihat mirip di permukaan, tetapi Restate memerlukan “orchestrator” terpusat, yang punya plus minus tersendiri dan membuatnya lebih mudah dibangun bersama worker serverless cf/vercel
Selain itu ada VirtualObject, jadi ini lumayan sebagai alternatif open-source tanpa vendor lock-in untuk DurableObject single-threaded milik Cloudflare
Ada dua hal yang benar-benar menonjol dari DBOS. 1) Dengan
dbos.enqueue_workflow, kita bisa melakukan messaging atomik di dalam transaksi DB yang sama dengan logika bisnis. Bagian ini sering kali menjadi titik paling rapuh di berbagai solusi, jadi jika bisa ditangani secara atomik dan tahan lama di transaksi yang sama dengan eksekusi logika bisnis, kompleksitasnya jauh berkurang2) DBOS menyimpan status workflow di DB, jadi sepertinya mudah membuat dashboard observabilitas dengan metabase/looker. Akan bagus juga kalau Restate mengekspor instance rocksdb agar bisa dihubungkan ke metabase
Saya penasaran dengan pengalaman nyata orang-orang yang pernah memakai DBOS dan Temporal
Saya pernah memakai Temporal sebelumnya dan itu bekerja cukup baik, tetapi saya sempat merasa tidak nyaman saat membangun solusi karena batas ukuran payload request atau event
Memang ada kelebihan karena ia memaksa praktik engineering yang baik, tetapi saya juga tidak selalu ingin memakai logika khusus berupa mengunggah file CSV ke S3 lalu meneruskan tautannya dan mengunduhnya kembali di workflow hanya karena file CSV itu lebih besar dari 2MB
Saya ingin tahu seperti apa pengalaman dengan DBOS, dan bagaimana perbandingannya dengan Temporal dari sisi kompleksitas operasional maupun kesetaraan fitur
Di rumah pun saya menjalankannya untuk menangani tugas otomasi rumah yang tidak terlalu sensitif terhadap waktu. Latensi workflow-nya tidak terlalu buruk, tetapi saya rasa saya tidak akan memakainya untuk trigger yang harus merespons seketika seperti event deteksi gerakan di rumah, sedangkan untuk timeout seperti mematikan sesuatu setelah periode tidak aktif, itu masih cocok
Saya cukup menyukai pendekatan menaruh REST API tipis di depan Temporal di dalam VPC atau klaster Kubernetes. Dengan begitu trigger berbasis event tidak perlu memikirkan autentikasi Temporal atau pemeriksaan status workflow, dan ini membantu menjaga event sebisa mungkin tetap tanpa logika
Misalnya trigger DB berjalan langsung atau memasukkan event ke antrean, lalu handler memanggil REST API tipis dengan detail event yang diperlukan. REST API dapat memutuskan apakah ini harus memulai workflow, mengirim signal ke workflow yang sudah ada, atau mengabaikannya. Polanya berbeda-beda tergantung situasi, tetapi dalam kasus saya saya sering memakai
SignalWithStart, atau jika tidak layak memulai dan memang tidak ada workflow yang sudah ada, ya dibuang sajaSelain itu, saat perlu mengorkestrasi aksi-aksi yang saling independen dalam siklus hidup satu objek, fitur parent/child workflow sangat berguna, dan saya juga suka karena ia bisa dibatalkan ketika faktor eksternal mengubah jalur progres objek tersebut
Kalau dijelaskan secara panjang dan agak samar, ini sangat kuat, mudah dipakai, dan sangat membantu memindahkan logika siklus hidup ke luar API. Jika diletakkan di dalam API, utang teknis mudah menumpuk dan pengelolaannya jadi rapuh. Saya setuju bahwa memaksa kita mengikuti praktik terbaik itu lebih baik daripada melempar logika ke tempat yang terlihat mudah lalu belakangan menjadi jebakan tersembunyi
Namun saya sempat mencoba produk Cloud-nya dan kaget dengan harganya. Bahkan sebelum naik ke produksi, kredit gratis sebesar 1.000 dolar sudah habis. Saya juga tidak ingin mengoperasikan Temporal lokal sendiri
Menurut saya pribadi, yang terbaik adalah mengambil idenya dari arsitekturnya lalu mengimplementasikannya sendiri dengan Postgres
Saya tidak 100% puas dengannya. Rasanya seperti tambahan, bukan bagian yang esensial, dan ini juga masih rilis awal. Tetapi setidaknya sekarang masalah itu pada dasarnya sudah teratasi
Setelah menjalankannya di produksi selama lebih dari setahun, menurut saya Temporal didesain dengan buruk, lambat, dan dari sisi infrastruktur benar-benar terlalu berat
Untuk pekerjaan yang tidak sepele, misalnya lebih dari 200 event per workflow dan hanya beberapa ratus yang berjalan bersamaan sepanjang hari, Anda bisa saja menghabiskan jutaan dolar untuk biaya infrastruktur, dan hasilnya tetap saja kurang bagus
Jika menjalankan benchmark sendiri, angkanya buruk
Tim sales-nya juga benar-benar buruk dan terlihat putus asa
Dari sudut pandang developer, SDK-nya cukup bagus
Jangan sampai terkunci di nexus, dan kalau tim sales menelepon, pastikan tim legal ikut ada di ruangan
Butuh waktu untuk memahami cara migrasi dari Celery, tetapi untuk kasus kami itu sepadan
Conductor OSS juga melakukan ini dengan cukup baik https://docs.conductor-oss.org/devguide/ai/index.html
https://github.com/agentspan-ai/agentspan pada dasarnya adalah lapisan SDK agen untuk Conductor, yang bisa membuat agen langgraph, OpenAI, vercel, dan ADK menjadi durable serta menambahkan orkestrasi tanpa perubahan kode
Daripada memisahkan penyimpanan data, state machine, constraint status yang valid, dan logika untuk berpindah antarstatus yang valid, akan bagus kalau semua itu bisa disatukan ke semacam kernel dari status aplikasi
Sejujurnya Postgres sudah punya banyak kemampuan seperti ini, tetapi saya masih belum melihat gambaran yang jelas di level aplikasi atau produk yang menyediakan himpunan status yang dapat dibuktikan untuk transisi aplikasi, lalu otomatis mengeksposnya ke klien dengan cara yang bermanfaat. Misalnya, pengguna ini boleh memberi like pada postingan ini tetapi tidak boleh mengeditnya
Di mata saya ini terlihat seperti bentuk colored Petri net, tetapi saya masih belum melihat paradigma status aplikasi yang sederhana seperti database yang punya batas keberhasilan yang jelas
Hanya saja saya tidak yakin apakah itu benar-benar integrasi penuh
Karena DBOS tidak mendukung Rust, saya mengimplementasikan versi Rust yang sangat minimal dan mirip ini di https://github.com/tensorzero/durable
Ini cukup stabil dan bisa diskalakan, tetapi tentu saja Anda harus sangat berhati-hati dengan implementasi SQL. Semoga ini menarik bagi para pembaca di sini
https://flawless.dev/
Saya sepenuhnya memahami dan setuju dengan konsepnya. Ini cara yang bagus untuk memasukkan jenis durabilitas seperti ini ke dalam sistem workflow
Hanya saja, dengan otak gamer, saya ingin menyebut ini sebagai save scumming skala besar. Banyak orang mungkin sudah tahu bahwa pendekatan ini berhasil, tetapi mungkin belum mengaitkannya dengan konsep ilmu komputer yang abstrak
Strategi lain untuk meningkatkan ketahanan adalah menyusun workflow dari operasi-operasi idempoten. Ini bisa berguna saat status workflow terlalu besar untuk dicadangkan dengan mudah. Sebagai gantinya, jika tugas dijalankan ulang dari awal, semua langkah hingga titik kemajuan terakhir hanya akan menjadi no-op
Saya terus dibuat takjub oleh banyaknya hal yang bisa dilakukan dengan sedikit alat selama Postgres ada di dalam kotak peralatan
Baru-baru ini saya mengembangkan distributed queue dan hasilnya bekerja sangat baik, benchmark-nya juga bagus, serta tidak ada race condition maupun konflik. Saya memakai
SKIP LOCKEDagar para worker bisa bersaing dengan amanJika ingin membuat worker di beberapa node menghindari benturan, Anda juga bisa memakai mutex berskala sesi, yaitu
pg advisory lockSELECT FOR UPDATEtidak akan berskala dengan baikEdit: setelah saya cek lagi, sepertinya sekarang sarannya justru berubah menjadi kebalikannya
Di Rails ada beberapa backend pekerjaan berbasis database, tetapi menurut konvensi, sebuah job harus selalu hanya melakukan satu hal dan, kalau bisa, selesai dengan sangat cepat
Karena itu, membangun workflow terasa agak dipaksakan. Baris terakhir job pertama akan memasukkan job kedua ke queue, lalu baris terakhir job kedua akan memasukkan job ketiga ke queue, dan seterusnya
Backend job tidak menampilkan semuanya sebagai workflow yang saling terhubung, melainkan memperlakukannya sebagai job independen, dan jika ingin memahami workflow pada level tinggi, kita harus membaca beberapa class job
Rails baru-baru ini memperkenalkan konsep continuable yang memungkinkan checkpoint per langkah dan melanjutkan eksekusi di dalam job, tetapi konvensi untuk menjaga job tetap memiliki tanggung jawab tunggal masih sangat kuat, jadi rasanya canggung untuk workflow sungguhan
Saya penasaran apakah orang lain juga mengalami hal seperti ini, dan apakah mereka menemukan solusinya
Ini pola yang sangat bagus. Sebaiknya lakukan sebanyak mungkin pekerjaan di dalam database
Spanner eksternal menyediakan change streams. Spanner internal berbeda; terutama karena dalam beberapa kasus ada kebutuhan skalabilitas yang ekstrem, dan juga campuran alasan "sudah berjalan dengan baik" serta "change stream arbitrer itu menakutkan"
Spanner internal memungkinkan transaksi apa pun menulis entri queue. Di sini queue kurang lebih adalah tabel khusus dengan kesadaran waktu. Anda bisa menjadwalkan pengiriman, dan entri akan didorong dari queue ke handler, sementara handler juga bisa melakukan penulisan ke DB di dalam transaksi dequeue. Dan semua skalabilitas yang sama tetap terjaga