3 poin oleh GN⁺ 4 jam lalu | 1 komentar | Bagikan ke WhatsApp
  • Ekstensi durable function yang menangani retry, penjadwalan, fan-out paralel, dan percabangan kondisional di dalam PostgreSQL hanya dengan DSL SQL kecil
  • Berjalan hanya dengan Postgres dan background worker tanpa container atau layanan eksternal
  • Semua tahap mencatat status sebagai checkpoint di PostgreSQL sehingga dapat dilanjutkan dari titik terhenti meski terjadi crash, restart, atau koneksi terputus
  • Tanpa perlu mengimplementasikan sendiri manajemen antrean, pelacakan status, pemulihan crash, koordinasi tahap, dan retry, cukup tulis SQL dan engine orkestrasi yang menangani sisanya
  • Pekerjaan yang jika diimplementasikan langsung membutuhkan lebih dari 300 baris boilerplate dapat digantikan dengan satu pemanggilan DSL, dan langsung tersedia sebagai open source di PostgreSQL 17

Gambaran umum dan nilai utama

  • Crash-proof durable function yang tertanam di Postgres, mengorkestrasi retry, penjadwalan, fan-out paralel, dan percabangan kondisional dengan DSL SQL kecil
  • Berjalan hanya dengan Postgres + background worker tanpa infrastruktur tambahan; tidak memerlukan container terpisah atau layanan eksternal
  • Berperan sebagai engine orkestrasi yang menangani manajemen antrean, pelacakan status, pemulihan crash, koordinasi tahap, dan retry; pengguna cukup menulis SQL

Jika diimplementasikan tanpa pg_durable

  • Untuk menjalankan 3 agregasi secara paralel lalu memperbarui dashboard sambil menambahkan retry dan pemulihan crash, dibutuhkan lebih dari 300 baris boilerplate
    • Hal yang harus dibangun sendiri: penyiapan dan konfigurasi antrean, manajemen worker dan polling, pemrosesan pesan dan pelacakan status, penanganan error dan retry, serta koordinasi tahap manual
    • Contoh kode mencakup banyak tabel status seperti job_queue, job_results, job_state, workflow_steps, step_variables, scheduled_jobs, serta polling worker, progres workflow, pemulihan crash, koordinator eksekusi paralel, pengiriman variabel, penjadwalan, dan fungsi pembersihan
    • Perhitungan next_run untuk penjadwalan juga memerlukan library parser cron eksternal tambahan

Jika diimplementasikan dengan pg_durable

  • Agregasi paralel yang sama + pembaruan dashboard dapat diekspresikan dengan satu pemanggilan df.start(), menggunakan operator & untuk fan-out lalu ~> untuk join
    • Contoh: 3 kueri bercabang paralel lalu bergabung ke tahap refresh dashboard untuk menghasilkan hasil
    • Dalam contoh eksekusi langsung, setelah 3 tahap berjalan paralel lalu join, status dashboard ready tercapai secara durable hanya dalam 1,9 detik
  • Manajemen antrean, pelacakan status, pemulihan crash, koordinasi tahap, dan retry semuanya ditangani oleh pg_durable

Fitur utama

  • Durable secara default

    • Semua tahap mencatat status sebagai checkpoint di PostgreSQL, sehingga workflow tetap bertahan meski terjadi crash, restart, atau koneksi terputus
    • Dilanjutkan persis dari titik terhenti
  • Retry otomatis

    • Logika retry bawaan untuk pekerjaan yang flaky; saat suatu tahap gagal, hanya tahap itu yang di-retry sementara workflow lainnya tetap berjalan
    • Tidak perlu kode penanganan error manual
  • Observabilitas penuh di SQL

    • Semua status workflow disimpan di tabel Postgres, sehingga riwayat eksekusi, output tahap, dan debugging kegagalan bisa dilakukan dengan SQL standar
    • Tidak memerlukan dashboard eksternal
  • Eksekusi paralel

    • Fan-out pekerjaan independen dengan operator & atau df.join(), menjalankan agregasi, pemanggilan API, dan tahap ETL secara bersamaan dengan koordinasi otomatis

