3 पॉइंट द्वारा GN⁺ 5 시간 전 | 1 टिप्पणियां | WhatsApp पर शेयर करें
  • PostgreSQL के भीतर retry, scheduling, parallel fan-out, conditional branching को एक छोटे SQL DSL से संभालने वाला durable function extension
  • container या external service के बिना, केवल Postgres और background worker से काम करता है
  • हर step PostgreSQL में state को checkpoint के रूप में लिखता है, इसलिए crash, restart, या connection टूटने पर भी रुके हुए बिंदु से फिर शुरू होता है
  • queue management, state tracking, crash recovery, step coordination, retry को खुद implement करने की ज़रूरत नहीं; सिर्फ SQL लिखें, orchestration engine बाकी संभालता है
  • सीधे implement करने पर 300+ lines of boilerplate लगने वाले काम को एक DSL call से बदलता है, और PostgreSQL 17 पर open source के रूप में तुरंत इस्तेमाल किया जा सकता है

अवलोकन और मुख्य मूल्य

  • Postgres में built-in crash-proof durable function जो retry, scheduling, parallel fan-out, और conditional branching को छोटे SQL DSL से orchestrate करता है
  • अतिरिक्त infrastructure के बिना केवल Postgres + background worker से चलता है; अलग container या external service की ज़रूरत नहीं
  • queue management, state tracking, crash recovery, step coordination, और retry सब संभालने वाला orchestration engine, उपयोगकर्ता को सिर्फ SQL लिखना होता है

pg_durable के बिना implement करने पर

  • 3 aggregations को parallel में चलाकर dashboard refresh करना हो, और उसमें retry व crash recovery भी जोड़नी हो, तो 300+ lines of boilerplate चाहिए
    • जिन्हें खुद बनाना पड़ेगा: queue setup और configuration, worker management और polling, message processing और state tracking, error handling और retry, manual step coordination
    • उदाहरण code में job_queue, job_results, job_state, workflow_steps, step_variables, scheduled_jobs जैसी कई state tables, polling worker, workflow progression, crash recovery, parallel execution coordinator, variable passing, scheduling, और cleanup functions शामिल हैं
    • scheduling के next_run calculation के लिए अतिरिक्त external cron parser library भी चाहिए

pg_durable के साथ implement करने पर

  • वही parallel aggregation + dashboard refresh एक ही df.start() call में व्यक्त किया जा सकता है, & operator से fan-out और ~> से join
    • उदाहरण: 3 queries parallel branches में चलने के बाद refresh dashboard step पर मिलती हैं और result बनाती हैं
    • live execution example में 3-step parallel execution के बाद join → dashboard ready तक सिर्फ 1.9 सेकंड में durable तरीके से पूरा
  • queue management, state tracking, crash recovery, step coordination, और retry सब pg_durable संभालता है

प्रमुख विशेषताएँ

  • Durable by default

    • हर step PostgreSQL में state को checkpoint के रूप में लिखता है, इसलिए crash, restart, या connection टूटने पर भी workflow जीवित रहता है
    • जहां रुका था, ठीक वहीं से फिर शुरू होता है
  • Automatic retries

    • flaky tasks के लिए built-in retry logic, step fail होने पर सिर्फ वही step retry होता है और बाकी workflow चलता रहता है
    • manual error-handling code की ज़रूरत नहीं
  • Full observability in SQL

    • सभी workflow states Postgres tables में store होते हैं; execution history देखना, step output जांचना, और failures debug करना standard SQL से संभव
    • external dashboard की ज़रूरत नहीं
  • Parallel execution

    • & operator या df.join() से independent tasks को fan-out किया जा सकता है, और aggregation, API calls, ETL steps को automatic coordination के साथ साथ-साथ चलाया जा सकता है

