# API Rate Limiting and Resilience Patterns **Last updated:** 2026-06-19 | Verified: MCP 2026-06-19 **Status:** GA **Category:** Copilot Extensibility & Integration --- ## Introduksjon Rate limiting og resilience patterns er kritiske for å bygge robuste Microsoft AI-applikasjoner som håndterer transiente feil, throttling og kapasitetsbegrensninger på en elegant måte. Microsofts AI-plattformer (Azure OpenAI, Copilot Studio, M365 Copilot) implementerer throttling for å beskytte infrastruktur og sikre rettferdig ressursfordeling. Effektiv håndtering av disse begrensningene skiller en prototyp fra en produksjonsklar løsning. Denne referansen dekker: - **Retry patterns** med exponential backoff for transiente feil - **Rate limiting patterns** for å unngå throttling - **Circuit breaker patterns** for varige feil - **Plattformspesifikke kvotegrenser** (Azure OpenAI, Copilot Studio) - **Implementeringsmønstre** med kodeeksempler **Confidence:** Verified (Microsoft Learn MCP, januar 2026) | Re-verified: MCP 2026-06-19 --- ## Kjernekomponenter / Nøkkelegenskaper ### 1. Retry Pattern (Retry etter transiente feil) **Formål:** Håndtere kortvarige feil (nettverkstap, midlertidig utilgjengelighet, timeouts) ved automatisk å prøve operasjonen på nytt etter en passende forsinkelse. **Nøkkelstrategier:** - **Cancel:** Avbryt hvis feilen ikke er transient eller sannsynligvis vil gjenta seg - **Retry immediately:** For sjeldne feil (f.eks. korrupt nettverkspakke) - **Retry after delay:** For vanlige connectivity/busy-feil — vent før retry (anbefalt) **Exponential backoff:** Vent 2s → 4s → 8s → 16s mellom forsøk for å unngå å overbelaste en allerede busy service. **Viktighetsgrad:** - Innebygd retry i mange Microsoft-biblioteker (Entity Framework, Azure SDK) - Logg tidlige feil som informasjon, kun siste forsøk som error - Idempotens-krav: operasjonen må være trygg å kjøre flere ganger **Verified:** [Retry pattern - Azure Architecture Center](https://learn.microsoft.com/en-us/azure/architecture/patterns/retry) ### 2. Rate Limiting Pattern (Kontrollert trafikk) **Formål:** Redusere throttling-feil ved å kontrollere antall requests sendt til en service over tid, innenfor servicens kapasitetsgrenser. **Problem som løses:** En naiv "retry on error"-tilnærming kan sende 3x mer trafikk enn nødvendig (eksempel: 10 000 records, 2 000 RU/s kapasitet = 30 000 forsøk i stedet for 10 000). **Løsning:** 1. **Bruk durable messaging** (Azure Service Bus, Event Hubs, Queue Storage) som buffer 2. **Dequeue i kontrollert tempo** (f.eks. 20 requests hvert 200ms i stedet for 100/sekund) — sender et jevnere dataflyt og forhindrer bottlenecks ved bursts 3. **Distributed lease management** for multiple prosesser (Azure Blob lease eller Zookeeper/Redis/etcd/Consul) 4. **Logisk partisjonering:** Deler kapasiteten i partisjoner (f.eks. 20 partisjoner à 25 req/s for 500 req/s totalt) — prosesser konkurrerer om eksklusive blob-leases per partisjon **Fordeler:** - Redusert trafikk og færre feil - Forutsigbar throughput - Lavere minneforbruk (dequeue kun når kapasitet er tilgjengelig) **Verified:** [Rate Limiting pattern - Azure Architecture Center](https://learn.microsoft.com/en-us/azure/architecture/patterns/rate-limiting-pattern) **Eksempel (Cosmos DB med 20 000 RU/s kapasitet, 10 000 records à 10 RU):** - Naiv retry: 30 000 requests sendt (10K + 8K + 6K + 4K + 2K) med 20 000 feil - Med rate limiting: 10 000 requests, ingen throttling-feil, forutsigbar gjennomstrømningstid ### 3. Circuit Breaker Pattern (Beskyttelse mot varige feil) **Formål:** Forhindre at applikasjonen spammer en service som er nede eller ikke responderer, ved å "åpne kretsen" etter N feilede forsøk. **Tilstander:** - **Closed:** Normal drift, requests går gjennom - **Open:** Etter X feil — blokkerer alle requests - **Half-Open:** Periodisk tillat én prøve-request for å sjekke om service er tilbake **Forskjell fra Retry:** - Retry forventer at feilen løser seg raskt - Circuit Breaker forventer langvarig feil og beskytter mot waste **Kombinasjon:** Bruk Retry pattern med Circuit Breaker for optimal resilience. **Verified:** [Circuit Breaker pattern - Azure Architecture Center](https://learn.microsoft.com/en-us/dotnet/architecture/cloud-native/application-resiliency-patterns#circuit-breaker-pattern) ### 4. HTTP Response Headers for Rate Limiting **Standard headers** (RateLimit-* eller X-RateLimit-*): - `RateLimit-Remaining`: Antall requests igjen i nåværende window - `RateLimit-Reset`: Tidspunkt når grensen resettes - `Retry-After`: Antall sekunder å vente før neste request (ved 429 Too Many Requests) **Status codes:** - **429 Too Many Requests:** Rate limit overskredet - **503 Service Unavailable:** Midlertidig overbelastet (retry etter `Retry-After`) **Best practice:** - Sjekk `RateLimit-Remaining` og throttle *før* du når 0 - Respekter `Retry-After` header ved 429-feil **Verified:** [What is rate limiting? - Microsoft Cloud Dev](https://learn.microsoft.com/en-us/microsoft-cloud/dev/dev-proxy/concepts/what-is-rate-limiting) --- ## Arkitekturmønstre ### Mønster 1: Retry med Exponential Backoff (C#) ```csharp using Microsoft.Azure.WebJobs; [FunctionName("EventHubTrigger")] [ExponentialBackoffRetry(5, "00:00:04", "00:15:00")] public static async Task Run([EventHubTrigger("myHub", Connection = "EventHubConnection")] EventData[] events, ILogger log) { // Function logic her // Retries automatisk 5 ganger med 4s min, 15 min max delay } ``` **Forklaring:** - 5 retry-forsøk - Initial delay: 4 sekunder - Max delay: 15 minutter - Eksponentiell økning mellom forsøk **Use case:** Azure Functions, Event Hubs triggers, Cosmos DB triggers. **Verified:** [Retry policies - Azure Functions](https://learn.microsoft.com/en-us/azure/azure-functions/functions-bindings-error-pages) ### Mønster 2: Custom Retry Logic med Transient Fault Handling (Teams Bot) ```csharp // Definer retry-strategi var exponentialBackoffRetryStrategy = new ExponentialBackoffRetryStrategy( 3, // 3 forsøk TimeSpan.FromSeconds(2), // Min backoff TimeSpan.FromSeconds(20), // Max backoff TimeSpan.FromSeconds(1) // Jitter delta (+/- 20%) ); // Definer retry policy var retryPolicy = new RetryPolicy(new BotSdkTransientExceptionDetectionStrategy(), exponentialBackoffRetryStrategy); // Utfør bot-operasjon med retry await retryPolicy.ExecuteAsync(() => connector.Conversations.ReplyToActivityAsync((Activity)reply)).ConfigureAwait(false); ``` **Transient Exception Detection (429 rate limit):** ```csharp public class BotSdkTransientExceptionDetectionStrategy : ITransientErrorDetectionStrategy { List transientErrorStatusCodes = new List() { 429 }; public bool IsTransient(Exception ex) { if (ex.Message.Contains("429")) return true; HttpResponseMessageWrapper? response = null; if (ex is HttpOperationException httpOperationException) response = httpOperationException.Response; return response != null && transientErrorStatusCodes.Contains((int)response.StatusCode); } } ``` **Forklaring:** - Sjekker om feil er HTTP 429 (rate limit) - Retry kun for transiente feil - Jitter (+/- 20%) sprer load fra multiple klienter **Use case:** Teams bots, Power Virtual Agents, Copilot Studio bots. **Verified:** [Optimize bot with rate limiting in Teams](https://learn.microsoft.com/en-us/microsoftteams/platform/bots/how-to/rate-limit) ### Mønster 3: Rate Limiting med Queue + Lease-basert Kapasitetsstyring ```text [API] → [Queue A / Queue B] → [Job Processor] → [Rate-limited Service] ↓ [Blob Lease Partitions] ``` **Workflow:** 1. API enqueuer records til durable queue (Azure Service Bus/Event Hubs) 2. Job Processor forsøker å lease blob-partitions (Azure Blob Storage) 3. For hver leaset partition → X requests/sekund kapasitet 4. Processor dequeuer kun det som kan prosesseres innenfor kapasitet 5. Lease expires → processor må re-lease eller redusere throughput **Eksempel:** - Service tillater 500 req/s - Oppretter 20 partitions × 25 req/s - Process A leaser 4 partitions → 100 req/s - Process B leaser 2 partitions → 50 req/s **Fordeler:** - Multiple unkoordinerte prosesser kan dele kapasitet - Redusert minnebruk (dequeue kun ved kapasitet) - Færre throttling-feil **Verified:** [Rate Limiting pattern - Azure Architecture Center](https://learn.microsoft.com/en-us/azure/architecture/patterns/rate-limiting-pattern) ### Mønster 4: Batch Job Queueing med Exponential Backoff (Azure OpenAI) ```python import time from openai import BadRequestError max_retries = 10 retries = 0 initial_delay = 5 delay = initial_delay while True: try: batch_response = client.batches.create( input_file_id=file_id, endpoint="/chat/completions", completion_window="24h", ) batch_id = batch_response.id print(f"✅ Batch created successfully after {retries} retries") break except BadRequestError as e: if 'token_limit_exceeded' in str(e): retries += 1 if retries >= max_retries: raise print(f"⏳ Token limit exceeded. Waiting {delay}s (retry {retries}/{max_retries})") time.sleep(delay) delay *= 2 # Exponential backoff else: raise ``` **Forklaring:** - Håndterer token_limit_exceeded for Azure OpenAI batch jobs - Fail-fast hvis token quota nådd (nytt i 2025) - Exponential backoff: 5s → 10s → 20s → 40s... **Use case:** Store batch-operasjoner (Azure OpenAI, Azure AI Foundry). **Verified:** [Batch deployments - Azure OpenAI](https://learn.microsoft.com/en-us/azure/foundry/openai/how-to/batch) --- ## Beslutningsveiledning ### Når bruke hvilken pattern? | Pattern | Use Case | Eksempel | |---------|----------|----------| | **Retry (immediate)** | Sjeldne, transiente feil | Korrupt nettverkspakke | | **Retry (exponential backoff)** | Vanlige transiente feil (connectivity, busy) | Azure OpenAI 429, Cosmos DB throttling | | **Rate Limiting** | Forutsigbar throttling-grense | Azure OpenAI TPM/RPM quotas, Copilot Studio generative AI limits | | **Circuit Breaker** | Langvarige feil (service nede) | Avhengighet på ekstern API som er nede i minutter | | **Kombiner Retry + Circuit Breaker** | Kritiske applikasjoner | E-handel checkout, helsesektorsystemer | ### Sjekkliste før implementering **1. Er operasjonen idempotent?** - Ja → Trygt å retry - Nei → Implementer idempotency token eller accept duplicate risk **2. Hva er tjenestens throttling-grense?** - Sjekk dokumentasjon for TPM (tokens per minute), RPM (requests per minute) - Eksempler: Azure OpenAI Standard tier = 150K TPM (gpt-4o), Copilot Studio = per Dataverse-environment RPM/RPH (generative AI: 50 RPM / 1 000 RPH med 1-10 message packs, skalerer til 100 RPM / 2 000 RPH; 8 000 RPM for meldinger til en agent) **3. Har applikasjonen multiple workstreams?** - Ja → Bruk shared rate limiter eller separate capacity pools - Nei → Simpel retry policy holder **4. Er feilen transient eller varig?** - Transient (429, 503) → Retry - Varig (500 Internal Server Error gjentatte ganger) → Circuit Breaker --- ## Integrasjon med Microsoft-stakken ### Azure OpenAI Service **Quota limits (per deployment):** - **gpt-4o** (Global Standard, Default tier): 450K TPM, 2.7K RPM - **gpt-4o-mini** (Default tier): 2M TPM, 12K RPM - **o1-preview** (Default tier): 300K TPM, 50 RPM **429 Error Scenarios:** 1. **Rate Limit Exceeded:** TPM/RPM quota overskredet → retry etter `Retry-After` 2. **High System Demand:** System under load → retry etter suggested time **Best practice:** - Sett `max_tokens` til minimum nødvendig (reduserer TPM-forbruk) - Bruk quota management for å øke TPM på high-traffic deployments - Implementer retry logic med exponential backoff - Unngå skarpe workload-endringer (gradvis økning) **Verified:** [Quotas and limits - Azure OpenAI](https://learn.microsoft.com/en-us/azure/foundry/openai/quotas-limits), [Manage quota - Azure OpenAI](https://learn.microsoft.com/en-us/azure/foundry-classic/openai/how-to/quota) ### Copilot Studio **Throttling error codes:** - **GenAISearchandSummarizeRateLimitReached:** Søk/summarize quota nådd (per hour/minute per Dataverse environment) - **GenAIToolPlannerRateLimitReached:** Generative orchestration quota nådd - **OpenAIRateLimitReached:** Max generative answers reached **Løsninger:** 1. **Licensing:** Kjøp flere capacity packs eller bytt til pay-as-you-go 2. **Request rate limit increase:** Kontakt Microsoft Support (kun for pay-as-you-go environments) 3. **Optimize bot:** Bruk express mode, cache retrieved info, bruk direct connector calls i stedet for Power Automate flows **Flow timeout:** Max 100 sekunder før timeout → optimaliser flow logic, flytt non-critical logic etter 'Return value(s)' step. **Verified:** [Resolve throttling errors in agents](https://learn.microsoft.com/en-us/troubleshoot/power-platform/copilot-studio/licensing/throttling-errors-agents), [Error codes - Copilot Studio](https://learn.microsoft.com/en-us/troubleshoot/power-platform/copilot-studio/authoring/error-codes) ### Power Automate (Cloud Flows) **Throttling limits:** - API request limits per 24 timer (avhenger av lisens) - Service protection API limits (Dataverse): 429 med `Retry-After` header **Best practice:** - Følg `Retry-After` interval (lengre delay hvis du sender demanding requests) - Start med lavt request-volum, øk gradvis til du treffer limit - Cache data i variabler i stedet for multiple API calls - Bruk direct connector calls (raskere enn flows fra Copilot Studio) **Verified:** [Retry operations - Dynamics 365](https://learn.microsoft.com/en-us/dynamics365/fin-ops-core/dev-itpro/data-entities/service-protection-retry-operations) ### Microsoft Teams Bots **Rate limits:** - Per bot per thread limit - Per bot global limit **Best practice:** - Detect transient exceptions (429 status code) - Implement exponential backoff med jitter - Unngå overdreven polling **Verified:** [Rate limiting in Teams](https://learn.microsoft.com/en-us/microsoftteams/platform/bots/how-to/rate-limit) --- ## Offentlig sektor (Norge) ### Compliance og logging **GDPR/Personvern:** - Logg kun feilinformasjon (status codes, timestamps), ikke persondata - Tidlige retry-feil = INFO, kun siste forsøk = ERROR (unngå flooding av PII i logs) **Sporbarhet:** - Implementer correlation IDs for å spore requests gjennom retry-forsøk - Aggreger feilstatistikk for å identifisere underliggende problemer (f.eks. persistent throttling = kapasitetsøkning nødvendig) ### Kostnadskontroll **Rate limiting reduserer kostnader:** - Færre unødvendige API-kall (Azure OpenAI, Copilot Studio) - Lavere TPM-forbruk = mindre behov for capacity packs **Example:** - Naiv retry (10K records, 30K requests sent) vs. rate limiting (10K records, 10K requests sent) = 66% redusert API-forbruk ### Tilgjengelighet og SLA **SLA-krav:** - Standard tier (Azure OpenAI) har *ingen latency SLA* og variabel latency ved high load - For kritiske tjenester: vurder **Provisioned Throughput** (Premium tier) for forutsigbar ytelse - Circuit Breaker beskytter mot cascade failures i multi-tjeneste-arkitekturer --- ## Kostnad og lisensiering ### Azure OpenAI **Quota management (gratis):** - Juster TPM/RPM per deployment (ingen ekstra kostnad) **Provisioned Throughput (PTU):** - Fast monthly cost per PTU - Bedre forutsigbarhet og lavere latency - Egnet for prod-workloads med strenge SLA-krav ### Copilot Studio **Capacity packs:** - Kjøp ekstra capacity for å øke quotas (generative AI messages) **Pay-as-you-go:** - Betale per bruk (Copilot credits) - Overage enforcement: "Agent unavailable" når quota nådd (tilbake online innen 5 min etter capacity økning) ### Power Automate **API request limits:** - Inkludert i lisens (varierer per plan: F1, P1, P2, etc.) - Overskridelse = throttling (429 errors) **Verified:** [Copilot Studio quotas](https://learn.microsoft.com/en-us/microsoft-copilot-studio/requirements-quotas), [Power Platform API limits](https://learn.microsoft.com/en-us/power-platform/admin/api-request-limits-allocations) --- ## For arkitekten (Cosmo) ### Når anbefale hvilken løsning? **Prototyping/POC:** - Start med innebygd retry (Azure SDK, Entity Framework) - Acceptable å treffe 429-feil under testing **Production-ready:** - **Implementer alle 3:** Retry + Rate Limiting + Circuit Breaker - Bruk durable messaging (Event Hubs, Service Bus) som buffer - Monitorér `RateLimit-Remaining` headers proaktivt **Kritiske tjenester (helse, finans, offentlig sektor):** - Azure OpenAI Provisioned Throughput (PTU) for SLA - Distributed rate limiting for multi-instance apps - Correlation IDs for full observability - Graceful degradation ved circuit breaker open (vis cached/fallback data) ### Red Flags (når å eskalere til PTU/Premium) 1. **Hyppig 429-feil til tross for retry logic** → Kapasitet for lav, vurder PTU 2. **Variabel latency påvirker brukeropplevelse** → Standard tier har ingen latency SLA 3. **Multiple apps konkurrerer om samme deployment** → Separer deployments eller bruk distributed lease 4. **Batch jobs tar timer lenger enn forventet** → Rate limiting med queue kan halvere tid ### Implementeringsrekkefølge (anbefalt) **Fase 1: Basic Resilience** 1. Implementer retry med exponential backoff (Azure SDK default eller custom policy) 2. Logg 429-feil og analyser frekvens **Fase 2: Proactive Rate Limiting** 3. Bruk `RateLimit-Remaining` header for å throttle *før* 429 4. Implementer queue-basert rate limiting hvis batch-operasjoner **Fase 3: Advanced Resilience** 5. Legg til Circuit Breaker for kritiske avhengigheter 6. Implementer distributed lease for multi-instance apps 7. Monitorér og tune retry/backoff-parametere basert på prod-data ### Spørsmål å stille kunden 1. **Hva er forventet request-volum?** (beregn TPM/RPM-behov) 2. **Hva er SLA-krav for latency?** (Standard vs. PTU) 3. **Har dere multiple applikasjoner som deler samme Azure OpenAI deployment?** (distributed rate limiting) 4. **Er operasjonene batch-orienterte eller real-time?** (queue vs. direct retry) 5. **Hva er akseptabel feilrate?** (0.1% = streng, 1% = moderat) ### Testing og Validering **Load testing:** - Simuler 2x forventet load for å verifisere retry logic - Sjekk at app håndterer 429-feil uten crash - Verifiser at circuit breaker åpner/lukker korrekt **Chaos engineering:** - Simuler service downtime (503 errors) for å teste circuit breaker - Sjekk at app degrader gracefully (fallback, cached data) **Metrics å monitorere:** - 429 error rate (mål: < 1% av requests) - Retry success rate (mål: > 95%) - P95/P99 latency (inkludert retry delays) - Circuit breaker state transitions (Open/Closed/Half-Open) --- ## Kilder og verifisering **Alle kilder verifisert via Microsoft Learn MCP (januar 2026):** 1. [Retry pattern - Azure Architecture Center](https://learn.microsoft.com/en-us/azure/architecture/patterns/retry) 2. [Rate Limiting pattern - Azure Architecture Center](https://learn.microsoft.com/en-us/azure/architecture/patterns/rate-limiting-pattern) 3. [Circuit Breaker pattern - Cloud-Native .NET](https://learn.microsoft.com/en-us/dotnet/architecture/cloud-native/application-resiliency-patterns) 4. [What is rate limiting? - Microsoft Cloud Dev](https://learn.microsoft.com/en-us/microsoft-cloud/dev/dev-proxy/concepts/what-is-rate-limiting) 5. [How to handle API throttling - Microsoft Cloud Dev](https://learn.microsoft.com/en-us/microsoft-cloud/dev/dev-proxy/concepts/how-to-handle-api-throttling) 6. [Azure OpenAI quotas and limits](https://learn.microsoft.com/en-us/azure/foundry/openai/quotas-limits) 7. [Manage Azure OpenAI quota](https://learn.microsoft.com/en-us/azure/foundry-classic/openai/how-to/quota) 8. [Batch deployments - Azure OpenAI](https://learn.microsoft.com/en-us/azure/foundry/openai/how-to/batch) 9. [Resolve throttling errors in Copilot Studio agents](https://learn.microsoft.com/en-us/troubleshoot/power-platform/copilot-studio/licensing/throttling-errors-agents) 10. [Error codes - Copilot Studio](https://learn.microsoft.com/en-us/troubleshoot/power-platform/copilot-studio/authoring/error-codes) 11. [Optimize bot with rate limiting in Teams](https://learn.microsoft.com/en-us/microsoftteams/platform/bots/how-to/rate-limit) 12. [Retry operations - Dynamics 365](https://learn.microsoft.com/en-us/dynamics365/fin-ops-core/dev-itpro/data-entities/service-protection-retry-operations) 13. [Retry policies - Azure Functions](https://learn.microsoft.com/en-us/azure/azure-functions/functions-bindings-error-pages) **MCP Calls:** 6 (3 searches, 2 fetches, 1 code sample search) **Unique URLs:** 13 sources