SSD Nodes Learn 🎉 VPS $4.99/माह से
गाइड Matt Connorलेखक: Matt Connor · अपडेट किया गया: 2026-08-07

LiteLLM को self-host कैसे करें: LLM gateway गाइड

LiteLLM का उपयोग करके अपने सभी LLM प्रदाताओं के लिए एक OpenAI-compatible endpoint बनाएँ। वर्चुअल कीज़, प्रति-की बजट और ऑटोमैटिक फॉलबैक सेटअप करने का पूरा तरीका यहाँ जानें।

Self-hosted LLM gateway क्या करता है

LiteLLM एक open source LLM gateway है जिसे आप स्वयं host करते हैं: यह एक ऐसा HTTP endpoint है जिसे आपके सभी applications call करते हैं, और यह प्रत्येक request को उस provider के पास भेज देता है जिसे उसे पूरा करना चाहिए। LLM का अर्थ large language model है। यह gateway OpenAI chat completions API (application programming interface) का उपयोग करता है, इसलिए कोई भी client library जो पहले से OpenAI के साथ काम करती है, वह दो बदलावों के बाद इसके साथ काम करने लगती है: base URL और key।

यह indirection की एक परत ही इसका मुख्य उद्देश्य है। आपके applications को अब provider credentials रखने की आवश्यकता नहीं होती। किसी model को बदलना अब कोड में पांच अलग-अलग services को बदलने के बजाय सर्वर पर config file में केवल एक line का बदलाव रह जाता है। और चूंकि हर call एक ही process से होकर गुजरती है, इसलिए आपके पास budget निर्धारित करने और खर्च का रिकॉर्ड रखने के लिए एक केंद्रीय स्थान होता है।

इसे run करने के बाद आपको ये सुविधाएं मिलती हैं:

  • एक endpoint. Applications https://gateway.example.com/v1 को target करती हैं और आपके द्वारा बनाए गए model name, जैसे bulk या strong, के लिए request भेजती हैं।
  • Virtual keys. प्रत्येक application को अपनी key मिलती है, जिसकी अपनी model allowlist और अपना spend ceiling होता है। आप दूसरों को प्रभावित किए बिना एक key को revoke कर सकते हैं।
  • Fallbacks. कोई failed call या बहुत बड़ा prompt स्वचालित रूप से किसी दूसरे model पर retry किया जाता है।
  • एक logged record. प्रत्येक request अपनी लागत के साथ एक row लिखती है, जिससे यह पता चल जाता है कि "किस app ने कितना खर्च किया"।

गेटवे को स्वयं क्यों चलाएं

एक managed router का आकार वही होता है, लेकिन हर request के बीच में किसी और की process काम कर रही होती है। इसे स्वयं चलाने से आपके provider keys और prompt text उस box पर सुरक्षित रहते हैं जिसे आप नियंत्रित करते हैं। इसकी वास्तविक लागत यह है: अब आप उस component का संचालन करते हैं जिस पर हर application निर्भर करती है। इस guide का अंतिम भाग इसी लागत के बारे में है, क्योंकि यह वह हिस्सा है जिसे अधिकांश लेख छोड़ देते हैं।

आवश्यकताएँ

  • Ubuntu 24.04 पर चलने वाला एक VPS (virtual private server), जिसमें Docker और Compose plugin इंस्टॉल हो।
  • यदि मशीन के बाहर से TLS (transport layer security) के माध्यम से gateway तक पहुँचना है, तो एक domain name जो उस VPS को point करता हो।
  • कम से कम एक provider API key।

Gateway कोई inference नहीं करता है। यह केवल requests को forward करता है और answers को stream करता है, इसलिए इसका CPU load model size के बजाय request volume पर निर्भर करता है। 1 vCPU वाला box बिना किसी समस्या के कई internal applications को संभाल सकता है। जो चीज़ बढ़ती है वह database है, क्योंकि gateway प्रत्येक request के लिए एक spend row लिखता है।

