18 पॉइंट द्वारा GN⁺ 2025-12-23 | 1 टिप्पणियां | WhatsApp पर शेयर करें
  • वितरित सिस्टम में latency समस्या को डिबग करते समय सबसे पहले TCP_NODELAY सेटिंग की जांच करनी चाहिए
  • Nagle algorithm 1984 के RFC896 में प्रस्तावित एक तरीका है, जिसे छोटे packets भेजते समय TCP header overhead कम करने के लिए डिज़ाइन किया गया था
  • लेकिन जब यह delayed ACK मेकेनिज़्म के साथ जुड़ता है, तो ACK मिलने तक डेटा ट्रांसमिशन रुक जाता है और latency-sensitive applications का प्रदर्शन खराब हो जाता है
  • आधुनिक data center वातावरण में RTT बहुत कम होता है, और ज़्यादातर सिस्टम पहले से ही बड़े messages भेजते हैं, इसलिए Nagle algorithm के फायदे लगभग समाप्त हो चुके हैं
  • इसलिए आधुनिक वितरित सिस्टम में TCP_NODELAY को डिफ़ॉल्ट रूप से सक्षम करना चाहिए, और Nagle algorithm अब व्यावहारिक रूप से ज़रूरी नहीं है

Nagle algorithm की पृष्ठभूमि

  • 1984 में John Nagle के RFC896 ने keyboard input जैसे छोटे डेटा ट्रांसफर में होने वाली 40-byte header बनाम 1-byte data के 4000% overhead की समस्या को हल करने के लिए यह तरीका प्रस्तावित किया था
    • उस समय समस्या यह थी कि उपयोगकर्ता हर अक्षर टाइप करते ही छोटे packets भेजे जाते थे, जिससे network efficiency कम हो जाती थी
    • इसका समाधान यह था कि जब तक पिछला डेटा ACK न हो जाए, तब तक नया segment न भेजा जाए
  • यह तरीका उस समय के network environment में प्रभावी था, लेकिन latency महत्वपूर्ण होने वाले आधुनिक सिस्टम के लिए उपयुक्त नहीं है

Nagle algorithm और Delayed ACK की परस्पर क्रिया

  • Delayed ACK (RFC813, RFC1122) एक तरीका है जिसमें receiving side तुरंत ACK नहीं भेजती, बल्कि response data आने या timer expire होने तक ACK को रोककर रखती है
  • Nagle algorithm ACK का इंतज़ार करते हुए ट्रांसमिशन रोक देता है, और delayed ACK ACK भेजने में देर करता है, इसलिए दोनों तरफ़ एक-दूसरे का इंतज़ार करने वाली deadlock जैसी स्थिति बन जाती है
  • John Nagle ने ख़ुद इस संयोजन को “भयानक संयोजन” कहा था, और बताया कि दोनों फीचर अलग-अलग लाए गए थे, लेकिन साथ उपयोग होने पर latency पैदा करते हैं

आधुनिक वातावरण में समस्याएँ

  • data center के भीतर RTT लगभग 500μs होता है, और एक ही region के भीतर भी यह कुछ milliseconds के स्तर पर बहुत कम होता है
  • ऐसे वातावरण में एक RTT जितनी देरी भी प्रदर्शन हानि में बदल जाती है
  • इसके अलावा आधुनिक वितरित सिस्टम TLS, serialization, protocol overhead आदि के कारण पहले से ही काफ़ी बड़े messages भेजते हैं, इसलिए single-byte packet की समस्या लगभग नहीं के बराबर रह गई है
  • छोटे messages की optimization अब application layer में की जाती है

TCP_NODELAY की आवश्यकता

  • latency-sensitive distributed systems में Nagle algorithm को बंद करने के लिए TCP_NODELAY सक्षम करना अनुशंसित है
    • यह कोई “inefficient” या “गलत configuration” नहीं है, बल्कि आधुनिक hardware और traffic characteristics के अनुरूप चुनाव है
  • लेखक का तर्क है कि TCP_NODELAY ही default होना चाहिए
    • कुछ ऐसा code जो हर write() call पर तुरंत भेजता है, धीमा पड़ सकता है, लेकिन ऐसे code को मूल रूप से सुधारा जाना चाहिए

