आमंत्रित करें और कमाएँ

आमंत्रण पुरस्कार कैसे काम करते हैं

अपना आमंत्रण लिंक साझा करें। मित्र इसके माध्यम से पंजीकरण करके टॉप-अप करता है तो उसके बाद के टॉप-अप पर आपको दिखाया गया पुरस्कार मिलेगा।

API त्रुटि 429 Too Many Requests: सीमाएं, Retry-After और सुरक्षित बैकऑफ

LLM API में HTTP 429 त्रुटियों को हल करने के लिए डेवलपर गाइड: RPM/TPM सीमा विश्लेषण, Retry-After पढ़ना और एक्सपोनेंशियल बैकऑफ कोड लागू करना।

विषय-सूची

API त्रुटि 429 Too Many Requests: सीमाएं, Retry-After और सुरक्षित बैकऑफ

HTTP 429 Too Many Requests त्रुटि तब उत्पन्न होती है जब कोई क्लाइंट API प्रदाता द्वारा निर्धारित अनुरोध आवृत्ति या टोकन सीमा को पार कर जाता है। बिना सोचे-समझे तुरंत पुनः प्रयास (retry) करने से समस्या हल नहीं होती, बल्कि यह ‘रिट्राई स्टॉर्म’ (retry storm) उत्पन्न करके खाते को लंबे समय तक अवरुद्ध कर देती है।

अपने एप्लिकेशन की स्थिरता बहाल करने के लिए, डेवलपर्स को सीमा के प्रकार (RPM, TPM या बैलेंस समाप्ति) की पहचान करनी चाहिए, Retry-After हेडर को सही ढंग से पार्स करना चाहिए और रैंडम जिटर के साथ एक्सपोनेंशियल बैकऑफ (Full Jitter Exponential Backoff) लागू करना चाहिए।

LLM API में HTTP 429 त्रुटि के कारण

आधुनिक भाषा मॉडल API (जैसे OpenAI, Anthropic और संगत गेटवे) में 429 स्थिति कोड मुख्य रूप से तीन कारणों से आता है:

  1. RPM (Requests Per Minute): प्रति मिनट अनुरोधों की संख्या की सीमा। यह तब होता है जब बिना कतार नियंत्रण के समानांतर कई अनुरोध भेजे जाते हैं।
  2. TPM (Tokens Per Minute): एक मिनट की अवधि में कुल इनपुट और आउटपुट टोकन की सीमा। लंबे संदर्भ या बड़े प्रॉम्प्ट भेजने पर यह सीमा जल्दी समाप्त हो जाती है।
  3. कोटा या बैलेंस की समाप्ति: प्रीपेड बैलेंस शून्य होने या निर्धारित खर्च सीमा तक पहुंचने के कारण रुकावट।
HTTP/1.1 429 Too Many Requests
Date: Sun, 23 Aug 2026 03:00:00 GMT
Content-Type: application/json
Retry-After: 6
x-ratelimit-limit-requests: 500
x-ratelimit-remaining-requests: 0
x-ratelimit-reset-requests: 6s
x-ratelimit-limit-tokens: 30000
x-ratelimit-remaining-tokens: 1200
x-ratelimit-reset-tokens: 150ms

{
  "error": {
    "message": "Rate limit reached for model in organization on tokens per minute (TPM). Please try again in 6s.",
    "type": "tokens",
    "param": null,
    "code": "rate_limit_exceeded"
  }
}

जब त्रुटि बैलेंस समाप्ति या 5-घंटे की सदस्यता सीमा के कारण होती है, तो स्वचालित पुनः प्रयास केवल नेटवर्क बैंडविड्थ बर्बाद करते हैं। जटिल लॉग का विश्लेषण किए बिना मूल कारण को तुरंत समझने के लिए, BetterToken एक पारदर्शी डैशबोर्ड प्रदान करता है: यह वास्तविक समय में HTTP स्थिति कोड, इनपुट/आउटपुट/कैश टोकन का सटीक विवरण और पे-ऐज़-यू-गो बैलेंस दिखाता है बिना किसी 5-घंटे के लॉकआउट के।

429 त्रुटि निदान तालिका

लक्षणमुख्य कारणप्रतिक्रिया में क्या जांचेंइंजीनियरिंग समाधान
समानांतर अनुरोधों पर विफलताRPM सीमा पारx-ratelimit-remaining-requests: 0सेमाफोर या कतार के माध्यम से समानांतरता सीमित करें
लंबे प्रॉम्प्ट पर विफलताTPM सीमा पारx-ratelimit-remaining-tokens < प्रॉम्प्ट आकारसंदर्भ को अनुकूलित करें, प्रॉम्प्ट कैशिंग चालू करें या बैच विभाजित करें
100% अनुरोधों पर 429बैलेंस / कोटा समाप्तinsufficient_quota त्रुटि कोडपुनः प्रयास रोकें और बैलेंस रिचार्ज करें या कुंजी जांचें
429 त्रुटियों में भारी वृद्धिरिट्राई स्टॉर्मRetry-After हेडर की अनदेखीप्रतीक्षा समय में रैंडम जिटर (Jitter) जोड़ें

Retry-After हेडर को सही ढंग से पार्स करना