सबसे पहले config.yaml लिखें

Config फ़ाइल यह तय करती है कि क्लाइंट किन मॉडल्स के लिए अनुरोध कर सकता है। इसमें चार शीर्ष-स्तरीय (top level) सेक्शन महत्वपूर्ण हैं: model_list, litellm_settings, router_settings और general_settings

model_list:
  - model_name: bulk
    litellm_params:
      model: anthropic/claude-haiku-4-5
      api_key: os.environ/ANTHROPIC_API_KEY
  - model_name: strong
    litellm_params:
      model: anthropic/claude-sonnet-5
      api_key: os.environ/ANTHROPIC_API_KEY
  - model_name: strong
    litellm_params:
      model: openai/gpt-5.5
      api_key: os.environ/OPENAI_API_KEY

litellm_settings:
  num_retries: 2
  request_timeout: 120
  allowed_fails: 3
  cooldown_time: 30
  json_logs: true
  set_verbose: false

router_settings:
  fallbacks: [{"bulk": ["strong"]}]
  context_window_fallbacks: [{"bulk": ["strong"]}]

general_settings:
  background_health_checks: true
  health_check_interval: 300

model_name वह नाम है जिसे आपके क्लाइंट भेजते हैं। litellm_params.model वास्तविक मॉडल है, जिसे provider/model के रूप में लिखा जाता है। अपने मॉडल्स का नाम वेंडर के बजाय उनके कार्य (job) के आधार पर रखें। जो एप्लिकेशन bulk के लिए अनुरोध करती है, वह तब भी काम करती रहती है जब आप अगले महीने यह तय करते हैं कि bulk को एक अलग मॉडल होना चाहिए।

api_key: os.environ/ANTHROPIC_API_KEY LiteLLM को रन टाइम पर उस वेरिएबल को पढ़ने के लिए कहता है। वास्तविक की (literal key) कभी भी फ़ाइल में दिखाई नहीं देती है, जो महत्वपूर्ण है क्योंकि config.yaml वह फ़ाइल है जिसे आप कमिट (commit) करते हैं।

दो एंट्रीज़ जानबूझकर strong नाम साझा करती हैं। जब एक से अधिक डिप्लॉयमेंट में समान model_name होता है, तो राउटर उन्हें एक-दूसरे के स्थान पर उपयोग करने योग्य (interchangeable) मानता है और पहले वाले के विफल होने पर दूसरे को आज़माता है। इस तरह strong तब भी काम करता रहता है जब किसी प्रोवाइडर का समय खराब चल रहा हो।

num_retries: 2 किसी retryable त्रुटि पर उसी डिप्लॉयमेंट को फिर से आज़माता है। फॉलबैक (fallback) केवल तभी सक्रिय होता है जब वे सभी रिट्राइज़ (retries) समाप्त हो जाते हैं। allowed_fails: 3 के साथ cooldown_time: 30 किसी डिप्लॉयमेंट को 3 बार विफल होने के बाद 30 सेकंड के लिए रोटेशन से बाहर कर देता है, ताकि 500 एरर देने वाला प्रोवाइडर हर अनुरोध पर आज़माया न जाए।

fallbacks और context_window_fallbacks के ट्रिगर अलग-अलग होते हैं, और दूसरा वाला वह उपयोगी विकल्प है जिसे लोग छोड़ देते हैं।

  • fallbacks तब सक्रिय होता है जब प्राथमिक कॉल विफल हो जाती है।
  • context_window_fallbacks तब सक्रिय होता है जब प्रोवाइडर अनुरोध को मॉडल की कॉन्टेक्स्ट विंडो से बड़ा होने के कारण अस्वीकार कर देता है, ताकि बहुत बड़ा प्रॉम्प्ट कॉलर को त्रुटि भेजने के बजाय उस मॉडल के पास जाए जिसमें उसके लिए जगह हो।