कौन-कौन से pattern बनाए जा सकते हैं

  • ETL Pipelines

    • cleanup → transform → load को क्रमबद्ध guarantee के साथ जोड़ना; हर step पिछले step का इंतज़ार करता है और failure पर pipeline साफ़ तरीके से रुकती है (~> sequence, |=> variables)
  • Parallel Aggregation

    • user count aggregation + revenue sum + inventory check को एक साथ चलाना; कई queries में fan-out करके सबके पूरा होने का इंतज़ार (&, df.join())
  • Order Processing

    • order ID capture करके validation, processing, और completion steps तक भेजना; steps के बीच variables अपने आप flow होते हैं (|=> capture, $var substitution, df.sleep())
  • Scheduled Jobs

    • cron schedule पर API polling, record archiving, और data sync; loop स्थायी रूप से चलता है और restart के बाद भी जीवित रहता है (@> loop, df.wait_for_schedule())
  • Conditional Branching

    • pending work, row count, या flags देखकर process या skip branch चुनना; branching logic application में नहीं, SQL में रहती है (df.if(), ?> conditional)
  • Multi-step Validation

    • data fetch → schema validation → business rule checks → approve/reject; हर step checkpoint होता है, इसलिए failure पर भी progress नहीं खोती
  • Database Maintenance

    • autovacuum blockers, table bloat, और wraparound risk detect करके review के लिए दिखाना; approval का इंतज़ार करने के बाद restart के बावजूद durable तरीके से correction (?> conditional, df.wait_for_signal(), @> loop)
  • Azure Functions & HTTP

    • df.http() से Azure Functions या allowed HTTPS endpoints को SQL से सीधे call करना; document chunking, row enrichment, और record classification inline संभालना
  • Human-in-the-Loop Approval

    • सामान्य काम अपने आप approve करना और high-risk कामों (बड़े invoices, destructive operations) को मानवीय approval signal आने तक pause करना (df.wait_for_signal(), df.if())

AI-आधारित authoring support

  • workflow को plain English में describe करने पर Copilot सही durable-function SQL generate कर सकता है; syntax सीखे बिना सिर्फ अपनी जरूरत बतानी होती है
  • repository में reusable agent skill pg-durable-sql शामिल है, जो GitHub Copilot और अन्य agents को operators, variable substitution, loop, parallel join आदि के साथ सही SQL generate करना सिखाती है

Open source उपलब्धता

  • waitlist या lock-in के बिना पूरी तरह open source; repository clone और build करके अपने PostgreSQL पर तुरंत चलाया जा सकता है
  • laptop, server, या cloud कहीं भी durable orchestration लागू किया जा सकता है

Azure HorizonDB managed option

  • Azure HorizonDB Microsoft की नई PostgreSQL cloud service है, जिसमें pg_durable built-in है, इसलिए लिखे गए durable functions को ज्यों का त्यों रखते हुए enterprise scale, security, और AI जोड़ा जा सकता है
    • अधिकतम 3× तेज performance, storage auto-scale होकर 128 TB तक, compute scale-out होकर 3,072 vCore तक
    • Microsoft Defender से real-time threat detection, Microsoft Entra ID से identity management
    • Filtered DiskANN vector search, semantic ranking, और in-database AI model curation
    • Microsoft Fabric near-real-time mirroring, VS Code integration, और GitHub Copilot integration
  • Built-in AI pipelines

    • HorizonDB, pg_durable के durable execution के ऊपर managed end-to-end AI pipelines की layer जोड़ता है; हर step checkpointed, retried, और crash-safe होता है
    • step flow: Ingest (documents/data load) → Chunk (content split) → Embed (vectorization) → Index (DiskANN storage) → Serve (search/ranking)