RFC 6585 विनिर्देश के अनुसार, Retry-After हेडर दो मानक प्रारूपों में प्रतीक्षा समय प्रदान करता है:

  • सापेक्ष सेकंड (पूर्णांक या दशमलव, उदा. Retry-After: 12)
  • HTTP-Date टाइमस्टैम्प (उदा. Retry-After: Sun, 23 Aug 2026 03:05:00 GMT)
import datetime
import email.utils
import time

def parse_retry_after(header_value: str | None, default_delay: float = 1.0) -> float:
    if not header_value:
        return default_delay
    header_value = header_value.strip()
    try:
        return max(0.0, float(header_value))
    except ValueError:
        pass

    try:
        parsed_date = email.utils.parsedate_to_datetime(header_value)
        now = datetime.datetime.now(datetime.timezone.utc)
        delay = (parsed_date - now).total_seconds()
        return max(0.0, delay)
    except Exception:
        return default_delay

Full Jitter एक्सपोनेंशियल बैकऑफ लागू करना

यदि Retry-After हेडर अनुपस्थित है, तो जिटर के साथ एक्सपोनेंशियल बैकऑफ का उपयोग करें। प्रयास $i$ के लिए प्रतीक्षा समय की गणना:

$$T_{ ext{wait}} = ext{random}(0, \min(T_{ ext{max}}, T_{ ext{base}} imes 2^i))$$

import asyncio
import json
import random
import httpx

class RateLimitRetryClient:
    def __init__(
        self,
        base_url: str = "https://www.bettertoken.ai/v1",
        api_key: str = "",
        max_retries: int = 4,
        base_delay: float = 1.0,
        max_delay: float = 32.0,
    ):
        self.base_url = base_url
        self.api_key = api_key
        self.max_retries = max_retries
        self.base_delay = base_delay
        self.max_delay = max_delay
        self.client = httpx.AsyncClient(
            base_url=self.base_url,
            headers={"Authorization": f"Bearer {self.api_key}"},
            timeout=60.0,
        )

    async def send_chat_completion(self, payload: dict) -> dict:
        for attempt in range(self.max_retries + 1):
            try:
                response = await self.client.post("/chat/completions", json=payload)
                if response.status_code == 200:
                    return response.json()

                if response.status_code == 429:
                    error_data = response.json().get("error", {})
                    error_code = error_data.get("code")

                    if error_code in ("insufficient_quota", "billing_not_active"):
                        raise RuntimeError(f"बिलिंग त्रुटि: {error_data.get('message')}")

                    if attempt == self.max_retries:
                        raise RuntimeError(f"अधिकतम पुनः प्रयास सीमा समाप्त (429): {response.text}")

                    retry_after = response.headers.get("Retry-After")
                    if retry_after:
                        wait_time = parse_retry_after(retry_after) + random.uniform(0.1, 0.5)
                    else:
                        backoff_cap = min(self.max_delay, self.base_delay * (2 ** attempt))
                        wait_time = random.uniform(0, backoff_cap)

                    await asyncio.sleep(wait_time)
                    continue

                response.raise_for_status()

            except httpx.RequestError as exc:
                if attempt == self.max_retries:
                    raise
                wait_time = min(self.max_delay, self.base_delay * (2 ** attempt))
                await asyncio.sleep(wait_time)

        raise RuntimeError("पुनः प्रयास बजट समाप्त होने के बाद अनुरोध विफल रहा")

सुरक्षा और पुनः प्रयास में सावधानी

रीड-ओनली (GET) अनुरोधों को दोहराना सुरक्षित है। लेकिन LLM अनुमान वाले POST अनुरोधों के लिए:

  1. डुप्लिकेट निष्पादन रोकें: यदि नेटवर्क टाइमआउट होता है, तो दोबारा भेजने से पहले जांचें कि टोकन खर्च हुए या कार्य पूरा हुआ या नहीं।
  2. क्लाइंट रिक्वेस्ट आईडी का उपयोग करें: लॉग में ट्रैक करने के लिए X-Request-ID हेडर शामिल करें।
  3. 401/403 को 429 न समझें: प्रमाणीकरण त्रुटियों को ठीक करने के लिए API कुंजी बदलनी होगी, इंतजार नहीं करना होगा।

रिकवरी सत्यापन

पूरा ट्रैफ़िक फिर से शुरू करने से पहले:

  • न्यूनतम टोकन (max_tokens: 5) के साथ एक परीक्षण अनुरोध भेजें।
  • HTTP 200 प्राप्त होने और x-ratelimit-remaining-requests हेडर की पुष्टि करें।
  • त्रुटि दर की निगरानी करते हुए धीरे-धीरे समानांतर अनुरोध बढ़ाएं।

कठोर मिनट सीमाओं के कारण अचानक होने वाली 429 रुकावटों से बचने और अनुरोधों पर पूर्ण नियंत्रण रखने के लिए, BetterToken API पर स्विच करें, समर्पित API कुंजियां बनाएं और डैशबोर्ड में रीयल-टाइम टोकन उपयोग की निगरानी करें।

संदर्भ और विनिर्देश

अपना LLM वर्कफ़्लो बेहतर बनाना चाहते हैं?

एक API से मॉडल जोड़ें, कुंजियाँ प्रबंधित करें और AI खर्च नियंत्रित करें।

मुफ़्त शुरू करें