इसके अलावा content_policy_fallbacks भी है, जो कंटेंट पॉलिसी के आधार पर मना करने वाले प्रोवाइडर के लिए है। इसे केवल तभी सेट करें जब आपके पास उन कॉल्स को भेजने के लिए कोई उचित स्थान हो।

VPS पर Docker Compose के साथ LiteLLM को Deploy करना

तीन फाइलों वाली एक डायरेक्टरी बनाएँ: config.yaml, docker-compose.yml और .env। अपस्ट्रीम क्विकस्टार्ट latest टैग को पुल करता है। इसके बजाय एक रिलीज टैग को पिन करें, ताकि अगले महीने docker compose up -d करने पर आपको वही गेटवे मिले जो आज मिला है, और रोलबैक केवल एक लाइन का काम हो।

services:
  litellm:
    image: ghcr.io/berriai/litellm:v1.95.0
    restart: unless-stopped
    command: ["--config", "/app/config.yaml", "--num_workers", "1"]
    ports:
      - "127.0.0.1:4000:4000"
    volumes:
      - ./config.yaml:/app/config.yaml:ro
    env_file: .env
    depends_on:
      db:
        condition: service_healthy

  db:
    image: postgres:16
    restart: unless-stopped
    environment:
      POSTGRES_USER: litellm
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?set POSTGRES_PASSWORD in .env}
      POSTGRES_DB: litellm
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U litellm"]
      interval: 5s
      timeout: 5s
      retries: 10
    volumes:
      - postgres_data:/var/lib/postgresql/data

volumes:
  postgres_data:

Compose यहाँ .env को दो बार पढ़ता है। एक बार compose फाइल के अंदर ${POSTGRES_PASSWORD} को सब्स्टिट्यूट करने के लिए, और दूसरी बार env_file के माध्यम से हर वेरिएबल को कंटेनर में पास करने के लिए।

अगस्त 2026 में v1.95.0 वर्तमान रिलीज थी। प्रोजेक्ट के रिलीज पेज को देखें और डिप्लॉयमेंट के समय जो भी वर्तमान हो उसे पिन करें। प्रत्येक रिलीज एक सिग्नेचर पब्लिश करती है, इसलिए आप इमेज पर भरोसा करने से पहले उसे चेक कर सकते हैं:

cosign verify --key https://raw.githubusercontent.com/BerriAI/litellm/v1.95.0/cosign.pub ghcr.io/berriai/litellm:v1.95.0

पोर्ट लाइन 127.0.0.1:4000:4000 है, जो पोर्ट को केवल लूपबैक इंटरफेस पर पब्लिश करती है। इसके बजाय 4000:4000 लिखें और आपका गेटवे पूरे इंटरनेट से एक्सेस किया जा सकेगा, क्योंकि Docker iptables FORWARD चेन में अपने नियम जोड़ता है और वे ufw से पहले इवैल्यूएट होते हैं, इसलिए ufw deny 4000 इसे नहीं रोकता है। यह सबसे आम तरीका है जिससे एक सेल्फ-होस्टेड गेटवे अनचाहे रूप से ओपन हो जाता है: देखें Docker ufw के ऊपर से कंटेनर पोर्ट को कैसे पब्लिश करता है। बाहर से आने वाला ट्रैफिक इसके बजाय रिवर्स प्रॉक्सी के माध्यम से आता है।

Provider keys को image से बाहर रखें

.env फ़ाइल में सभी secrets होते हैं। इसे run time पर environment के रूप में pass किया जाता है, इसलिए इसे कभी भी image में bake नहीं किया जाता है और न ही कभी commit किया जाता है।

LITELLM_MASTER_KEY=sk-REPLACE_ME
LITELLM_SALT_KEY=sk-REPLACE_ME_TOO
POSTGRES_PASSWORD=REPLACE_ME_AS_WELL
DATABASE_URL=postgresql://litellm:REPLACE_ME_AS_WELL@db:5432/litellm
STORE_MODEL_IN_DB=True
LITELLM_MODE=PRODUCTION
LITELLM_LOG=ERROR
ANTHROPIC_API_KEY=sk-ant-...
OPENAI_API_KEY=sk-proj-...

