8 पॉइंट द्वारा GN⁺ 2026-01-30 | 3 टिप्पणियां | WhatsApp पर शेयर करें
  • PostgreSQL extension proxy PgDog ने SQL parsing performance बढ़ाने के लिए Protobuf serialization की जगह Rust direct binding अपनाई
  • मौजूदा Protobuf-आधारित संरचना को C–Rust direct conversion (bindgen + Claude द्वारा जनरेटेड wrapper) से बदलकर parsing 5.45 गुना, deparsing 9.64 गुना तेज किया गया
  • performance bottleneck pg_query_parse_protobuf फ़ंक्शन में मिला, और caching की कोशिशों के बाद भी मूलभूत सुधार के लिए संरचना बदली गई
  • Claude LLM का उपयोग करके 6,000 lines का Rust–C conversion code अपने-आप जनरेट किया गया, और इसे parse, deparse, fingerprint, scan जैसी मुख्य functions पर लागू किया गया
  • इस optimization से PgDog की CPU usage और latency घटी, और PostgreSQL horizontal scaling proxy के रूप में इसकी efficiency काफ़ी बढ़ी

PgDog और Protobuf की सीमाएँ

  • PgDog PostgreSQL को scale करने के लिए बना एक proxy है, जो अंदरूनी तौर पर SQL queries parse करने के लिए libpg_query का उपयोग करता है
    • यह Rust में लिखा गया है, और पहले Protobuf serialization/deserialization के ज़रिए C library से communicate करता था
  • Protobuf तेज़ है, लेकिन direct binding तरीका उससे भी तेज़ है
    • PgDog टीम ने pg_query.rs को fork करके Protobuf हटाया और C–Rust direct binding लागू की
    • नतीजतन query parsing 5.45 गुना और deparsing 9.64 गुना तेज़ हो गई

benchmark परिणाम

  • benchmark को PgDog के fork repository में दोबारा चलाया जा सकता है
    • pg_query::parse (Protobuf): 613 QPS
    • pg_query::parse_raw (direct C–Rust): 3357 QPS
    • pg_query::deparse (Protobuf): 759 QPS
    • pg_query::deparse_raw (direct Rust–C): 7319 QPS

performance bottleneck analysis और caching प्रयास

  • samply profiler से CPU time का analysis करने पर pg_query_parse_protobuf फ़ंक्शन bottleneck निकला
  • caching के ज़रिए कुछ सुधार की कोशिश की गई
    • LRU algorithm-आधारित hashmap cache का उपयोग कर query text को key और AST को stored value के रूप में रखा गया
    • prepared statements के उपयोग पर reuse संभव था
  • लेकिन कुछ ORM हज़ारों unique queries बनाते थे, और पुराने PostgreSQL drivers prepared statements को support नहीं करते थे, इसलिए cache efficiency कम रही

LLM की मदद से Protobuf हटाना

  • PgDog टीम ने Claude LLM का उपयोग करके Protobuf हटाने वाले Rust bindings जनरेट किए
    • स्पष्ट और verify किए जा सकने वाले task scope में AI ने प्रभावी ढंग से काम किया
  • Claude ने libpg_query के Protobuf spec के आधार पर C structs को Rust structs से map किया
    • 2 दिनों की iterative मेहनत के बाद 6,000 lines का recursive Rust code पूरा हुआ
  • इसे parse, deparse, fingerprint, scan functions पर लागू किया गया, और pgbench के आधार पर 25% performance improvement की पुष्टि हुई

implementation की संरचनात्मक जानकारी

  • Rust और C के बीच conversion में unsafe functions का उपयोग करके structs को सीधे map किया गया
    • C structs को Postgres API तक भेजकर AST बनाया गया, फिर उसे Rust में recursively convert किया गया
  • हर AST node को convert_node फ़ंक्शन से process किया जाता है, जो SQL grammar के सैकड़ों tokens को map करता है
    • SELECT, INSERT जैसे हर node type के लिए अलग conversion functions मौजूद हैं
  • conversion result में मौजूदा Protobuf struct (protobuf::ParseResult) का दोबारा उपयोग किया गया, जिससे tests में byte-level comparison validation संभव हुआ
  • recursive algorithm में memory allocation कम होती है और CPU cache efficiency अधिक रहती है, इसलिए यह iterative implementation से तेज़ है
    • iterative implementation अनावश्यक memory allocation और hashmap lookups की वजह से उल्टा धीमी रही

निष्कर्ष

  • Postgres parser का overhead घटाकर PgDog ने latency, memory और CPU usage तीनों कम किए
  • इस optimization से PgDog और तेज़ तथा कम लागत पर चलने वाला PostgreSQL scaling proxy बन गया
  • PgDog PostgreSQL के horizontal scaling (next iteration) को साथ मिलकर बनाने वाले engineers की भर्ती कर रहा है

3 टिप्पणियां

 
a1eng0 2026-01-31

