- API authentication service देने वाली Unkey ने Cloudflare Workers-आधारित serverless architecture से Go-आधारित stateful server पर स्विच किया, जिससे performance और architecture complexity की समस्याएँ हल हुईं
- नई संरचना ने 6 गुना तेज response time दिया और जटिल cache bypass तरीकों तथा data pipeline overhead को हटा दिया
- Serverless environment में function calls के बीच persistent memory की गारंटी नहीं होती, इसलिए हर cache read के लिए network request चाहिए था, और p99 के आधार पर cache latency 30ms से अधिक थी
- Distributed system से सरल application architecture में बदलाव के साथ self-hosting संभव हुई, platform independence मिली, और developer experience भी काफ़ी बेहतर हुआ
- Serverless अनियमित workloads या simple request/response patterns के लिए उपयुक्त है, लेकिन जहाँ consistent low latency या persistent state management चाहिए, वहाँ stateful server अधिक प्रभावी है
Serverless की सीमाएँ और performance bottleneck
- Unkey में API authentication request path के core में था, इसलिए कुछ milliseconds की latency भी user experience पर सीधे असर डालती थी
- Cloudflare Workers की global edge deployment और auto scaling आकर्षक थीं, लेकिन cache persistence की कमी और network request latency बड़ी समस्या बन गई
-
Caching समस्या
- Serverless functions में calls के बीच persistent memory नहीं होती, इसलिए हर cache lookup के लिए external network request की ज़रूरत पड़ती है
- Cloudflare cache lookup की p99 latency 30ms से अधिक मापी गई
- कई layers के cache (SWR, Redis आदि) जोड़ने पर भी मूल रूप से यह ‘0 network requests’ से तेज नहीं हो सकता
- नतीजतन, 10ms से कम response का लक्ष्य हासिल नहीं हो पाया
-
SaaS coupling समस्या
- Serverless infra management का बोझ कम करता है, लेकिन व्यवहार में अतिरिक्त SaaS tools ज़रूरी हो जाते हैं
- cache → Redis, batch processing → Queue, logs → Durable Objects आदि
- हर service latency, cost, और failure point बढ़ाती है
- Cloudflare Durable Objects, Queues, Workflows आदि का मिश्रित उपयोग करने पर भी वास्तविक complexity उल्टा बढ़ गई
-
Data pipeline समस्या
- Serverless volatile environment होने के कारण हर call पर data को तुरंत flush करना पड़ता है
- events, logs, metrics को संभालने के लिए जटिल buffering और relay services खुद बनानी पड़ीं
- उदाहरण:
chproxy के जरिए ClickHouse में logs का batch transfer
- Axiom को logs भेजते समय rate limit bypass करने के लिए अलग buffering server बनाया
- नतीजतन साधारण analytics feature भी distributed event processing system जैसी complexity ले आया
Stateful server पर बदलाव
- Go-आधारित state server (v2) लाने के बाद in-memory batching और periodic flush संभव हो गया
- अतिरिक्त services या जटिल pipelines की ज़रूरत नहीं रही
- maintainability, debugging, और local testing काफ़ी सरल हो गए
-
Performance परिणाम
/v1/keys.verifyKey और /v2/keys.verifyKey की तुलना में latency 6 गुना कम हुई
- Cloudflare के 300 global POP से कम infra होने के बावजूद users की महसूस की गई performance काफ़ी बेहतर हुई
Performance के अलावा लाभ
-
Self-Hosting
- Cloudflare runtime पर निर्भरता के कारण customers Unkey को self-host नहीं कर सकते थे
- Workers runtime तकनीकी रूप से open source है, लेकिन local execution (development mode में भी) बेहद कठिन था
- Standard Go server पर आने से self-hosting आसान हो गई
- सिर्फ
docker run -p 8080:8080 unkey/api command से इसे चलाया जा सकता है
- किसी special runtime या जटिल configuration की ज़रूरत नहीं
- अब developers कुछ ही seconds में पूरा Unkey stack local में चला सकते हैं, जिससे debugging और testing बहुत आसान हो गई
- local development और debugging की गति में बड़ा सुधार हुआ
-
Developer experience में सुधार
- Serverless में आने वाली सीमाएँ:
- function execution constraints का ध्यान रखना पड़ता था
- calls के बीच state बनाए रखना कठिन था
- distributed logs की debugging जटिल थी
- local testing environment असुविधाजनक था
- Stateful server पर आने से यह complexity tax हट गया
-
Platform independence
- अब Cloudflare ecosystem पर निर्भरता नहीं रही
- कहीं भी deploy किया जा सकता है
- किसी भी database का उपयोग किया जा सकता है
- runtime compatibility की चिंता बिना third-party services integrate की जा सकती हैं
Migration strategy और सीख
- Migration का उपयोग समय के साथ जमा हुई API design समस्याओं को सुधारने के अवसर के रूप में किया गया
- नया v2 API पुराने v1 के साथ चलता है, इसलिए deprecation period में customers दोनों versions इस्तेमाल कर सकते हैं
- Serverless बनाए रखने का एक फ़ायदा यह था कि usage शून्य तक गिरने पर भी v1 API चलाने की लागत बहुत ज़्यादा नहीं थी, इसलिए मुफ़्त migration period मिल गया
-
जो चीज़ें बरकरार रखीं
- Serverless approach की हर चीज़ नहीं छोड़ी गई
- global edge deployment: AWS Global Accelerator का उपयोग कर दुनिया भर में low latency बनाए रखी गई
- auto scaling: Fargate serverless constraints के बिना scaling संभालता है
-
Rate limiter performance में सुधार
- Serverless model में speed, accuracy, और cost के बीच बड़ा trade-off था, और distributed nature के कारण तीनों साथ पाना लगभग असंभव था
- Stateful server और in-memory state के साथ ज़्यादा तेज, ज़्यादा accurate, और कम operating cost वाला rate limiter बनाया गया
कब serverless सही है (और कब नहीं)
-
Serverless कब सही है
- अनियमित workloads: जब लगातार run नहीं करना हो, तब scale-to-zero की economics शानदार होती है
- simple request/response patterns: जब persistent state या complex data pipeline की ज़रूरत न हो
- event-driven architecture: infra management के बिना events पर response देने के लिए बेहतरीन
-
Serverless कब सही नहीं है
- जब consistent low latency चाहिए: external network dependency performance गिराती है
- जब persistent state चाहिए: statelessness को bypass करने का काम complexity बढ़ाता है
- high-frequency workloads: per-invocation billing model किफ़ायती नहीं होता
- जब fine-grained control चाहिए: platform abstraction एक constraint बन सकता है
-
Complexity cost
- Migration की सबसे बड़ी सीख platform constraints को bypass करने की complexity cost को समझना थी
-
Serverless में क्या बनाना पड़ा
- statelessness को bypass करने के लिए sophisticated caching library
- data batching के लिए कई auxiliary services
- metrics collection के लिए complex log pipeline
- local development के लिए sophisticated workarounds
-
Stateful server में
- ऊपर की सारी चीज़ें गायब हो गईं
- कई moving parts वाले distributed system से सरल application architecture पर वापसी हुई
- कई बार constraints को bypass करने से बेहतर दूसरी foundation चुनना ही सबसे अच्छा solution होता है
अगले कदम
- अभी यह Global Accelerator के पीछे AWS Fargate पर चल रहा है, लेकिन यह अस्थायी व्यवस्था है
- अगले साल अपना deployment platform "Unkey Deploy" लॉन्च करने की योजना है, जिससे customers (और Unkey खुद) Unkey को अपनी पसंद की किसी भी जगह चला सकेंगे
- Stateful Go server पर बदलाव Unkey को वास्तव में portable और self-hostable बनाने का पहला कदम है
- Implementation details GitHub repository में open source के रूप में सार्वजनिक हैं
3 टिप्पणियां
मैं भी कभी लगभग serverless का कट्टर समर्थक था और serverless आर्किटेक्चर को हर जगह लागू करता था, लेकिन इन दिनों मैं
ec2एक औरrdsएक से बनी संरचना को ज़्यादा पसंद करता हूँ। और फिर ज़रूरत के हिसाब से धीरे-धीरे चीज़ों को एक-एक करके अलग करता हूँ। serverless अपनाने के बारे में अब बहुत सोच-विचार करके ही फैसला करता हूँ.इसके कई कारण हैं, लेकिन अगर टीम में सिर्फ एक भी ऐसा व्यक्ति हो जिसे serverless की जानकारी न हो, तो communication/maintenance की लागत काफ़ी बढ़ जाती है। और जब फिर से सर्वर चलाकर देखा, तो एक बार फिर महसूस हुआ कि serverless उतना सस्ता भी नहीं था और उतना सुविधाजनक भी नहीं था, जितना मैंने सोचा था।
Hacker News राय
कई सालों तक serverless environment (मुख्य रूप से amazon lambda, और कुछ अन्य भी) इस्तेमाल करने के अनुभव के आधार पर, मैं लेखक की राय से पूरी तरह सहमत हूँ
serverless कुछ हिस्सों में काम कम करता है, लेकिन साथ ही "कृत्रिम रूप से पैदा होने वाली समस्याओं" को हल करने में दूसरे क्षेत्रों में काम बढ़ जाता है
मेरे एक मामले में upload capacity limit की समस्या थी
जब मौजूदा application को serverless में migrate किया, तो मुझे लगा कि बड़े customer data import के लिए API endpoint बना देना और एक background worker जोड़ देना काफी होगा
लेकिन "api gateway" (code को call करने वाला proxy) में 100MB से ज्यादा upload नहीं हो सकता था, और जब पूछा कि क्या limit बदली जा सकती है, तो बस यही कहा गया कि customers को छोटे-छोटे files में बाँटकर upload करने को कहें
तकनीकी रूप से यह ठीक लग सकता है, लेकिन हकीकत यह है कि असली customers अपना upload तरीका बदलने वाले नहीं हैं
यह कुछ वैसा है जैसे "vacuum में तो बढ़िया चलता है" — सिद्धांत में शानदार लगता है, लेकिन व्यवहार में serverless पर जाने से जो समय और लागत बचती है, वही आखिर में serverless-विशेष समस्याएँ सुलझाने में फिर से लग जाती है
इस समस्या को हल करने के लिए presigned S3 URL देना चाहिए
user को सीधे S3 पर upload करने देना, फिर upload result भेजवाना, या file name को request id से अलग पहचानना जैसी methods से integration किया जा सकता है
AWS environment लंबे समय से इस्तेमाल करने के नाते यह चीज़ परेशान करने वाली ज़रूर है, लेकिन अगर arbitrary file upload API खुला छोड़ दिया जाए तो DoS attack का जोखिम बड़ा होता है, इसलिए 100MB limit अपने आप में समझ में आती है
बस आजकल internet speed को देखते हुए 100MB का मानक थोड़ा पुराना लगता है
फिर भी किसी न किसी बिंदु पर limit ज़रूरी होगी
हमारी company एक समय AWS SSL certificates विभाग के लिए flagship customer जैसी थी
Vanity URL (custom domain) support करना था, इसलिए हर domain के लिए SSL certificate चाहिए था, और उनकी संख्या हजारों में थी
AWS का certificate management tool कुछ सौ तक तो सहज था, लेकिन इस समस्या के हल होने में लगभग 3 महीने लग गए
यह देखना हैरान करने वाला था कि AWS की कुछ services बहुत कम customers की मांग के हिसाब से जल्दी प्रतिक्रिया नहीं दे पातीं
शुरुआत में Lambda बहुत संभावनाशील लगा, इसलिए अपनाया, लेकिन अंत में हमने सारे Lambda projects छोड़ दिए और ज़रूरत के हिसाब से container environment में चले गए
Lambda में भी Node runtime को हर 1~2 साल में upgrade करना पड़ता है, जबकि containers में आप यह चक्र खुद तय कर सकते हैं, इसलिए वह ज्यादा flexible है
computer science की सबसे कठिन समस्या है एक computer से दूसरे computer में file copy करना
भविष्य के पाठकों के लिए एक reference छोड़ रहा हूँ
"tus" uploader और endpoint इस्तेमाल करने पर upload के दौरान chunking, resume जैसी सुविधाएँ मिलती हैं, इसलिए ऐसी limits पार करने के लिए यह उपयुक्त है
https://tus.io/
जैसा article में समझाया गया है, serverless की अपनी उपयोगिता ज़रूर है
लेकिन मुझे नहीं लगता कि यह ज़्यादातर applications के लिए उपयुक्त है
खास परिस्थिति न हो तो मैं serverless को core infrastructure के रूप में इस्तेमाल करने की योजना नहीं बनाऊँगा
असल में इससे infrastructure management और झंझटभरा हो जाता है, ऐसा लगता है
हर platform की requirements अलग हैं, test/development का तरीका भी अलग है, इसलिए हर बार चीज़ें अस्पष्ट लगती हैं और local testing भी कठिन हो जाती है
abstraction layer में भी हर platform के अपने traps हैं, और कोई वास्तविक standard मौजूद नहीं है
Docker image के रूप में executable package करना ज्यादा सुविधाजनक है, और environment setup को भी ठीक-ठाक abstract किया जा सकता है, इसलिए मेरे लिए यह ज्यादा स्वाभाविक development environment है
Linux environment और filesystem स्तर की न्यूनतम abstraction सबसे प्रभावी लगती है
ज़रूरत हो तो उसी image को server के रूप में चलाकर on-demand या हमेशा-तैयार स्थिति में operate भी किया जा सकता है
पिछले 10 सालों के कई technology trends को देखें तो अक्सर बड़े enterprises ने अपनी ही scale पर मौजूद समस्याओं को हल करने के लिए जिन technologies का इस्तेमाल किया, वही बाद में hype बन गईं
उदाहरण के तौर पर GraphQL, react, Tailwind, NextJS आदि आते हैं
कोई भी tool हर problem का universal समाधान नहीं होता; अपनी स्थिति और समस्या को अनुभव और समझ के आधार पर चुनना ज़रूरी है
मैं अभी amazon lambda app को local में चलाने की कोशिश करते हुए कितना "मज़े" कर रहा हूँ, यह बताना मुश्किल है
deploy से पहले test करना अपने आप में challenge है
Knative (Kubernetes के लिए Serverless) सीधे containers स्वीकार करता है
क्योंकि यह एक standard packaging format है, इसलिए अलग-अलग platforms पर आसानी से ले जाया जा सकता है
वह team असल में application नहीं, बल्कि stateful server application में integrate होने वाली library बना रही थी
performance का फायदा भी इस वजह से था कि authentication को customer environment के करीब process किया गया, serverless की वजह से नहीं
क्या लगभग सभी "serverless" platforms Docker images स्वीकार नहीं करते?
मुझे पता है Cloud Run तो करता है
असल चिंता यह है कि “serverless function” बहुत ज़्यादा चीज़ें abstract कर देता है
ClickHouse को हजारों छोटे insert पसंद नहीं हैं, इसलिए हम chproxy नाम की एक Go service से events इकट्ठा करके बड़े batch में भेजते हैं
हर Cloudflare Worker analytic events chproxy को भेजता है, और chproxy उन्हें इकट्ठा करके ClickHouse को bulk में भेजता है
खासकर ClickHouse data के मामले में, अलग service बनाने के बजाय asynchronous insert feature भी था; यह क्यों नहीं इस्तेमाल किया गया, यह जानना दिलचस्प होगा
https://clickhouse.com/docs/optimize/asynchronous-inserts
developers ऐसे tools में दबे हुए लगते हैं जो supposedly चीज़ें "आसान" बनाते हैं
जबकि अधिकांश problems सबसे बुनियादी tools (compiler, bash script, library) से भी आसानी से हल हो सकती हैं
tools के इस obsession की वजह से कई बार company और developers दोनों को नुकसान होता है
मेरी राय में, 2013 का Docker ही आखिरी tool था जिसने सच में व्यापक और सकारात्मक बदलाव किया
उसके बाद की चीज़ें कुछ companies के लिए मददगार हो सकती हैं, लेकिन उन्हें हर company पर लागू करने की कोशिश से अक्सर productivity टूटती है या systems अस्थिर हो जाते हैं
आजकल Cloudflare जैसी जगहों पर v8 isolates को 'next-gen docker' की तरह push किया जा रहा है, लेकिन कुछ workloads के लिए बेहतरीन होना और हर जगह फिट होना अलग बात है
"Docker image लो और उसे internet पर चला दो" वाला pattern इतना ताकतवर है कि मुझे लगता है 2040 में भी यही सबसे प्रभावी तरीका रहेगा
यह भी समस्या है कि fundamentals जानने वाले लोग कम होते जा रहे हैं
काम करने का तरीका ऐसा बन गया है कि stack का ज़्यादातर हिस्सा third-party services को outsource कर दिया जाता है, और खुद सिर्फ core application का कुछ भाग बनाया जाता है
यहाँ तक कि वह भी AI लिख सकता है
पूरी industry जैसे "सीखी हुई लाचारी" को बढ़ावा दे रही है
जितना लोग सोचते हैं उससे कहीं ज्यादा लोग compiler, bash script, library जैसी बुनियादी चीज़ों को अच्छी तरह नहीं जानते
AWS lambda बहुत ही सस्ता है
visibility बढ़ाने के लिए यह काम आता है!
bash script लिखकर Staff level तक पहुँचा हुआ मैंने किसी को नहीं देखा
मैं "vercel security checkpoint" से पूछना चाहता हूँ
iPhone पर proton VPN और Firefox Focus के साथ California और Canada exit node से connect करने पर बार-बार code 99 "Failed to verify your browser" error आता है
दिक्कत क्या है?
यह thread मेरी सोच को और पक्का करता है
"serverless" शब्द की परिभाषा ही इतनी धुंधली है कि नाम ही बेमानी लगता है
आखिर servers अभी भी मौजूद हैं
यह कुछ वैसा है जैसे "बिना बिजली वाला" कहना, जबकि असल में बिजली इस्तेमाल हो रही हो
नाम बदल गया है, पर यह नहीं बताता कि वास्तव में क्या हो रहा है
मुझे नहीं लगता कि पूरी सीख सिर्फ "serverless बुरा है" तक सीमित है
ज्यादा महत्वपूर्ण सबक यह है कि अगर आपकी service की dependencies हैं, तो service को client के करीब ले जाने भर से end-to-end experience तेज़ नहीं हो जाता, जब तक dependencies को भी साथ न ले जाया जाए
स्वाभाविक रूप से dependencies के करीब build करना बेहतर है, और अगर वह पर्याप्त न हो तो सभी dependencies को client के करीब ले जाना या sync करना पड़ता है, लेकिन व्यवहार में यह प्रक्रिया अक्सर बहुत जटिल हो जाती है
dependencies को कैसे और कितनी बार इस्तेमाल किया जाता है, इस पर बहुत कुछ निर्भर करता है; अगर DB है तो उसे server के करीब रखना चाहिए या client के करीब, यह use case पर निर्भर करेगा
कुछ scenarios में fast response चाहिए होता है, कुछ में delay स्वीकार्य है
server या client side पर क्या cache किया जा सकता है, उसके आधार पर architecture को अलग तरह से बाँटा जा सकता है
मुझे नहीं लगता कि इसे सिर्फ द्विआधारी तरीके से देखना चाहिए
अगर सबसे बेहतर price-to-performance ratio चाहिए, तो सही जवाब है कि instance खुद setup करो और जो चाहिए वह खुद संभालो
cloud providers को overbilling magician बनने की ज़रूरत नहीं है
अभी हम जिस "local maximum" पर पहुँचे हैं, वह है Docker containers को standard environment/deployment artifact मानना और ज़रूरत पड़ने पर सिर्फ secrets inject करना
इससे local testing आसान होती है, और infrastructure automation, reproducibility जैसी ज़्यादातर बड़ी खूबियाँ भी मिल जाती हैं
serverless ज़्यादातर apps के लिए overkill है, लेकिन कुछ apps के लिए यह अच्छी तरह फिट बैठता है
खासकर simple utilities, on-demand services, या बड़े scale की stateless apps, जिन्हें अपनी infrastructure की ज़रूरत न हो, उनके लिए serverless ज्यादा उपयुक्त हो सकता है
यह ज़रूरी नहीं कि serverless सिर्फ simple use cases के लिए ही हो; बल्कि मुझे लगता है कि "traditional webapp" model और serverless platform के बीच एक मूलभूत टकराव है
लगता है अब मैं misterio के लिए तैयार हूँ
https://github.com/daitangio/misterio
यह simple stateless Docker cluster wrapper है
यह मेरे homelab से शुरू हुआ था, लेकिन फिर इसे अच्छी प्रतिक्रिया मिली
Docker कुछ-कुछ microservices जैसा है
कुछ apps के लिए यह उपयुक्त है, लेकिन industry standard की तरह इसे बढ़ा-चढ़ाकर पेश किया गया है
Docker का अंधाधुंध इस्तेमाल करने पर security patching और operations burden बढ़ता है; हर project में बिना सोचे इस्तेमाल करना risk management की विफलता है
dependency problems को अब ज्यादातर developers global install से बचने वाले patterns से हल कर लेते हैं
पहले जैसा Docker अनिवार्य नहीं रहा, लेकिन अभी भी mainstream है
hosting providers के नज़रिए से देखें तो Docker अपनाने से margin कम-से-कम 10% बढ़ सकता है
नीचे किसी ने जिस "tool obsession" की बात की, मुझे लगता है Docker भी उसका हिस्सा है
बात यह नहीं है that serverless काम नहीं करता; मुद्दा यह है कि authors को उस foundation की पर्याप्त समझ नहीं थी जिसे वे बना रहे थे
latency-sensitive API को stateless edge runtime पर रखना beginner-level mistake है, और उसके कारण जो pain हुआ वह पूरी तरह predictable था
मेरे अनुभव में cloud services की ज्यादातर समस्याएँ architecture के misuse या misunderstanding से आती हैं
थोड़ा और सावधान design होता, तो ये मानवीय समस्याएँ टाली जा सकती थीं
लेकिन दिक्कत यह है कि cloud vendors अक्सर अपने products को आकर्षक marketing के साथ बेचते हैं और वास्तविक performance numbers छिपाए रखते हैं
क्या Lambdas मेरे workload के लिए सच में पर्याप्त तेज़ हैं, या AWS RDS external replication मेरे लिए सही है, यह तब तक पता नहीं चलता जब तक आप test न कर लें
मैंने अनुभव से सीखा है कि AWS की वास्तविक performance खुद benchmark करनी पड़ती है
मुद्दा यह नहीं कि authors समझ नहीं पाए; किसी ने जो जानकारी साझा की, उसकी अपनी अहमियत है
मुझे नहीं लगता कि इसे सिर्फ "beginner mistake" कहकर टाला जा सकता है
असल दुनिया में engineers अक्सर जानते हैं कि कोई approach production के लिए सही नहीं है, लेकिन managers उसे "आजकल का तरीका" कहकर आसानी से आगे बढ़ा देते हैं
या फिर time और budget constraints की वजह से "कम बेहतर विकल्प" चुनना पड़ता है
या यह भी हो सकता है कि मूल implementation team को सच में पूरी समझ न हो; फिर भी ऐसी stories साझा करना हमारी पूरी community के लिए बहुत फायदेमंद है
मेरे अनुभव में, अगर किसी चीज़ की पक्की ज़रूरत हो (जैसे fast autoscaling, low latency, CPU, disk, network speed आदि), तो सीधे EC2 instances खुद manage करना सबसे भरोसेमंद होता है
control छोड़कर performance gain की उम्मीद करोगे, तो ऐसे bottlenecks मिलेंगे जिन्हें ठीक भी नहीं कर पाओगे
आखिरकार इसका मतलब यही है कि authors "आज के 10,000 में से एक" थे
https://xkcd.com/1053/
व्यक्तिगत रूप से, ऐसी जानकारी और गलतियाँ साझा करने के लिए मैं उनका आभारी हूँ
इंजीनियरिंग हमेशा लागत की लड़ाई होती है
शुरुआत में इसका उपयोग prototyping या business बनाने में लगने वाला समय कम करने के लिए किया जाता है
बाद में optimization करते हुए लागत घटानी चाहिए
ऐसे लेख अपने-आप में यह साबित करते हैं कि लेखक कितना कम इंजीनियर है
ऐसा ही