दो LiteLLM keys को वास्तविक randomness के साथ generate करें, फिर फ़ाइल को lock करें:

printf 'sk-%s\n' "$(openssl rand -hex 32)"
chmod 600 .env

LITELLM_MASTER_KEY एडमिन क्रेडेंशियल है। यह management API को authenticate करता है और /ui पर Admin UI के लिए पासवर्ड है। किसी भी application के पास इसे कभी नहीं होना चाहिए।

LITELLM_SALT_KEY डेटाबेस में संग्रहीत provider क्रेडेंशियल्स को encrypt करता है। इसे एक बार सेट करें और छोड़ दें। यदि आप इसे बाद में बदलते हैं, तो पहले से संग्रहीत क्रेडेंशियल्स को decrypt नहीं किया जा सकेगा। इसके परिणामस्वरूप gateway सामान्य रूप से start तो हो जाएगा, लेकिन उन providers को की जाने वाली हर call authentication पर विफल हो जाएगी।

STORE_MODEL_IN_DB=True आपको config.yaml को छुए बिना Admin UI से models को जोड़ने और edit करने की सुविधा देता है। यह सुविधाजनक है, लेकिन यह आपके source of truth को दो भागों में विभाजित कर देता है। तय करें कि कौन सा authoritative है और उस निर्णय को config के पास लिख लें।

जो तर्क keys को config फ़ाइल से बाहर रखता है, वही तर्क उन्हें उन tools से भी बाहर रखता है जो आप किसी agent को देते हैं। Provider secrets को AI agents से बाहर रखना उस pattern को कवर करता है, और Docker Compose में env फ़ाइलें और secrets इसकी कार्यप्रणाली को कवर करता है।

इसे start करें और पहली boot प्रक्रिया को monitor करें:

docker compose up -d
docker compose logs -f litellm

जाँचें कि यह वास्तव में काम कर रहा है

यहाँ दो unauthenticated probes और एक authenticated probe है, और वे अलग-अलग कारणों से विफल होते हैं।

curl -s http://127.0.0.1:4000/health/liveliness
curl -s http://127.0.0.1:4000/health/readiness

/health/liveliness को किसी authentication की आवश्यकता नहीं होती है और जब process चल रही होती है तो यह "I'm alive!" का उत्तर देता है। /health/readiness को भी किसी authentication की आवश्यकता नहीं होती है। यह "status": "healthy" और db field के साथ एक JSON object लौटाता है, या जब database तक नहीं पहुँचा जा सकता है तो 503 error देता है। अपनी monitoring को readiness पर point करें, क्योंकि liveliness उस gateway पर भी green रहती है जो एक भी virtual key को look up नहीं कर सकता है।

Authenticated check वह है जो providers से बात करता है:

curl -s http://127.0.0.1:4000/health \
  -H "Authorization: Bearer $LITELLM_MASTER_KEY"

यह healthy_endpoints और unhealthy_endpoints arrays के साथ उत्तर देता है। unhealthy_endpoints में authentication error के साथ बैठा एक model यह दर्शाता है कि .env में provider key गलत है या गायब है, जो कि वह विफलता है जिसे आप अभी ढूँढना चाहते हैं। चूँकि background_health_checks: true set है, proxy इन probes को हर health_check_interval seconds में अपने आप चलाता है और /health अंतिम परिणाम लौटाता है, इसलिए इसे poll करने पर हर बार आपके providers को test request नहीं भेजी जाती है।

वर्चुअल कीज़ और प्रति-की बजट

प्रत्येक एप्लिकेशन को अपनी एक की (key) मिलती है, जिसे मास्टर की के आधार पर तैयार किया जाता है।