अन्य संबंधित विकल्प

  • TCP_QUICKACK विकल्प ACK delay कम करता है, लेकिन portability issues और असंगत व्यवहार के कारण यह मूल समाधान नहीं है
  • असली समस्या यह है कि kernel डेटा को application के इच्छित समय से ज़्यादा देर तक रोके रखता है, जबकि write() call पर उसे तुरंत भेजा जाना चाहिए

निष्कर्ष

  • Nagle algorithm अतीत में network efficiency बढ़ाने के लिए एक शानदार आविष्कार था, लेकिन
    आधुनिक high-speed networks और distributed systems के माहौल में यह उल्टा latency बढ़ाने वाला पुराना फीचर बन गया है
  • इसलिए TCP_NODELAY को हमेशा सक्षम रखना आधुनिक सिस्टम डिज़ाइन का बुनियादी सिद्धांत माना जाना चाहिए

1 टिप्पणियां

 
GN⁺ 2025-12-23
Hacker News की राय
  • यह Nagle algorithm की पृष्ठभूमि समझाता है, जो पुराने multipoint networking के दौर में बनाया गया था
    उस समय कई hosts एक ही Ethernet channel साझा करते थे, इसलिए collisions से बचने के लिए CSMA/CD का उपयोग होता था
    लेकिन आज अधिकांश Ethernet point-to-point संरचना वाले हैं, और full duplex वातावरण में काम करते हैं जहाँ भेजना और पाना एक साथ संभव है
    इसलिए CSMA अब ज़रूरी नहीं है, और TCP_NODELAY सेट करके Nagle algorithm को निष्क्रिय करना ज़्यादातर मामलों में उचित लगता है
    • यह जानने की जिज्ञासा है कि क्या CSMA से जुड़ी यह प्रेरणा वास्तव में Nagle algorithm के डिज़ाइन में थी, या सिर्फ उस समय के संदर्भ का उल्लेख किया गया है
    • वास्तव में Nagle algorithm का उद्देश्य सिर्फ packet coalescing था
      इसे default बनाना networking इतिहास की बड़ी गलतियों में से एक लगता है
    • संदर्भ के लिए, Ethernet CSMA/CD का उपयोग करता है, जबकि WiFi CSMA/CA का
      लगभग 2014 में data center switches बदलते समय, 10Mbit half duplex को समर्थन न मिलने के कारण कुछ पुराने उपकरण बनाए रखने पड़े थे
    • जब application packet size की परवाह नहीं करता या latency-sensitive नहीं होता, तब Nagle काफ़ी तर्कसंगत है
      यह बहुत छोटे packets बनने से रोकता है
    • यहाँ network layer confusion लगता है
      Nagle TCP layer का optimization है, जिसका काम छोटे packets को जोड़कर efficiency बढ़ाना है
      CSMA physical/data link layer की समस्या है, और Nagle से अलग है
  • गेम डेवलपमेंट के दौरान network latency समस्या debug करते हुए यह पोस्ट मिली
    Go में लिखा backend वैसे भी default रूप से TCP_NODELAY सेट करता है, इसलिए कारण यह नहीं था, लेकिन Nagle की समस्या-समझ पर चर्चा दिलचस्प लगी
    पहले की चर्चा भी थी, यह thread देख सकते हैं
    • Julia Evans का अच्छा लेख भी सुझाया गया
      DICOM protocol जैसी chatty communication में TCP_NODELAY=1 सेट करने पर throughput काफ़ी बढ़ जाता है
    • आप कौन-सा गेम बना रहे हैं, यह जानने की जिज्ञासा है। मुझे भी Ebitengine और Golang के साथ गेम बनाना पसंद है, इसलिए दिलचस्पी है
  • लगभग 10 साल पहले खुद Nagle ने कहा था कि असली समस्या delayed ACK है
    संबंधित लिंक देखें
    मेरा मानना है कि आज के workloads में delayed ACK कोई बड़ा लाभ नहीं देता
    HTTP-केंद्रित आधुनिक वातावरण में Nagle और delayed ACK दोनों को बंद करना बेहतर लगता है
    • मूल लेख में भी यह बात है
      data centers के बीच RTT सैकड़ों microseconds के स्तर का होता है, इसलिए एक RTT जितनी भी देरी करना उल्टा नुकसानदेह हो सकता है
  • Polish में “nagle” का मतलब “अचानक” होता है, और यह algorithm के नाम पर बहुत फिट बैठता है, यह जानकर आश्चर्य हुआ
    • यह Nominative determinism का एक और उदाहरण लगता है
      wiki link
    • दिलचस्प बात यह है कि “NODELAY on” होने पर अचानक भेजता है, और “off” होने पर एक साथ भेजता है, मानो यह शब्द दोनों settings का अर्थ समेटे हुए हो
    • वास्तव में यह John Nagle नामक व्यक्ति द्वारा लिखे गए RFC 896 पर आधारित algorithm है
  • यह अजीब लगता है कि Nagle algorithm kernel default के रूप में सेट है
    कब भेजना है और कब buffer करना है, यह application को तय करना चाहिए
  • यह हैरानी की बात थी कि लेख में MSG_MORE का उल्लेख नहीं था
    Linux में यह kernel को संकेत देता है कि और data जल्द आने वाला है, इसलिए header और data को अलग-अलग भेजते समय उपयोगी है
    io_uring के साथ इसका उपयोग और अधिक efficient है
    • वास्तव में एक ही system call में कई data fragments को बिना copy किए भेजा जा सकता है
  • मुझे लगता है कि Nagle algorithm की समस्या यह है कि socket API में तुरंत भेजने वाला flush फ़ीचर नहीं है
    अगर ऐसे messages के बाद buffer खाली कर भेजने की सुविधा हो जिनमें तुरंत response चाहिए, तो अच्छा होगा
    आजकल TCP channels में synchronous और asynchronous messages मिले-जुले होते हैं, इसलिए बात और जटिल हो जाती है
    काश SCTP जैसे protocols ज़्यादा व्यापक रूप से उपयोग में आते
    • मैं इस बात से सहमत हूँ कि stream API में flush नहीं है। यह साफ़ तौर पर डिज़ाइन की कमी लगती है
    • network I/O को files की तरह संभालने की UNIX philosophy समझ में आती है, लेकिन अगर शुरू से message-oriented API होता तो यह समस्या शायद न होती
      TLS जैसी wrapping में भी message boundaries ढूँढना झंझट भरा होता है
    • हर send पर MSG_MORE लगाया जाए और सिर्फ आख़िरी पर हटाया जाए, तो परोक्ष रूप से flush जैसा असर मिल सकता है
    • stream API कई तरह से असुविधाजनक है
      आदर्श रूप से “buffering allowed” bit सेट करके बड़े transfer को टुकड़ों में बाँटना चाहिए और अंत में “send immediately” निर्दिष्ट कर पाना चाहिए
      TCP_CORK कुछ हद तक मिलती-जुलती वैकल्पिक व्यवस्था है, लेकिन थोड़ी भद्दी है
      file I/O भी ऐसी ही समस्या झेलता है
    • TCP_CORK क्या है, यह जानने की उत्सुकता है
  • (2024) पहले की चर्चा इस लिंक पर हुई थी
  • Oxide and Friends podcast episode में इस विषय को कवर किया गया है
    काफ़ी दिलचस्प सामग्री है
    • Oxide एक ऐसी कंपनी है जो server OS और hardware को नए सिरे से डिज़ाइन करती है, इसलिए पारंपरिक protocols की फिर से समीक्षा करने वाला यह दृष्टिकोण उसकी brand philosophy से अच्छी तरह मेल खाता है
  • Nagle algorithm कुछ ऐसा लगता है जैसे policy को kernel में डाल दिया गया हो, इसलिए असहज लगता है
    application को latency और throughput के बीच संतुलन खुद नियंत्रित कर पाना चाहिए
    • delayed ack न होने पर यह एक तर्कसंगत algorithm है, और TCP stack के हिस्से के रूप में इसके होने की वजह यह है कि उसी layer पर समस्या हल करने की कोशिश की गई थी
      लेकिन इसे application स्तर पर लागू करने के लिए unacked data जानना पड़ेगा, जो inefficient है
    • सैद्धांतिक रूप से यह सही है, लेकिन व्यवहार में ज़्यादातर userspace code network के निचले स्तरों की परवाह नहीं करता
      सिर्फ एक साधारण 20ms flush timer भी होता तो बहुत बेहतर होता
    • वास्तव में TCP_NODELAY socket स्तर पर सेट होता है, इसलिए इसे application द्वारा चुना गया userspace निर्णय कहना ज़्यादा उचित है
    • एक program के trade-offs दूसरे programs को प्रभावित कर सकते हैं, इसलिए मेरा मानना है कि पूरे system के दृष्टिकोण से kernel का mediator होना ज़रूरी है