Pola yang bisa dibuat

  • Pipeline ETL

    • Menghubungkan cleanup → transform → load dengan jaminan urutan, setiap tahap menunggu tahap sebelumnya dan menghentikan pipeline secara bersih jika gagal (~> sequence, |=> variables)
  • Agregasi Paralel

    • Menjalankan agregasi jumlah pengguna + total pendapatan + pemeriksaan inventaris secara bersamaan, fan-out ke beberapa kueri lalu menunggu semuanya selesai (&, df.join())
  • Pemrosesan Pesanan

    • Menangkap ID pesanan lalu meneruskannya ke tahap validasi, pemrosesan, dan penyelesaian, dengan aliran variabel otomatis antar tahap (|=> capture, $var substitution, df.sleep())
  • Job Terjadwal

    • Polling API, pengarsipan record, dan sinkronisasi data dengan jadwal cron, dengan loop yang berjalan permanen dan tetap bertahan setelah restart (@> loop, df.wait_for_schedule())
  • Percabangan Kondisional

    • Memeriksa pekerjaan tertunda, jumlah baris, atau flag untuk bercabang ke proses atau lewati, dengan logika percabangan berada di SQL, bukan di aplikasi (df.if(), ?> conditional)
  • Validasi Multi-tahap

    • Mengambil data → memvalidasi skema → memeriksa aturan bisnis → menyetujui/menolak, dengan setiap tahap di-checkpoint sehingga progres tidak hilang meski gagal
  • Pemeliharaan Database

    • Mendeteksi faktor penghambat autovacuum, bloat tabel, dan risiko wraparound untuk ditampilkan ke proses review, lalu memperbaikinya secara durable bahkan setelah restart setelah persetujuan diterima (?> conditional, df.wait_for_signal(), @> loop)
  • Azure Functions & HTTP

    • Memanggil Azure Functions atau endpoint HTTPS yang diizinkan langsung dari SQL dengan df.http(), untuk menangani chunking dokumen, pengayaan baris, dan klasifikasi record secara inline
  • Persetujuan Human-in-the-Loop

    • Menyetujui otomatis pekerjaan rutin, dan untuk pekerjaan berisiko tinggi (faktur besar, operasi destruktif) menjeda hingga ada sinyal persetujuan manusia (df.wait_for_signal(), df.if())

Bantuan penulisan berbasis AI

  • Jika workflow dijelaskan dalam bahasa Inggris biasa, Copilot akan menghasilkan SQL durable-function yang benar, sehingga cukup menjelaskan apa yang diinginkan tanpa perlu mempelajari sintaks
  • Repositori juga menyertakan skill agen yang dapat digunakan ulang, pg-durable-sql, untuk mengajarkan GitHub Copilot dan agen lain cara menghasilkan SQL yang benar untuk operator, substitusi variabel, loop, parallel join, dan lainnya

Tersedia sebagai open source

  • Disediakan sepenuhnya sebagai open source tanpa daftar tunggu atau lock-in, sehingga repositori dapat di-clone, di-build, dan langsung dijalankan di PostgreSQL Anda sendiri
  • Dapat menerapkan durable orchestration di laptop, server, maupun cloud

Opsi terkelola Azure HorizonDB

  • Azure HorizonDB adalah layanan cloud PostgreSQL baru dari Microsoft, dengan pg_durable bawaan, sehingga durable function yang ditulis tetap bisa dipertahankan sambil menambahkan skala enterprise, keamanan, dan AI
    • Performa hingga 3× lebih cepat, auto-scaling storage hingga 128 TB, scale-out compute hingga 3.072 vCore
    • Deteksi ancaman real-time Microsoft Defender, manajemen identitas Microsoft Entra ID
    • Filtered DiskANN vector search, semantic ranking, dan kurasi model AI in-database
    • Mirroring hampir real-time Microsoft Fabric, integrasi VS Code, dan keterhubungan dengan GitHub Copilot
  • Pipeline AI bawaan

    • HorizonDB melapisi pipeline AI end-to-end terkelola di atas eksekusi durable pg_durable, dengan setiap tahap aman terhadap checkpoint, retry, dan crash
    • Alur tahap: Ingest (memuat dokumen/data) → Chunk (memecah konten) → Embed (vektorisasi) → Index (penyimpanan DiskANN) → Serve (pencarian dan ranking)