curl -s http://127.0.0.1:4000/key/generate \
  -H "Authorization: Bearer $LITELLM_MASTER_KEY" \
  -H 'Content-Type: application/json' \
  -d '{
    "key_alias": "nightly-summariser",
    "models": ["bulk"],
    "max_budget": 5,
    "budget_duration": "30d",
    "rpm_limit": 60,
    "tpm_limit": 200000
  }'

रिस्पॉन्स में key फील्ड होता है जो sk- से शुरू होता है। यह स्ट्रिंग ही वह चीज़ है जो एप्लिकेशन को प्राप्त होती है, और एप्लिकेशन को केवल यही प्राप्त होता है।

  • models उन अनुरोधों की एक अनुमति सूची (allowlist) है जो यह की कर सकती है। ऊपर दी गई की केवल bulk के लिए अनुरोध कर सकती है और किसी अन्य चीज़ के लिए नहीं।
  • max_budget: 5 के साथ budget_duration: "30d" का अर्थ है प्रति 30 दिनों के रोलिंग चक्र में पांच अमेरिकी डॉलर, जिसके बाद की काम करना बंद कर देती है।
  • rpm_limit और tpm_limit केवल इस की के लिए प्रति मिनट अनुरोधों और प्रति मिनट टोकन की सीमा तय करते हैं।
  • key_alias वह है जिसे आप छह सप्ताह बाद स्पेंड लॉग में पहचान पाएंगे। इसे हमेशा सेट करें।

जब बजट समाप्त हो जाता है, तो कॉल HTTP 401 के साथ विफल हो जाती है और उसका बॉडी इस प्रकार होता है:

ExceededBudget: Current spend for token: 7.2e-05; Max Budget for Token: 2e-07

स्टेटस कोड ही इसे भ्रमित करने वाला बनाता है। एक क्लाइंट लाइब्रेरी 401 को ऑथेंटिकेशन समस्या के रूप में रिपोर्ट करती है, इसलिए स्टैक ट्रेस पढ़ने वाला डेवलपर यह जांचने लगता है कि क्या की वैध है। स्टेटस कोड के साथ रिस्पॉन्स बॉडी को भी लॉग करें, अन्यथा बजट समाप्त होने की स्थिति हर बार टूटे हुए क्रेडेंशियल जैसी दिखेगी।

कीज़ का निरीक्षण और समायोजन उसी मैनेजमेंट API के माध्यम से करें:

curl -s "http://127.0.0.1:4000/key/info?key=sk-..." \
  -H "Authorization: Bearer $LITELLM_MASTER_KEY"

curl -s -X POST http://127.0.0.1:4000/key/update \
  -H "Authorization: Bearer $LITELLM_MASTER_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"key": "sk-...", "max_budget": 25}'

गेटवे पर लागू किया गया बजट तब भी प्रभावी रहता है जब समस्या स्वयं एजेंट के साथ हो, यही कारण है कि यह VPS पर AI एजेंटों के लिए लागत नियंत्रण की आधारशिला है।

बल्क वर्क को सस्ते मॉडल पर भेजें

क्लाइंट को गेटवे की ओर पॉइंट करें। बेस URL, की (key), और मॉडल का नाम सेट करें:

curl -s http://127.0.0.1:4000/v1/chat/completions \
  -H "Authorization: Bearer sk-<the virtual key>" \
  -H 'Content-Type: application/json' \
  -d '{
    "model": "bulk",
    "messages": [{"role": "user", "content": "Say hello in five words."}]
  }'

कोई भी OpenAI क्लाइंट लाइब्रेरी एक ही तरह से काम करती है: base_url को https://gateway.example.com/v1 पर सेट करें और api_key को वर्चुअल की (key) पर सेट करें।