1 टिप्पणियां

 
GN⁺ 5 시간 전
Hacker News की राय
  • लगता है 2026 Postgres queues का साल होगा: DBOS[0], pgQue[1] जैसी दिशा दिखाई दे रही है, और कम्युनिटी का ऐसे विकल्प बनाना बढ़िया है
    लेकिन एक पूर्व application engineer के नज़रिए से, मैं queue logic को code और Git के अंदर रखना पसंद करता हूँ। सही tools मिलें तो शायद राय बदल जाए
    [0]: https://www.dbos.dev/
    [1]: https://github.com/NikolayS/pgque

    • हो सकता है काम करने का तरीका ज़्यादा मुश्किल हो, या बस अलग हो, लेकिन documentation, खोजने लायक लिखित सामग्री, अनुभव, और tools कम लगते हैं
      version control, debugging, testing, release कैसे होते हैं, यह जानने की जिज्ञासा है। data locality और stack simplification के लिए सब कुछ एक जगह रखना अच्छा लगता है, लेकिन ऐसा भी महसूस होता है कि इसे “ठीक से” करने के उपयोगी ज्ञान का बहुत हिस्सा खो जाता है
    • “queue logic को code में रखना चाहता हूँ” इस बात से सहमत हूँ। data की तुलना में उस data पर होने वाली actions कहीं ज़्यादा बार बदलती हैं, इसलिए हर बार action बदलने पर migration करनी पड़े, यह समझ नहीं आता
      Supabase में थोड़ा भी जटिल काम करने के लिए Postgres functions बनानी पड़ती थीं, यह बात भी इसी कारण बेहद नापसंद थी। हालांकि पिछली startup में हमने Postgres के ऊपर एक simple job queue खुद बनाया था, और अगर pgQue जैसा कुछ होता तो शायद वह कहीं अधिक polished रूप लेता
    • मैं Postgres 7 के समय से प्रशंसक रहा हूँ और प्रयोग के तौर पर जितना हो सके उतना PostgreSQL के अंदर डालने की कोशिश की, लेकिन कम से कम developer experience और observability अभी भी कमज़ोर हैं
      multi-master extensions भी ऐसी चीज़ नहीं हैं जिन्हें तुरंत इस्तेमाल कर लें और पूरी तरह सुरक्षित मान लें, इसलिए database scaling की ज़रूरत को जल्दी सामने ला देने वाले write-heavy complex work को उसमें डालने में हिचक है
    • जिन projects में DB triggers थे, वहाँ SQL code को भी Git में रखकर manage किया जाता था
      local setup के समय triggers local database में चले जाएँ, इसके लिए उन्हें Django migrations में ठूँसने के मामले भी थे
  • इसमें stored procedures वाली गंध आती है। unit testing भी कठिन, version control भी कठिन, और business logic database के अंदर छिपकर एक “hidden brain” बन जाता है
    noisy workloads को isolate करना भी मुश्किल है, observability भी नहीं है, और scaling pressure पूरा का पूरा Postgres पर आ जाता है। खासकर API calls जैसी input/output की कमी है। जो काम सिर्फ local database के अंदर चलते हैं, उनके लिए ठीक हो सकता है, लेकिन उपयोग-क्षेत्र संकरा लगता है

    • stored procedures भी सही तरह इस्तेमाल किए जाएँ तो बेहतरीन होते हैं। versioning के लिए monotonically increasing ID नाम के अंत में जोड़ दें, breaking change चाहिए तो ID बढ़ाएँ, और पुराने version तब तक रहने दें जब तक उनका इस्तेमाल पूरी तरह बंद न हो जाए
      बेशक database upgrade procedure ठीक होना चाहिए। अगर team members root से मनमानी SQL migrations चलाते फिरें, तो फिर परेशानी तय है
      unit testing भी दूसरी SQL testing की तरह ही की जा सकती है, बस database चलाना पड़ता है। अगर stored procedures को test नहीं कर सकते, तो इसका मतलब SQL को ही test करने का तरीका नहीं है, और असली समस्या वही है
      stored procedures का विकल्प यह नहीं है कि business logic database में बिल्कुल न हो, बल्कि अक्सर उसका मतलब यह होता है कि SQL codebase में इधर-उधर बिखरा रहता है, test करना कठिन होता है, versioning और encapsulation खराब होते हैं, और प्रदर्शन बेवजह धीमा हो जाता है
      observability वाली बात कुछ हद तक सही है; SQL की समस्याओं के अंदर झाँकना ज़्यादातर programming languages की तुलना में अधिक मेहनत माँगता है। लेकिन अगर stored procedures input/output और scaling problems पैदा कर रहे हैं, तो उन्हें गलत तरह इस्तेमाल किया जा रहा है; सही इस्तेमाल में वे अक्सर input/output को काफ़ी घटाकर scalability सुधारते हैं
  • अगर मैंने सही समझा है, तो Pi LLM harness के developers द्वारा बनाया गया Absurd pure database access को जितना हो सके उतना कम करने की दिशा में लगता है। मैं अभी इस विषय को बस देखना शुरू ही कर रहा हूँ
    https://github.com/earendil-works/absurd

    • एक छोटी-सी correction, absurd शायद Mario Zechner के earendil में जुड़ने से पहले शुरू हुआ earendil का मूल project लगता है, और commits में भी मैंने उन्हें नहीं देखा
      बेशक मुझे सारी अंदरूनी बातें नहीं पता, इसलिए सचमुच जिज्ञासा है
  • “कब इस्तेमाल नहीं करना चाहिए” में लिखा है, “जब workflow का अधिकांश हिस्सा Postgres के बाहर हो और कई heterogeneous systems में फैला हो”; अगर ऐसा है, तो फिर समझ नहीं आता कि यह project Temporal जैसी चीज़ों से कैसे तुलना कर सकता है
    लगता है शायद मैं इस recommendation से संकेतित limitation को गलत समझ रहा हूँ

    • सहमत हूँ। example https://github.com/microsoft/pg_durable/blob/main/examples/i... को देखकर project की value ठीक से समझ नहीं आती
      तकनीकी रूप से यह दिलचस्प उपलब्धि हो सकती है, लेकिन इस तरह का SQL पढ़ना काफ़ी अजीब लगता है
      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'
      );
  • कंपनी Azure से बंधी हुई है, और हम अब भी इंतज़ार कर रहे हैं कि Azure PostgreSQL आधुनिक फीचर्स की बराबरी करे
    उदाहरण के लिए, यह इस्तेमाल नहीं कर सकते: https://www.paradedb.com/blog/hybrid-search-in-postgresql-th...
    अल्ट्रा-वाइड हाई-डायमेंशनल वेक्टर का भी सपोर्ट नहीं है। pg_durable को open source करना अच्छी बात है, लेकिन पहले वे बुनियादी फीचर्स ही जोड़ लें जो AWS में सामान्य रूप से मिल जाते हैं

    • ParadeDB AGPL है, इसलिए बड़े cloud providers के लिए इसे आम तौर पर उपलब्ध कराना मुश्किल है। लेकिन Azure HorizonDB में https://github.com/timescale/pg_textsearch इस्तेमाल किया जा सकता है, और Flex में भी जल्द आने की संभावना है
      साफ़-साफ़ बताऊँ तो मैं pg_textsearch का maintainer हूँ और अभी Azure में हूँ। वेक्टर सपोर्ट वाली बात पूरी तरह समझ नहीं आई; क्या आपका मतलब Azure में उपलब्ध pgvector + diskann से आगे किसी और चीज़ से है?
    • वेक्टर सर्च के लिए शायद Azure Cosmos DB ज़्यादा उपयुक्त होगा
    • शायद आपने यह पहले ही देखा होगा, लेकिन बस एक bare VM बनाकर उस पर नया Postgres इंस्टॉल न करने की वजह जानने में दिलचस्पी है
    • मैं Azure PG टीम में Postgres के AI फीचर्स का PM हूँ। जिन फीचर्स की मांग की गई है, वे वास्तव में उपलब्ध हैं, और पिछले 3–6 महीनों में काफ़ी प्रगति हुई है
      hybrid search (BM25 + vector) के मामले में ParadeDB का pg_search भी AWS का native फीचर नहीं है; उसे EC2 पर खुद host करना पड़ता है। Azure PostgreSQL के लिए हमने pg_textsearch को native बनाया है, जो वही BM25 ranking model देता है, और उसका मुख्य contributor अभी Azure Postgres टीम में है
      दस्तावेज़: https://learn.microsoft.com/en-us/azure/horizondb/ai/full-te...
      हाई-डायमेंशनल वेक्टर के मामले में तो हम आगे हैं। HNSW इस्तेमाल करने वाला pgvector 2,000 dimensions तक सीमित है, लेकिन Azure वेक्टर स्टोरेज और सर्च के लिए pgvector को सपोर्ट करता है, और हाई-डायमेंशन, बड़े पैमाने के workloads के लिए Microsoft का graph-based vector index pg_diskann भी देता है। यह अधिकतम 16,000 dimensions तक सपोर्ट करता है, और graph traversal के दौरान WHERE conditions को evaluate करने वाला advanced in-index filtering भी देता है, जिससे selective conditions में recall कम नहीं होता
      pgvector: https://learn.microsoft.com/en-us/azure/horizondb/ai/vector-...
      DiskANN हाई-डायमेंशन सपोर्ट: https://learn.microsoft.com/en-us/azure/horizondb/ai/vector-...
      ये फीचर्स अभी Azure PostgreSQL, खासकर Azure HorizonDB Preview में उपलब्ध हैं। अगर कोई खास workload है, तो हम उसे और विस्तार से देख सकते हैं
  • यह मुझे Apache Airflow जैसे DAG schedulers द्वारा बहुत पहले से हल की जा चुकी एक पुरानी समस्या का गलत समाधान लगता है
    यह अजीब लगता है कि control flow को code की बजाय database में क्यों रखना चाहेंगे। मैं प्रोजेक्ट को नीचा नहीं दिखा रहा, बस अभी तक बात पूरी तरह समझ नहीं आई

    • Microsoft के पास इस काम के लिए Durable Task framework[1] है, जो Temporal की तरह self-hosted standalone service के रूप में भी चल सकता है, और Azure Functions में serverless तरीके से भी। अगर मुझे सही याद है, तो यह Airflow और Temporal से भी पहले आया था
      यह प्रोजेक्ट ज़्यादा database-specific use case जैसा लगता है। इसका फायदा शायद यह है कि workflow logs और codebase को मिलाकर लाइन-दर-लाइन trace किए बिना, काम की सटीक state सीधे database में track की जा सकती है। लोड और latency भी कम हो सकते हैं, और operations के लिहाज़ से चलाने वाले components भी एक कम हो जाते हैं
      [1] https://learn.microsoft.com/en-us/azure/durable-task/common/...
    • Airflow जैसे बाहरी tools को database load का पता नहीं होता। अगर कोई developer 200 concurrent workers database पर छोड़ दे, तो दूसरे workloads प्रभावित हो सकते हैं
      इसके उलट, यह तरीका अभी शायद ऐसा काम नहीं करता, लेकिन इसमें round-trip latency की लागत के बिना लगभग real-time performance feedback लेकर खुद को adjust करने की क्षमता हो सकती है
  • दस्तावेज़ और उदाहरण पढ़ने के बाद भी कुछ बातें स्पष्ट नहीं हैं। यह जानना चाहता हूँ कि df.wait_for_schedule() कैसे काम करता है
    अगर इसे application से कॉल करें तो क्या यह idempotent है, यानी एक ही parameter के साथ दो बार चलाने पर tick दो बार होता है, या इसे query console से केवल एक बार मैन्युअली कॉल किया जाता है, या migration script के हिस्से के रूप में चलाया जाता है, यह समझ नहीं आ रहा
    यह भी जानना चाहता हूँ कि उदाहरण[0] में timed_out timeout होने पर लौटाया जाने वाला fixed constant है या नहीं। error या exception handling कैसे होती है, यह भी तुरंत साफ़ नहीं दिखता
    [0] https://github.com/microsoft/pg_durable/blob/main/examples/i...

    • df.start() को कॉल करने पर एक durable function बनती है और साथ ही उसका execution शुरू हो जाता है। यह कॉल उस execution को दर्शाने वाला instance ID लौटाती है, जिसे बाद में उस execution को refer करने के लिए इस्तेमाल किया जा सकता है
      इस durable function के भीतर df.wait_for_signal() को कॉल किया जाता है, और यह कॉल उस function instance के भीतर ठीक एक बार ही execute होती है, इसलिए duplicate संभव नहीं है। अगर df.start() कॉल खुद timeout होकर फिर से चलाई जाती है तो duplicate हो सकता है, लेकिन उस स्थिति में एक अलग function instance बनता है
      SQL execution के दौरान अगर कोई unhandled error आती है तो function instance fail हो जाता है, और state में वही सटीक error ऊपर आ जाती है
  • database के बाहर मौजूद orchestration tool की जगह इसे क्यों इस्तेमाल करना चाहिए, क्या कोई यह समझा सकता है। README और उदाहरण पढ़ने के बाद भी अभी तक बात पूरी तरह समझ नहीं आई

    • database के snapshot PITR का उपयोग करें तो किसी खास समय बिंदु तक के durable task भी साथ में पूरे restore हो जाते हैं
      उसी data store से जुड़े दूसरे component के साथ backup को sync करने की ज़रूरत नहीं पड़ती, इसलिए यह ETL pipeline या state machine जैसे कामों के लिए अच्छा है। अगर ETL ज़्यादातर SQL में है, तो असली काम का उसी server पर चलना भी मददगार होता है
    • contributor के नज़रिए से देखें तो Microsoft के Postgres ग्राहक काफ़ी बराबरी से दो समूहों में बँटे हुए हैं। एक वे जो जितना संभव हो उतना database के भीतर करना चाहते हैं, और दूसरे वे जो application और computation को database के बाहर रखना चाहते हैं
    • अगर architecture में database ही एकमात्र stateful component है, तो यह कभी-कभी सुविधाजनक होता है
      जब सारी state एक ही database में हो, तो consistent backup मिलने की संभावना भी ज़्यादा होती है
    • यह application workflow के साथ अच्छी तरह integrate हो सकता है। उदाहरण के लिए front-end app के permalink पर progress दिखाना संभव है, app restart के बाद भी चलते रहने वाले workflow बनाए जा सकते हैं, और कोई अतिरिक्त infra component जोड़ने की ज़रूरत नहीं पड़ती
      https://transport.data.gouv.fr पर Postgres का इस्तेमाल ऐसे ही काम के लिए किया जा रहा है, और काफ़ी processing करने वाली Elixir app में यह मददगार है। मुझे अभी pg_durable के बारे में ज़्यादा नहीं पता, लेकिन मैंने मिलते-जुलते समाधान इस्तेमाल या लागू किए हैं, इसलिए बात समझ में आती है
  • क्या database पहले से ही scale करना सबसे कठिन infra में से एक नहीं है। फिर उसके ऊपर long-running task और क्यों डालना चाहेंगे, यह समझ नहीं आता

    • Postgres में long-running task चलाना कोई बिल्कुल नई बात नहीं है। उदाहरण के लिए pg_cron है
      आख़िरकार इस तरह का workload database के against ही चलने वाला काम है, चाहे उसे कोई external component trigger करे या न करे। data या AI pipeline में अतिरिक्त component से होने वाले round-trip और failure point से बचने के लिए database से HTTP query भेजने का तरीका भी अब ज़्यादा आम हो गया है। हालाँकि computation को data के पास लाना है या data को computation के पास ले जाना है, यह अब भी एक बड़ा architectural decision है
  • यह मुझे एक और https://en.wikipedia.org/wiki/Inner-platform_effect जैसा लगता है, जिसकी शायद ज़रूरत ही न पड़ती अगर लोकप्रिय programming language या virtual machine पहले से determinism, मापने योग्य और नियंत्रित step-by-step execution, runtime state को pause करना, serialization·deserialization और resume को support करतीं