1 komentar

 
GN⁺ 4 jam lalu
Komentar Hacker News
  • Tahun 2026 tampaknya akan menjadi tahunnya antrean Postgres: ada arus seperti DBOS[0], pgQue[1], dan keren melihat komunitas membuat opsi seperti ini
    Namun, dari sudut pandang mantan application engineer, saya lebih suka logika antrean berada di kode dan di Git. Mungkin pendapat saya bisa berubah kalau ada tool yang tepat
    [0]: https://www.dbos.dev/
    [1]: https://github.com/NikolayS/pgque

    • Mungkin cara kerjanya memang lebih sulit atau sekadar berbeda, tetapi tampaknya masih kurang dokumentasi, tulisan yang bisa dicari, pengalaman, dan alat
      Saya penasaran bagaimana version control, debugging, testing, dan rilis dilakukan. Menaruh semuanya di satu tempat demi localitas data dan penyederhanaan stack memang terlihat bagus, tetapi rasanya banyak pengetahuan berguna tentang cara melakukannya dengan “benar” jadi hilang
    • Saya setuju dengan “logika antrean ingin saya taruh di kode”. Aksi yang harus dilakukan terhadap data itu berubah jauh lebih sering daripada datanya sendiri, jadi saya tidak paham kenapa harus melakukan migration setiap kali ingin mengubah aksinya
      Itulah juga alasan saya sangat tidak suka bahwa di Supabase, begitu ingin melakukan sesuatu yang sedikit kompleks, saya harus membuat fungsi Postgres. Meski begitu, di startup saya sebelumnya kami memang pernah membangun antrean kerja sederhana sendiri di atas Postgres, dan kalau saat itu ada sesuatu seperti pgQue, hasilnya mungkin akan jauh lebih rapi
    • Saya sudah jadi penggemar sejak era Postgres 7 dan pernah bereksperimen menaruh sebanyak mungkin hal ke dalam PostgreSQL, tetapi setidaknya developer experience dan observability masih kurang
      Ekstensi multi-master juga bukan sesuatu yang bisa langsung dipakai dan sepenuhnya aman, jadi saya berhati-hati memasukkan pekerjaan kompleks yang padat tulis, yang bisa mempercepat kebutuhan akan skalabilitas database
    • Di proyek yang punya trigger DB, kami juga menaruh kode SQL di Git untuk dikelola
      Saat setup lokal, kadang kami bahkan menyelipkannya ke migration Django agar trigger masuk ke database lokal
  • Ini berbau stored procedure. Sulit untuk unit test maupun version control, dan business logic tersembunyi di dalam database menjadi semacam “otak tersembunyi”
    Sulit juga mengisolasi workload yang berisik, tidak ada observability, dan semua tekanan skalabilitas menumpuk ke Postgres. Terutama karena kemampuan input/output seperti pemanggilan API kurang. Untuk pekerjaan yang hanya berjalan di dalam database lokal, ini mungkin oke, tetapi kelihatannya use case-nya sempit

    • Stored procedure juga sangat bagus kalau dipakai dengan benar. Version control bisa dilakukan dengan ID yang terus meningkat di akhir nama, lalu saat perlu perubahan yang breaking, ID-nya dinaikkan, dan versi lama dibiarkan tetap ada sampai tidak dipakai lagi
      Tentu saja, harus ada prosedur upgrade database yang benar. Kalau anggota tim menjalankan migration SQL sembarangan dengan akses root, Anda akan kerepotan
      Unit test juga bisa dilakukan sama seperti testing SQL lain, hanya saja Anda perlu menyalakan database. Kalau stored procedure tidak bisa dites, berarti SQL itu sendiri juga tidak punya cara untuk dites, dan itulah masalah yang sebenarnya
      Alternatif dari stored procedure bukan berarti tidak menaruh business logic di database sama sekali, melainkan sering kali SQL jadi tersebar di berbagai bagian codebase, sulit diuji, buruk dalam version control dan enkapsulasi, serta menjadi lambat tanpa perlu
      Soal observability itu ada benarnya sampai batas tertentu; menelusuri masalah SQL memang biasanya lebih merepotkan dibanding kebanyakan bahasa pemrograman. Tetapi kalau stored procedure justru menimbulkan masalah input/output dan skalabilitas, berarti itu digunakan dengan keliru; kalau dipakai dengan benar, justru sering kali sangat mengurangi input/output dan meningkatkan skalabilitas
  • Kalau saya memahaminya dengan benar, Absurd yang dibuat para pengembang Pi LLM harness tampaknya bergerak ke arah meminimalkan akses database murni sebisa mungkin. Saya sendiri baru mulai melihat topik ini
    https://github.com/earendil-works/absurd

    • Sedikit koreksi, absurd tampaknya adalah proyek asli earendil yang sudah dimulai sebelum Mario Zechner bergabung ke earendil, dan saya juga tidak melihat commit darinya
      Tentu saja saya tidak tahu semua detailnya, jadi saya benar-benar penasaran
  • Di bagian “kapan tidak sebaiknya digunakan” tertulis “ketika workflow sebagian besar berada di luar Postgres dan melintasi beberapa sistem heterogen”, tetapi kalau begitu saya tidak tahu bagaimana proyek ini bisa dibandingkan dengan Temporal atau yang sejenis
    Saya penasaran apakah saya salah memahami batasan yang diisyaratkan rekomendasi itu

    • Setuju. Melihat contoh https://github.com/microsoft/pg_durable/blob/main/examples/i..., saya tidak terlalu paham apa nilai proyek ini
      Secara teknis ini mungkin pencapaian yang menarik, tetapi membaca SQL seperti ini terasa cukup ganjil
      SELECT df.start(
      @> (
      ($$SELECT ... FROM demo.invoices WHERE status = 'pending'$$ |=> 'inv')
      ~> df.if_rows('inv',
      $$UPDATE ... SET status = 'processing'$$
      ~> (df.http(...) |=> 'resp')
      ~> df.if($$SELECT $r.ok$$,
      -- classify, branch, wait for signal ...
      ),
      df.sleep(5)
      )
      ),
      'invoice-approval-pipeline'
      );
  • Di perusahaan kami terikat ke Azure, dan masih terus menunggu Azure PostgreSQL menyusul fitur-fitur modern
    Misalnya, kami tidak bisa memakai ini: https://www.paradedb.com/blog/hybrid-search-in-postgresql-th...
    Vektor berdimensi tinggi yang sangat lebar juga tidak didukung. Merilis pg_durable sebagai open source memang bagus, tapi saya jadi berpikir, bagaimana kalau mulai dengan menghadirkan dulu fitur-fitur dasar yang di AWS sudah bisa didapat dengan mudah

    • ParadeDB berlisensi AGPL, jadi umumnya sulit disediakan oleh penyedia cloud besar. Namun, di Azure HorizonDB Anda bisa menggunakan https://github.com/timescale/pg_textsearch, dan ada kemungkinan besar segera masuk ke Flex juga
      Sekadar disclosure, saya adalah maintainer pg_textsearch dan sekarang bekerja di Azure. Saya kurang paham maksud komentar soal dukungan vektor—apakah yang diinginkan adalah sesuatu yang melampaui pgvector + diskann yang disediakan Azure?
    • Untuk pencarian vektor, rasanya Azure Cosmos DB lebih cocok, bukan?
    • Mungkin ini sudah dipertimbangkan, tapi saya penasaran kenapa tidak cukup membuat bare VM lalu memasang Postgres versi terbaru?
    • Saya PM di tim Azure PG yang menangani fitur AI untuk Postgres. Fitur-fitur yang diminta sebenarnya sudah tersedia, dan dalam 3–6 bulan terakhir ada banyak kemajuan
      Untuk pencarian hibrida (BM25 + vektor), pg_search dari ParadeDB juga bukan fitur native AWS dan harus di-host sendiri di EC2. Di Azure PostgreSQL, kami telah membuat pg_textsearch secara native yang menyediakan model peringkat BM25 yang sama, dan kontributor utamanya sekarang ada di tim Azure Postgres
      Dokumentasi: https://learn.microsoft.com/en-us/azure/horizondb/ai/full-te...
      Untuk vektor berdimensi tinggi, justru ini area yang lebih unggul. pgvector yang memakai HNSW memiliki batas 2.000 dimensi, tetapi Azure mendukung pgvector untuk penyimpanan dan pencarian vektor, dan untuk workload berdimensi tinggi berskala besar menyediakan pg_diskann, indeks vektor berbasis graf milik Microsoft. Ini mendukung hingga 16.000 dimensi, serta filtering tingkat lanjut di dalam indeks yang mengevaluasi kondisi WHERE selama penelusuran graf, sehingga tidak kehilangan recall pada kondisi yang selektif
      pgvector: https://learn.microsoft.com/en-us/azure/horizondb/ai/vector-...
      Dukungan DiskANN untuk dimensi tinggi: https://learn.microsoft.com/en-us/azure/horizondb/ai/vector-...
      Fitur-fitur ini saat ini tersedia di Azure PostgreSQL, khususnya Azure HorizonDB Preview. Jika ada workload tertentu, saya bisa melihatnya lebih spesifik
  • Ini terasa seperti solusi yang keliru untuk masalah lama yang sudah diselesaikan sejak dulu oleh scheduler DAG seperti Apache Airflow
    Rasanya aneh ingin menyimpan control flow di database alih-alih di kode. Bukan bermaksud meremehkan proyeknya, saya cuma masih belum benar-benar memahaminya

    • Microsoft punya framework Durable Task[1] untuk penggunaan seperti ini, yang bisa dijalankan sebagai layanan independen self-hosted seperti Temporal, dan juga bisa berjalan secara serverless di Azure Functions. Kalau saya ingat benar, ini bahkan lebih dulu muncul daripada Airflow dan Temporal
      Proyek ini tampaknya lebih ditujukan ke use case yang spesifik untuk database. Keuntungannya mungkin Anda bisa melacak status persis dari suatu pekerjaan langsung di database itu sendiri, tanpa harus menelusuri log workflow dan codebase baris demi baris. Beban dan latensinya juga mungkin lebih kecil, dan secara operasional ada satu komponen lebih sedikit yang perlu dijalankan
      [1] https://learn.microsoft.com/en-us/azure/durable-task/common/...
    • Alat eksternal seperti Airflow tidak bisa mengetahui beban database. Jika developer menghantam database dengan 200 worker paralel, workload lain bisa ikut terdampak
      Sebaliknya, pendekatan ini—meskipun tampaknya belum bekerja seperti itu saat ini—berpotensi menyesuaikan diri sendiri dengan menerima umpan balik performa hampir real-time tanpa biaya latensi bolak-balik
  • Bahkan setelah membaca dokumentasi dan contohnya, masih ada beberapa hal yang belum jelas. Saya penasaran bagaimana df.wait_for_schedule() bekerja
    Jika dipanggil dari aplikasi, apakah ini idempoten? Jika dijalankan dua kali dengan parameter yang sama, apakah tick akan terjadi dua kali? Apakah ini sesuatu yang dipanggil manual sekali dari konsol kueri, atau dijalankan sebagai bagian dari skrip migrasi? Saya juga penasaran apakah timed_out pada contoh[0] adalah konstanta tetap yang dikembalikan saat timeout. Juga tidak langsung terlihat bagaimana penanganan error atau exception dilakukan
    [0] https://github.com/microsoft/pg_durable/blob/main/examples/i...

    • Saat df.start() dipanggil, itu membuat fungsi durable dan sekaligus mulai menjalankannya. Pemanggilan ini mengembalikan instance ID yang merepresentasikan eksekusi tersebut, dan itu bisa dipakai untuk merujuk eksekusi itu setelahnya
      Di dalam fungsi durable ini, df.wait_for_signal() dipanggil, dan pemanggilan ini hanya dieksekusi tepat satu kali di dalam instance fungsi tersebut, jadi duplikasi tidak mungkin terjadi. Jika pemanggilan df.start() sendiri timeout lalu dijalankan ulang, duplikasi bisa terjadi, tetapi dalam kasus itu instance fungsi yang berbeda akan dibuat
      Jika terjadi error yang tidak tertangani selama eksekusi SQL, instance fungsi akan gagal, dan statusnya akan memuat persis error yang terjadi
  • Bisakah dijelaskan kenapa seseorang harus memakai ini alih-alih alat orkestrasi di luar database. Bahkan setelah membaca README dan contoh-contohnya, saya masih belum paham

    • Jika memakai snapshot PITR database, semua pekerjaan durable hingga titik waktu tertentu juga ikut dipulihkan
      Tidak perlu menyinkronkan backup dengan komponen lain yang berada pada penyimpanan data yang sama, jadi ini bagus untuk pipeline ETL atau pekerjaan bergaya state machine. Jika ETL-nya sebagian besar adalah SQL, juga membantu karena pekerjaan nyatanya berjalan di server yang sama
    • Dari sudut pandang kontributor, pelanggan Postgres Microsoft tampaknya terbagi cukup merata menjadi dua kelompok. Kelompok yang ingin melakukan sebanyak mungkin hal di dalam database, dan kelompok yang ingin menyimpan aplikasi dan komputasi di luar database
    • Ini kadang praktis jika dalam arsitektur, database adalah satu-satunya komponen yang menyimpan state
      Jika semua state ada di satu database, peluang untuk mendapatkan backup yang konsisten juga lebih tinggi
    • Ini bisa terintegrasi dengan baik dengan workflow aplikasi. Misalnya, memungkinkan menampilkan progres dari permalink di aplikasi frontend, membuat workflow yang tetap berlanjut setelah aplikasi di-restart, dan tanpa perlu menambah satu komponen infrastruktur lagi
      Di https://transport.data.gouv.fr, Postgres dipakai untuk tujuan seperti itu, dan itu membantu dalam aplikasi Elixir yang melakukan cukup banyak pemrosesan. Saya sendiri belum terlalu tahu soal pg_durable, tetapi saya pernah memakai atau mengimplementasikan solusi serupa jadi bisa memahami idenya
  • Bukankah database sudah termasuk salah satu infrastruktur yang paling sulit diskalakan. Saya tidak paham kenapa orang ingin menambahkan pekerjaan berjalan lama di sana

    • Menjalankan pekerjaan berjalan lama di Postgres sama sekali bukan hal baru. pg_cron adalah salah satu contohnya
      Pada akhirnya, workload seperti ini adalah pekerjaan yang memang akan dieksekusi terhadap database, baik dipicu oleh komponen eksternal maupun tidak. Dalam pipeline data atau AI, mengirim kueri HTTP dari database juga makin umum untuk menghindari round-trip tambahan dan titik kegagalan dari komponen ekstra. Tetapi, apakah komputasi dibawa ke data atau data dibawa ke komputasi adalah pilihan desain besar yang memang masih diperdebatkan
  • Ini terasa seperti satu lagi https://en.wikipedia.org/wiki/Inner-platform_effect yang mungkin tidak diperlukan andaikan bahasa pemrograman atau virtual machine populer sudah mendukung determinisme, eksekusi langkah demi langkah yang bisa diukur dan dikendalikan, penghentian sementara state runtime, serialisasi/deserialisasi, dan melanjutkan eksekusi