config.yaml की राउटिंग पॉलिसी अब कॉलर को पता चले बिना लागू हो जाती है। bulk के लिए किया गया अनुरोध सस्ते मॉडल पर जाता है। यदि वह कॉल अपने रिट्राय (retries) के बाद विफल हो जाती है, तो अनुरोध को strong के विरुद्ध फिर से प्रयास किया जाता है। यदि प्रॉम्प्ट bulk के लिए बहुत लंबा है, तो context_window_fallbacks इसे त्रुटि देने के बजाय strong पर भेज देता है। बल्क वर्क जैसे कि क्लासिफिकेशन पास या समराइजिंग बैकलॉग डिफ़ॉल्ट रूप से सस्ते में चलते हैं, और केवल कठिन अनुरोधों पर ही अधिक खर्च आता है।

यहीं पर एक गेटवे टूल-उपयोग करने वाले एजेंट्स के साथ अपनी उपयोगिता साबित करता है। एक उसी VPS पर MCP (model context protocol) सर्वर और उसे चलाने वाला एजेंट दोनों एक ही एंडपॉइंट की ओर पॉइंट कर सकते हैं, जिससे उनके पीछे का मॉडल किसी को भी फिर से डिप्लॉय किए बिना बदल जाता है।

आपको कैसे पता चलेगा कि fallback हुआ है?

यह विफलता का वह प्रकार है जिसमें पैसे का नुकसान होता है, क्योंकि कुछ भी टूटा हुआ नहीं दिखता। एक सफल fallback HTTP 200 और सामान्य response body लौटाता है। आपका सस्ता model एक दिन के लिए बंद हो सकता है, हर call चुपचाप महंगे model द्वारा पूरी की जा सकती है, और इसका पहला प्रमाण invoice होता है।

इसका प्रमाण response headers में मौजूद होता है। उन्हें देखें:

curl -s -D - -o /dev/null http://127.0.0.1:4000/v1/chat/completions \
  -H "Authorization: Bearer sk-<the virtual key>" \
  -H 'Content-Type: application/json' \
  -d '{"model":"bulk","messages":[{"role":"user","content":"ping"}]}' \
  | grep -i '^x-litellm'
  • x-litellm-model-group वह है जो client ने मांगा था। x-litellm-model-id वह deployment है जिसने उत्तर दिया। जब ये दोनों अलग हों, तो fallback हुआ है।
  • x-litellm-attempted-fallbacks और x-litellm-attempted-retries उनकी गिनती करते हैं। एक स्वस्थ call पर दोनों 0 होते हैं।
  • x-litellm-response-cost उस एक call की अमेरिकी डॉलर में लागत है।
  • x-litellm-call-id वह identifier है जिसका उपयोग आप अपने logs में उसी call को खोजने के लिए करते हैं।

हर request पर x-litellm-attempted-fallbacks को record करें और जब यह 0 न रहे तो alert जारी करें। वह एक संख्या ही एक ऐसी routing policy जो काम कर रही है, और एक ऐसी routing policy जो चुपचाप "हमेशा महंगे model का उपयोग करें" बन गई है, के बीच का अंतर है।

इसका पूर्ण संस्करण tracing है, और यह अपने स्वयं के सेटअप का हकदार है: agent calls की tracing के लिए self-hosted Langfuse। LiteLLM callback के साथ आता है, इसलिए इसे जोड़ना केवल दो लाइन और credentials का काम है।

litellm_settings:
  success_callback: ["langfuse"]
  failure_callback: ["langfuse"]
LANGFUSE_PUBLIC_KEY=pk-lf-...
LANGFUSE_SECRET_KEY=sk-lf-...
LANGFUSE_HOST=https://langfuse.example.com

failure_callback और success_callback दोनों सेट करें। यदि आप इसे छोड़ देते हैं, तो आप केवल वही traces रखेंगे जहाँ कुछ भी गलत नहीं हुआ। इन सबसे अलग, LiteLLM हर request के लिए Postgres में एक spend row लिखता है और /ui पर मौजूद Admin UI उस table को पढ़ता है। यह traffic के साथ बढ़ता है, इसलिए इसे छोटी disk पर monitor करें।