हो सकता है कि मैं मूल लेख को गलत समझ रहा हूँ, लेकिन खासकर Rust से जुड़े लेखों में अक्सर ऐसा लगता है कि मुद्दे की असली बात से हटकर इसे ऐसे लिखा जाता है मानो यह सिर्फ़ "Rust होने की वजह से" तेज़ हो गया हो.

इस लेख का मुख्य बिंदु तो यह है कि अनावश्यक serialization overhead कम करने से performance बेहतर हुई है.

अब दोबारा देखता हूँ तो यह भी शायद Rust की उतनी प्रशंसा करने वाला लेख नहीं लगता, लेकिन क्या दूसरे लेखों की वजह से मेरे मन में इसके प्रति नकारात्मक धारणा बन गई है?

 
xguru 2026-01-31

मुझे भी लगा कि इस मूल शीर्षक में, वास्तविक सामग्री से अलग, Rust पर जरूरत से ज़्यादा ज़ोर है, जिससे यह प्रदर्शन सुधार पर केंद्रित दिखता है, इसलिए मैंने इसे थोड़ा संशोधित किया।
लगता है Rust से जुड़े लेखों में ऐसा रुझान अक्सर दिखता है, इसलिए उन्हें थोड़ा फ़िल्टर करके पढ़ने की ज़रूरत होती है।

 
GN⁺ 2026-01-30
Hacker News की राय
  • शीर्षक ऐसा लगता है मानो Rust ने 5 गुना performance improvement दिया हो, लेकिन विडंबना यह है कि असल में चीज़ें पहले धीमी हुई थीं
    समस्या यह थी कि Rust में लिखे गए software को C में लिखी libpg_query का इस्तेमाल करना था, लेकिन उसे सीधे जोड़ नहीं पा रहे थे, इसलिए Protobuf-आधारित Rust–C binding का उपयोग किया गया
    यह तरीका धीमा था, इसलिए आखिरकार LLM की मदद से non-portable लेकिन कहीं अधिक optimized binding फिर से लिखी गई
    अगर शुरुआत से ही C में लिखा गया होता, तो conversion process की ज़रूरत ही नहीं पड़ती। यानी, शीर्षक “Rust इस्तेमाल करने से हुए performance loss को कम किया” अधिक सटीक होता
    conversion layer portability और security देती है, लेकिन आखिरकार copy·conversion·serialization बार-बार होती है और यही app को धीमा बनाने के कारणों में से एक है

    • Rust धीमा नहीं था, समस्या external library के inefficient design की थी
      Rust से C library को call करना बहुत आसान है, और safe wrapper भी पहले से बहुत मौजूद हैं
      बीच में Protobuf रखने वाली संरचना लगभग कभी नहीं देखी, और bottleneck वही था
      शीर्षक सिर्फ click खींचने के लिए “Rust में फिर से लिखा” वाले meme के करीब लगता है
    • अगर C में लिखा होता तो तेज़ होता, यह कहना fair नहीं है
      मूल library में serialization/deserialization बार-बार होने वाला गलत design था, और असली बात उसे हटाना है
      शीर्षक “Protobuf को सामान्य API से बदलकर 5 गुना तेज़ किया” अधिक सही है
    • सीधे FFI का इस्तेमाल क्यों नहीं किया, यह जानने की जिज्ञासा है
      Rust में C binding सबसे आसान चीज़ों में है, और अगर API बहुत बड़ा न हो तो यह simple होता है
      memory के अंदर data exchange के लिए Protobuf अनुपयुक्त tool लगता है
    • अगर LLM से optimization किया गया, तो सोचता हूँ कि उसी से C library को Rust में पूरी तरह port करना बेहतर होता
      आगे LLM की वजह से अलग-अलग भाषाओं में porting विस्फोटक रूप से बढ़ती दिख सकती है
    • Rust और Postgres के बीच Protobuf रखना performance nightmare जैसा है। हैरानी है कि ऐसी library लोकप्रिय हुई
  • शीर्षक कुछ हद तक भ्रामक है
    असल में बात यह है कि “Protobuf serialization step हटाया तो चीज़ें तेज़ हो गईं”

    • Protobuf साधारण copy से संभव न होने वाली version compatibility देता है
      यह client और server को स्वतंत्र रूप से update होने पर भी काम करने देता है, और कई भाषाओं के बीच communication आसान बनाता है
      बड़े systems में ऐसी flexibility बहुत महत्वपूर्ण होती है
    • Protobuf serialization साधारण memory copy से 5 गुना धीमी है, यह सुनकर उल्टा सोच से तेज़ लगती है
    • memcpy या mmap कहीं तेज़ हैं, लेकिन Rust ecosystem में ऐसे unsafe तरीकों से बचा जाता है
    • ऐसे मामले में Arrow जैसे standardized zero-copy format का उपयोग अच्छा हो सकता है। यह भाषा-विशिष्ट padding समस्या और security checks को अपने-आप संभालता है
  • वजह Rust नहीं, बल्कि Protobuf को generalized storage format की तरह इस्तेमाल करना हो सकता है
    आखिरकार, किसी खास उद्देश्य के लिए चीज़ों को सरल बनाना ही मुख्य बात थी

    • “Protobuf को native optimized implementation से बदला” जैसा शीर्षक कम ध्यान खींचता
      शीर्षक में Rust डालना clickbait जैसा चुनाव लगता है
    • लेख का शीर्षक बहस छेड़ता है, लेकिन मुख्य लेख इस बात को पहचानता भी है
    • असल में इसका Rust से बहुत कम संबंध है, लेकिन Rust न होता तो यह main page तक शायद नहीं पहुँचता
  • pg_query के मूल लेखक ने पृष्ठभूमि समझाई
    शुरुआत में pganalyze में Postgres query को parse करके table references ढूँढने, query को rewrite करने और format करने के लिए इसका उपयोग हुआ
    पहले JSON इस्तेमाल किया गया, लेकिन बाद में Protobuf में बदला गया ताकि कई भाषाओं (Ruby, Go, Rust, Python आदि) में type-safe binding आसानी से दी जा सके
    Rust जैसी भाषाओं के लिए FFI बेहतर है, लेकिन दूसरी भाषाओं में maintenance burden ज़्यादा होता है
    वे Lev की कोशिश का समर्थन करते हैं, और आगे libpg_query तक सीधे FFI access देने वाले functions जोड़ने की योजना है
    हालांकि जहाँ performance महत्वपूर्ण न हो, वहाँ Protobuf अब भी अधिक सुविधाजनक विकल्प है

  • “5 गुना तेज़” सुनकर Cap’n Proto के “अनंत गुना तेज़” वाले मज़ाक की याद आती है

    • Cap’n Proto, Protobuf बनाने वाले व्यक्ति की ही रचना है, और उसने ऐसा इसलिए कहा था क्योंकि इसकी संरचना parsing की ज़रूरत नहीं पड़ने देती है
    • लेकिन असल उपयोग में Cap’n Proto की usability कमज़ोर लगती है
  • शीर्षक बढ़ा-चढ़ाकर कहा गया है, लेकिन असली काम प्रभावशाली है
    Protobuf को पूरी तरह हटाया नहीं गया, बल्कि उसके इस्तेमाल के तरीके को optimize किया गया
    “X में बदलते ही 5 गुना तेज़ हो गया” जैसी पंक्ति का मतलब अक्सर यह होता है कि “पहले implementation बुरी तरह गड़बड़ थी, उसे ठीक किया गया”
    मुख्य सीख यह है

    1. serialization/deserialization अक्सर छिपा हुआ bottleneck बन जाते हैं
    2. default implementation आम तौर पर हर स्थिति के लिए optimized नहीं होती
    3. profiling से bottleneck को ठीक-ठीक पहचानना चाहिए
      Rust FFI में भी overhead होता है, इसलिए असली उपलब्धि भाषा नहीं बल्कि data flow का redesign और optimization effort है
  • FlatBuffers तेज़ है, लेकिन Protobuf इस्तेमाल करने का कारण यह है कि उसे बड़ी कंपनियाँ maintain करती हैं

    • लेकिन FlatBuffers भी Google maintain करता है
      आखिरकार, “Google ने बनाया है इसलिए सुरक्षित है” वाली धारणा का कोई आधार नहीं है
    • मैंने भी पहले Google platform (code.google.com) पर code डाला था और उसके बंद हो जाने का नुकसान देखा है
      अगर सिर्फ memory sharing और version fields वाला zero-copy structure चाहिए, तो Protobuf का खास कारण नहीं दिखता
    • Google ने अब तक string field zero-copy optimization सार्वजनिक नहीं किया है
  • Protobuf performance मज़ाक के स्तर की लगती है
    serialization लगभग free होने वाले zero-copy formats इस्तेमाल करने चाहिए
    उदाहरण के लिए, मेरे बनाए Lite³ की speed FlatBuffers से 242 गुना तेज़ है

    • लेकिन वह library 2025 के नवंबर के बाद ही आई
      Protobuf इस्तेमाल करने के पीछे ecosystem, schema, भाषा-विशिष्ट tooling जैसी कई व्यावहारिक वजहें होती हैं
  • असल समस्या Rust या Protobuf नहीं, बल्कि PostgreSQL abstraction layer की inefficient serialization implementation थी
    pgdog ने उस layer को हटाकर data को सीधे C API में pass किया
    गैर-ज़रूरी features हटाने से स्वाभाविक रूप से चीज़ें तेज़ हो जाती हैं
    लेकिन कुछ लोगों के लिए अब भी serialization की ज़रूरत रहेगी
    ऐसे लोगों के लिए “Rust में बदलो” वाला शीर्षक गलत संदेश देता है
    आखिरकार, ज़्यादातर मामलों में JSON काफ़ी है, और अगर सच में अधिक speed चाहिए तो serialization को ही टालना चाहिए

  • यह अनुचित तुलना है
    IPC communication में serialization protocol इस्तेमाल करने पर overhead होना स्वाभाविक है
    “20% तेज़ हो तो improvement, 10 गुना तेज़ हो तो मतलब शुरू से गलत बनाया गया था” — यह कहावत यहाँ बिल्कुल फिट बैठती है