# Circuit Breaker Patterns for AI Models
**Last updated:** 2026-02
**Status:** GA
**Category:** API Management & AI Gateway
---
## Introduksjon
Circuit breaker-mønsteret er en grunnleggende resiliensmekanisme for AI-applikasjoner som kommuniserer med Azure OpenAI og andre LLM-backends. Når en backend-tjeneste blir overbelastet eller utilgjengelig, forhindrer circuit breaker at applikasjonen fortsetter å sende forespørsler som uansett vil feile. I stedet "bryter kretsen" og returnerer en feilmelding umiddelbart, slik at backend-tjenesten får tid til å gjenopprette seg.
For Azure AI-tjenester er circuit breaker spesielt viktig fordi Azure OpenAI returnerer 429 (Too Many Requests) med en `Retry-After`-header som kan ha verdier opp til 24 timer. Uten circuit breaker vil applikasjoner fortsette å hamre på en throttlet tjeneste, noe som forverrer situasjonen og kaster bort gateway-ressurser. APIMsintegrerte circuit breaker håndterer dette automatisk ved å respektere `Retry-After`-headeren.
I kombinasjon med backend pools og lastbalansering utgjør circuit breaker selve nervesystemet i en intelligent AI-gateway: den detekterer problemer, isolerer feilende backends, ruter trafikk til friske alternativer, og gjenoppretter normal drift automatisk når backend er tilbake.
---
## Circuit Breaker State Machine
### Tre tilstander
Circuit breaker opererer som en tilstandsmaskin med tre tilstander:
```
Feil > threshold
┌─────────┐ ───────────────► ┌──────────┐
│ CLOSED │ │ OPEN │
│ (normal)│ ◄────────────── │ (trip) │
└─────────┘ Alle OK i └──────────┘
│ half-open │
│ │ Trip duration
│ │ utløpt
│ ┌──────────────┐ │
│ │ HALF-OPEN │◄───┘
│ │ (test) │
│ └──────────────┘
│ │
│ Suksess │ Feil
◄──────────────┘───────────► OPEN
```
| Tilstand | Oppførsel | Varighet |
|----------|-----------|----------|
| **Closed** | Normal drift, alle requests videresendes til backend | Ubegrenset (til feilbetingelse oppstår) |
| **Open** | Alle requests avvises umiddelbart med 503 | Trip duration (konfigurerbar, eller fra Retry-After) |
| **Half-Open** | Et begrenset antall test-requests sendes til backend | Til nok suksesser ELLER ny feil |
### APIM-spesifikk oppførsel
APIMcircuit breaker har noen viktige forskjeller fra den generelle circuit breaker-mønsteret:
| Egenskap | APIM Circuit Breaker |
|----------|---------------------|
| **Konfigurasjons-scope** | Per backend (ikke per API eller policy) |
| **Antall regler** | Kun én regel per backend (p.t.) |
| **Synkronisering** | Ingen mellom gateway-instanser (approksimasjon) |
| **Retry-After respekt** | Ja, dynamisk trip duration basert på backend-respons |
| **Støttede tiers** | Alle unntatt Consumption |
| **Respons ved Open** | 503 Service Unavailable |
---
## Konfigurasjon
### Grunnleggende circuit breaker for Azure OpenAI
```bicep
resource openaiBackend 'Microsoft.ApiManagement/service/backends@2023-09-01-preview' = {
parent: apim
name: 'openai-norwayeast'
properties: {
url: 'https://aoai-norwayeast.openai.azure.com/openai'
protocol: 'http'
circuitBreaker: {
rules: [
{
name: 'ai-resilience-rule'
failureCondition: {
count: 3
interval: 'PT1M'
statusCodeRanges: [
{ min: 429, max: 429 }
{ min: 500, max: 599 }
]
}
tripDuration: 'PT10S'
acceptRetryAfter: true
}
]
}
}
}
```
### Attributter forklart
| Attributt | Type | Beskrivelse | Anbefalt verdi for AI |
|-----------|------|-------------|----------------------|
| `failureCondition.count` | int | Antall feil som trigger trip | 3-5 |
| `failureCondition.interval` | duration | Tidsvindu for feil-telling | PT1M (1 minutt) |
| `failureCondition.statusCodeRanges` | array | HTTP-koder som teller som feil | 429 + 500-599 |
| `tripDuration` | duration | Hvor lenge circuit er åpent | PT10S - PT1M |
| `acceptRetryAfter` | bool | Bruk Retry-After header som trip duration | **true** (alltid for AI) |
### Prosentbasert vs. count-basert triggering
APIM støtter to modeller for feil-deteksjon:
**Count-basert (anbefalt for AI):**
```json
{
"failureCondition": {
"count": 3,
"interval": "PT1M",
"statusCodeRanges": [{"min": 429, "max": 429}]
}
}
```
Trigger: 3 eller flere 429-responser innen 1 minutt.
**Prosentbasert:**
```json
{
"failureCondition": {
"percentage": 50,
"interval": "PT1M",
"statusCodeRanges": [{"min": 429, "max": 429}]
}
}
```
Trigger: 50% eller mer av requests feiler innen 1 minutt.
**Anbefaling:** Count-basert er mer forutsigbar for AI-workloads. Prosentbasert kan gi falske positiver ved lav trafikk (2 av 3 requests feiler = 66%).
---
## Failure Threshold Tuning
### Faktorene som påvirker threshold
| Faktor | Lav threshold (1-2) | Høy threshold (5-10) |
|--------|---------------------|---------------------|
| **Reaksjonstid** | Rask, reagerer umiddelbart | Tregere, tolererer noen feil |
| **Falske positiver** | Høy risiko | Lav risiko |
| **Backend-beskyttelse** | Sterk, minimal ekstra belastning | Svakere, flere feil-requests |
| **Anbefalt for** | Kritiske, kapasitetsbegrensede backends | Robuste backends med transiente feil |
### Anbefalte innstillinger per scenario
| Scenario | count | interval | tripDuration | acceptRetryAfter |
|----------|-------|----------|--------------|-----------------|
| **PTU-instans (high priority)** | 3 | PT1M | PT10S | true |
| **PAYGO-instans (fallback)** | 5 | PT2M | PT30S | true |
| **Dev/test** | 2 | PT30S | PT5S | true |
| **Business-critical** | 3 | PT1M | PT10S | true |
| **Batch processing** | 10 | PT5M | PT1M | true |
### Dynamisk trip duration med Retry-After
Når `acceptRetryAfter: true` er satt, overstyrer Azure OpenAIs `Retry-After`-header den konfigurerte `tripDuration`:
```
Scenario: OpenAI returnerer 429 med Retry-After: 30
→ Circuit breaker åpner i 30 sekunder (ikke konfiguert tripDuration)
→ Etter 30 sekunder: half-open → test request
→ Suksess: circuit lukkes
→ Feil: circuit åpner igjen med ny Retry-After
Scenario: OpenAI returnerer 429 med Retry-After: 86400 (1 dag!)
→ Circuit breaker åpner i 24 timer
→ All trafikk rutes til andre backends i poolen
```
> **Viktig advarsel:** Azure OpenAI kan returnere Retry-After verdier opp til 1 dag (86400 sekunder). Med `acceptRetryAfter: true` vil dette bety at backend er utilgjengelig i 24 timer. Sørg for at backend-poolen har nok kapasitet i andre backends til å håndtere dette.
---
## Fallback-policies
### Mønster 1: Backend Pool med automatisk failover
Den enkleste og mest robuste tilnærmingen:
```xml
```
Når circuit breaker utløses på Priority 1-backends, ruter APIM automatisk til Priority 2, osv.
### Mønster 2: Retry med backend-bytte
Eksplisitt retry-logikk som bytter backend ved 429:
```xml
```
**Viktig:** `interval="0"` betyr umiddelbar retry til neste backend, IKKE ventetid. Server-side retries bør aldri ha delay — det holder opp klienten og bruker gateway-ressurser.
### Mønster 3: Graceful Degradation med cache-fallback
```xml
60
@{
return new JObject(
new JProperty("error", new JObject(
new JProperty("code", "service_unavailable"),
new JProperty("message", "AI-tjenesten er midlertidig utilgjengelig. Prøv igjen om 60 sekunder."),
new JProperty("type", "circuit_breaker_open")
))
).ToString();
}
```
### Mønster 4: Fallback til enklere modell
```xml
```
---
## Recovery-mekanismer
### Automatisk recovery
Circuit breaker håndterer recovery automatisk:
```
1. Trip: Circuit åpner (503 til klienter)
2. Wait: tripDuration utløper (eller Retry-After)
3. Half-Open: Test-request sendes til backend
4. Success: Circuit lukkes, normal drift gjenopptas
5. Failure: Circuit åpner igjen, ny tripDuration starter
```
### Recovery-timing
| Kilde | Prioritet | Typisk verdi |
|-------|-----------|--------------|
| `Retry-After` header (når `acceptRetryAfter: true`) | Høyest | 1-86400 sekunder |
| Konfigurert `tripDuration` | Fallback | PT10S - PT1M |
| Default (uten konfigurasjon) | Lavest | PT1M |
### Overvåking av circuit breaker-tilstand
```xml
@{
var backendId = context.Backend?.Id ?? "unknown";
var statusCode = context.Response.StatusCode;
return $"Backend: {backendId}, Status: {statusCode}";
}
```
**KQL for circuit breaker-hendelser:**
```kusto
ApiManagementGatewayLogs
| where ResponseCode == 503
| extend backendId = tostring(parse_json(BackendResponseBody).backendId)
| summarize CircuitBreakerTrips = count() by backendId, bin(TimeGenerated, 5m)
| render timechart
```
---
## Timeout-konfigurasjon
### Forward-request timeout
Kontroller hvor lenge APIM venter på backend-respons:
```xml
```
**Anbefalte timeouts for AI-workloads:**
| Operasjon | Anbefalt timeout | Begrunnelse |
|-----------|------------------|-------------|
| Chat Completion (standard) | 60-120 sek | GPT-4o kan bruke tid på komplekse prompts |
| Chat Completion (streaming) | 120-180 sek | Streaming starter raskt, men kan vare lenge |
| Embeddings | 30-60 sek | Raskere operasjon, typisk < 10 sek |
| Image Generation (DALL-E) | 120-180 sek | Bildegenerering er CPU-intensivt |
| Assistants API | 180-300 sek | Multi-step agent workflows |
| Batch API | 300-600 sek | Store batch-operasjoner |
### Timeout + Circuit Breaker interaksjon
```
Timeout utløper (120 sek)
→ APIM registrerer det som feil
→ Teller mot circuit breaker threshold
→ Etter N timeouts → Circuit breaker trip
→ Backend fjernes fra pool → Trafikk til alternativer
```
> **Best practice:** Sett timeout lavere enn det du tror er nødvendig. Bedre å få rask feil og retry til annen backend enn å vente 120 sekunder på en hengende request.
---
## Avanserte mønstre
### Mønster: Cascading Circuit Breakers
For multi-tier arkitekturer der APIM ruter til mellomtjenester som igjen kaller Azure OpenAI:
```
Client → APIM [CB-1] → Custom Service [CB-2] → Azure OpenAI
```
```bicep
// CB-1: APIM → Custom Service
resource customServiceBackend 'Microsoft.ApiManagement/service/backends@2023-09-01-preview' = {
properties: {
circuitBreaker: {
rules: [{
failureCondition: {
count: 5
interval: 'PT2M'
statusCodeRanges: [
{ min: 502, max: 504 }
]
}
tripDuration: 'PT30S'
}]
}
}
}
```
Applikasjons-nivå CB-2 implementeres med Polly (.NET), resilience4j (Java), eller tilsvarende.
### Mønster: Health Endpoint Monitoring
Kombiner circuit breaker med aktiv health checking:
```xml
@("https://aoai-norwayeast.openai.azure.com/openai/models?api-version=2024-10-21")
GET
```
> **Merk:** Health endpoint monitoring legger til latens og backend-belastning. Bruk det kun for scenarier der circuit breaker alene ikke gir rask nok failover.
---
## Anti-mønstre
| Anti-mønster | Problem | Løsning |
|--------------|---------|---------|
| **Ingen circuit breaker** | Backend overbelastes, cascading failure | Aktiver circuit breaker på alle AI-backends |
| **For lav threshold (count=1)** | Falske positiver ved transiente feil | Bruk count=3-5 for produksjon |
| **For lang tripDuration** | Backend er unødvendig utilgjengelig | Bruk `acceptRetryAfter: true` |
| **Ignorere Retry-After** | Hammer backend som eksplisitt ber om pause | Sett `acceptRetryAfter: true` alltid |
| **Server-side delay** | Retry med sleep/delay holder opp klienter | Bruk `interval="0"` med backend pool failover |
| **Timeout for lang** | Gateway-ressurser brukt opp på hengende requests | Sett realistiske timeouts per operasjonstype |
| **Mangle monitoring** | Ingen innsikt i circuit breaker-oppførsel | Emit metrikk + KQL dashboards |
---
## Komplett resiliens-policy
```xml
60
{"error":{"code":"all_backends_unavailable","message":"Alle AI-backends er midlertidig utilgjengelige"}}
```
---
## For Cosmo
- Circuit breaker er obligatorisk for alle Azure OpenAI backends i produksjon -- uten det risikerer du cascading failures og bortkastet gateway-kapasitet mot throttlede backends.
- Sett ALLTID `acceptRetryAfter: true` for Azure OpenAI backends. Azure OpenAI returnerer presise Retry-After verdier som gir optimal recovery-timing. Uten dette bruker du den statiske tripDuration som kan være for kort eller for lang.
- Anbefalt baseline: `count: 3`, `interval: PT1M`, `tripDuration: PT10S`, `acceptRetryAfter: true`. Juster count opp for PAYGO-backends med mer toleranse.
- Kombiner circuit breaker med backend pools for automatisk failover: når PTU-backend tripper, ruter APIM automatisk til PAYGO-backends uten klient-endringer.
- Advarsler: Azure OpenAI kan returnere Retry-After opp til 86400 sekunder (1 dag). Sørg for at arkitekturen har nok alternative backends til å håndtere langvarige circuit breaks.