गेटवे को रिवर्स प्रॉक्सी के पीछे रखें

बॉक्स के बाहर से किसी भी चीज़ को port 4000 तक नहीं पहुँचना चाहिए। nginx या Caddy में TLS को terminate करें और इसे loopback address पर forward करें।

location / {
    proxy_pass http://127.0.0.1:4000;
    proxy_http_version 1.1;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_buffering off;
    proxy_read_timeout 600s;
}

इनमें से दो पंक्तियाँ ऐसी हैं जिन्हें लोग अक्सर छोड़ देते हैं। proxy_buffering off महत्वपूर्ण है क्योंकि streaming completion सर्वर-sent events की एक श्रृंखला होती है, और buffering चालू रहने पर nginx response समाप्त होने तक chunks को रोक कर रखता है, जिससे client को कुछ भी दिखाई नहीं देता और अंत में सब कुछ एक साथ प्राप्त होता है। proxy_read_timeout 600s महत्वपूर्ण है क्योंकि एक लंबी generation nginx के 60 सेकंड के डिफ़ॉल्ट समय से अधिक चलती है, और ऐसा होने पर client को 504 error मिलता है जबकि error log में upstream timed out (110: Connection timed out) while reading response header from upstream दर्ज हो जाता है।

certificate के लिए, nginx पर Let's Encrypt के साथ Certbot सबसे छोटा रास्ता है। यदि बॉक्स पहले से ही कई containers को serve कर रहा है, तो कई Compose apps के सामने Traefik एक ही स्थान पर routing और certificates को manage करता है।

गेटवे अब विफलता का एक एकल बिंदु (single point of failure) है

आपने जो बनाया है उसके बारे में ईमानदार रहें। आपके स्वामित्व वाले सभी एप्लिकेशन अब एक VPS पर एक कंटेनर पर निर्भर हैं। जब यह डाउन होता है, तो कोई भी एप्लिकेशन किसी मॉडल को कॉल नहीं कर सकता, उन प्रदाताओं (providers) को भी नहीं जो पूरी तरह से ठीक काम कर रहे हैं। इसके परिणामस्वरूप चार बातें सामने आती हैं।

  • एक गलत कॉन्फ़िगरेशन सब कुछ एक साथ बंद कर देता है। restart: unless-stopped क्रैश होने पर रीस्टार्ट होता है, और यह उस कंटेनर को बार-बार रीस्टार्ट करता है जो config.yaml को पार्स नहीं कर सकता। हर कॉन्फ़िगरेशन बदलाव के बाद docker compose logs litellm पढ़ें, और कॉन्फ़िगरेशन में बदलाव तब करें जब आपके पास उन्हें देखने का समय हो।
  • Postgres रिक्वेस्ट पाथ में स्थित है। वर्चुअल की लुकअप और खर्च रिकॉर्डिंग दोनों इसका उपयोग करते हैं। /health/readiness का 503 एरर देना आपकी चेतावनी है कि गेटवे चल तो रहा है लेकिन इनमें से कोई भी काम नहीं कर पा रहा है।
  • एक को बड़ा बनाने के बजाय इंस्टेंस जोड़कर स्केल करें। प्रोजेक्ट का अपना मार्गदर्शन प्रति इंस्टेंस एक वर्कर (--num_workers 1) का है, जिसमें कई इंस्टेंस एक डेटाबेस साझा करते हैं। लोड बैलेंसर के पीछे दो छोटे गेटवे होने से एकल कंटेनर वाली समस्या खत्म हो जाती है। वे डेटाबेस की समस्या को खत्म नहीं करते हैं।
  • जिसे आप दोबारा जेनरेट नहीं कर सकते उसका बैकअप लें। यह config.yaml और .env है, साथ ही डेटाबेस का एक pg_dump भी है। LITELLM_SALT_KEY खो जाने से उस डंप के अंदर मौजूद एन्क्रिप्टेड प्रदाता क्रेडेंशियल्स बेकार हो जाते हैं, इसलिए env फ़ाइल और डंप एक ही बैकअप जॉब का हिस्सा होने चाहिए: off-box स्टोरेज पर restic बैकअप

अपग्रेड करने का अर्थ है इमेज टैग को एडिट करना और docker compose up -d चलाना। LiteLLM डिफ़ॉल्ट रूप से स्टार्टअप पर prisma migrate deploy चलाता है, इसलिए नया कंटेनर अपने पहले बूट पर डेटाबेस स्कीमा को माइग्रेट कर देता है। टैग बदलने से पहले डंप लें, क्योंकि पुरानी इमेज को वापस लाने से वह माइग्रेशन पूर्ववत (undo) नहीं होता जो पहले ही चल चुका है।

FAQ

क्या LiteLLM हर कॉल में ध्यान देने योग्य latency जोड़ता है?

अगस्त 2026 में इसके README के अनुसार, यह प्रोजेक्ट 1000 requests प्रति सेकंड पर 95th percentile पर 8 ms latency का दावा करता है। इसे एक vendor का आंकड़ा मानें। जो संख्या वास्तव में आपकी latency को प्रभावित करती है, वह आपके applications और gateway के बीच की network दूरी है, क्योंकि आपने हर कॉल में एक अतिरिक्त round trip जोड़ दिया है। Gateway को उसी region में चलाएँ जहाँ उसे कॉल करने वाले applications हैं, और फिर वास्तविक response पर x-litellm-overhead-duration-ms header के साथ अपने overhead को मापें।

nginx को सामने रखने के बाद streaming काम करना क्यों बंद कर देती है?

क्योंकि nginx डिफ़ॉल्ट रूप से upstream responses को buffer करता है और streaming completion वास्तव में server-sent events की एक श्रृंखला होती है। जब proxy_buffering चालू होता है, तो nginx chunks को इकट्ठा करता है और उन्हें केवल तभी जारी करता है जब response पूरा हो जाता है, इसलिए client चुपचाप प्रतीक्षा करता है और फिर एक साथ पूरा उत्तर प्राप्त करता है। Location block में proxy_buffering off; सेट करें। उसी block में proxy_read_timeout को बढ़ाएँ, क्योंकि अन्यथा एक लंबी generation प्रक्रिया nginx के 60 सेकंड के डिफ़ॉल्ट समय से अधिक हो जाती है और client को 504 error मिलती है।

जब virtual key का बजट समाप्त हो जाता है तो क्या होता है?

कॉल HTTP 401 error के साथ विफल हो जाती है और response body ExceededBudget: Current spend for token: 7.2e-05; Max Budget for Token: 2e-07 के रूप में होती है। 401 यहाँ एक भ्रम पैदा करता है: एक client library इसे authentication विफलता के रूप में रिपोर्ट करती है, इसलिए लोग संदेश पढ़ने के बजाय यह जाँचने लगते हैं कि key वैध है या नहीं। Status code के साथ response body को log करें। Master key के विरुद्ध /key/info?key=sk-... के साथ key की वास्तविक स्थिति की पुष्टि करें, और यदि बजट बहुत कम सेट किया गया था तो /key/update के साथ सीमा बढ़ाएँ।

क्या gateway hosted models के साथ-साथ local model को भी route कर सकता है?

हाँ, और यह model_list में एक और entry है। api_base के साथ ollama_chat/ prefix का उपयोग करें, उदाहरण के लिए api_base: http://ollama:11434 के साथ model: ollama_chat/llama3.1। Container के अंदर से, localhost का अर्थ वही container होता है, इसलिए Docker network पर Compose service name या host के address का उपयोग करें, कभी भी 127.0.0.1 का नहीं। Local model को खड़ा करना एक अलग कार्य है: देखें VPS पर Ollama के साथ LLM को self-host करना