# Load Balancing Across Azure OpenAI Instances
**Last updated:** 2026-02
**Status:** GA
**Category:** API Management & AI Gateway
---
## Introduksjon
Lastbalansering på tvers av flere Azure OpenAI-instanser er en kritisk kapabilitet for enterprise AI-arkitekturer. Azure OpenAI har begrensninger på tokens per minutt (TPM) og requests per minutt (RPM) per deployment, og én enkelt instans vil sjelden dekke behovene til en hel organisasjon. Ved å distribuere trafikk over flere instanser -- gjerne i ulike regioner -- kan organisasjoner øke total kapasitet, forbedre tilgjengelighet og optimalisere kostnader.
Azure API Management (APIM) tilbyr innebygd backend pool-funksjonalitet som gjør dette uten egenutviklet kode. Backend pools støtter round-robin, weighted, priority-basert og session-aware lastbalansering, kombinert med circuit breaker for automatisk failover. For norsk offentlig sektor er dette spesielt relevant: flere etater kan dele infrastruktur, mens Provisioned Throughput Units (PTU) prioriteres for å maksimere investert kapasitet.
Det er viktig å forstå at APIM-lastbalansering er approksimasjon: ulike gateway-instanser synkroniserer ikke state seg imellom. Dette betyr at vektede fordelinger er omtrentlige, ikke eksakte. For de fleste AI-brukstilfeller er dette akseptabelt, da Azure OpenAI selv håndterer throttling med 429-responser og Retry-After headers.
---
## Backend Pool-konsepter
### Hva er en backend pool?
En backend pool i APIM er en samling av backend-tjenester som gatewayen behandler som én logisk enhet for lastbalansering. For Azure OpenAI betyr dette at flere OpenAI-instanser (potensielt i ulike regioner, med ulike deployment-typer) grupperes bak ett endepunkt.
| Egenskap | Verdi |
|----------|-------|
| Maks backends per pool | 30 |
| Synkronisering mellom gateway-instanser | Nei (approksimasjon) |
| Session awareness | Ja (cookie-basert) |
| Health checking | Via circuit breaker |
| Deployment-modell | Bicep, ARM, REST API, Portal |
### Backend-registrering
Hver backend i poolen registreres med URL, autentisering og valgfrie metadata:
```xml
```
---
## Load Balancing-strategier
### Strategi 1: Round-Robin
Fordeler requests jevnt mellom alle backends i poolen.
```
Request 1 → Backend A (Norway East)
Request 2 → Backend B (Sweden Central)
Request 3 → Backend C (West Europe)
Request 4 → Backend A (Norway East) ← syklusen gjentas
```
**Bruk når:**
- Alle instanser har lik kapasitet (samme TPM-allokering)
- Ingen preferanse for spesifikke regioner
- Enkel konfigurasjon er prioritert
**Bicep:**
```bicep
resource backendPool 'Microsoft.ApiManagement/service/backends@2023-09-01-preview' = {
parent: apim
name: 'openai-pool'
properties: {
type: 'Pool'
pool: {
services: [
{
id: '/backends/openai-norwayeast'
}
{
id: '/backends/openai-swedencentral'
}
{
id: '/backends/openai-westeurope'
}
]
}
}
}
```
### Strategi 2: Weighted (vektet)
Fordeler requests basert på tildelte vekter. Nyttig når backends har ulik kapasitet.
```
Vekter: A=3, B=2, C=1 (totalt 6)
→ A mottar ~50% av trafikk
→ B mottar ~33% av trafikk
→ C mottar ~17% av trafikk
```
**Bruk når:**
- Backends har ulik TPM-allokering
- Blue-green deployment med gradvis trafikkskift
- Ulike pricing-modeller (PTU vs. pay-as-you-go)
**Bicep:**
```bicep
resource backendPool 'Microsoft.ApiManagement/service/backends@2023-09-01-preview' = {
parent: apim
name: 'openai-pool-weighted'
properties: {
type: 'Pool'
pool: {
services: [
{
id: '/backends/openai-norwayeast-ptu'
weight: 5
priority: 1
}
{
id: '/backends/openai-swedencentral-paygo'
weight: 3
priority: 1
}
{
id: '/backends/openai-westeurope-paygo'
weight: 2
priority: 1
}
]
}
}
}
```
### Strategi 3: Priority-Based (anbefalt for AI)
Organiserer backends i prioritetsgrupper. Lavere prioritetsnummer = høyere prioritet. Backends i lavere prioritetsgrupper brukes kun når alle backends i høyere grupper er utilgjengelige (circuit breaker utløst).
```
Priority 1: PTU-instanser (fast pris, utnytt først)
├── openai-norwayeast-ptu (weight: 3)
└── openai-swedencentral-ptu (weight: 2)
Priority 2: Pay-as-you-go fallback
├── openai-westeurope-paygo (weight: 1)
└── openai-eastus-paygo (weight: 1)
```
**Typisk scenario for norsk offentlig sektor:**
| Prioritet | Deployment-type | Region | Begrunnelse |
|-----------|-----------------|--------|-------------|
| 1 | PTU | Norway East | Datasuverenitet + fast pris, bruk først |
| 1 | PTU | Sweden Central | Nær-region redundans |
| 2 | Pay-as-you-go | West Europe | Spillover ved høy last |
| 3 | Pay-as-you-go | East US | Nødfallback ved regional utfall |
**Bicep:**
```bicep
resource backendPool 'Microsoft.ApiManagement/service/backends@2023-09-01-preview' = {
parent: apim
name: 'openai-pool-priority'
properties: {
type: 'Pool'
pool: {
services: [
{
id: '/backends/openai-norwayeast-ptu'
weight: 3
priority: 1
}
{
id: '/backends/openai-swedencentral-ptu'
weight: 2
priority: 1
}
{
id: '/backends/openai-westeurope-paygo'
weight: 1
priority: 2
}
{
id: '/backends/openai-eastus-paygo'
weight: 1
priority: 3
}
]
}
}
}
```
### Strategi 4: Session-Aware
Sikrer at alle requests fra samme bruker-sesjon rutes til samme backend. Kritisk for Azure OpenAI Assistants API der thread state er bundet til en spesifikk instans.
```
Sesjon 1: Bruker A ──cookie──► Backend A (alle requests i sesjonen)
Sesjon 2: Bruker B ──cookie──► Backend B (alle requests i sesjonen)
Sesjon 3: Bruker C ──cookie──► Backend A (ny sesjon, tilfeldig valgt)
```
**Bruk når:**
- Assistants API (thread state)
- Chat-applikasjoner med stateful backends
- Når backend cacher bruker-kontekst
**Bicep:**
```bicep
resource backendPool 'Microsoft.ApiManagement/service/backends@2023-09-01-preview' = {
parent: apim
name: 'openai-pool-session'
properties: {
type: 'Pool'
pool: {
services: [
{
id: '/backends/openai-norwayeast'
weight: 1
priority: 1
}
{
id: '/backends/openai-swedencentral'
weight: 1
priority: 1
}
]
sessionAffinity: {
type: 'Cookie'
cookieName: 'apim-session-id'
}
}
}
}
```
**Cookie-håndtering for klienter:**
Klienter MÅ lagre `Set-Cookie`-headeren fra APIM og sende den tilbake i påfølgende requests for å opprettholde sesjonsaffinitet.
---
## Individual Backend-konfigurasjon
### Registrere en Azure OpenAI backend
```bicep
resource openaiBackend 'Microsoft.ApiManagement/service/backends@2023-09-01-preview' = {
parent: apim
name: 'openai-norwayeast-ptu'
properties: {
url: 'https://aoai-norwayeast.openai.azure.com/openai'
protocol: 'http'
description: 'Azure OpenAI PTU deployment i Norway East'
circuitBreaker: {
rules: [
{
name: 'openai-circuit-breaker'
failureCondition: {
count: 3
interval: 'PT1M'
statusCodeRanges: [
{ min: 429, max: 429 }
{ min: 500, max: 599 }
]
}
tripDuration: 'PT10S'
acceptRetryAfter: true
}
]
}
}
}
```
### Autentisering via Managed Identity
```xml
```
**RBAC-konfigurasjon:**
```bicep
// Grant Cognitive Services User role to APIM managed identity
resource roleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
scope: openaiResource
name: guid(apim.id, openaiResource.id, 'cognitive-services-user')
properties: {
roleDefinitionId: subscriptionResourceId(
'Microsoft.Authorization/roleDefinitions',
'a97b65f3-24c7-4388-baec-2e87135dc908' // Cognitive Services User
)
principalId: apim.identity.principalId
principalType: 'ServicePrincipal'
}
}
```
---
## Deployment Slot Selection
### Routing til ulike modell-deployments
Når backends har ulike deployment-navn (f.eks. `gpt-4o` i en region, `gpt4-turbo` i en annen), kan APIM-policies transformere URL-en:
```xml
```
### Modell-versjonshåndtering
```xml
2024-10-21
```
---
## Regional Distribution
### Topologi 1: Single-Region APIM, Multi-Region Backends
```
APIM (Norway East)
│
┌────────┼────────┐
▼ ▼ ▼
OpenAI OpenAI OpenAI
(Norway East) (Sweden C.) (West EU)
Priority 1 Priority 1 Priority 2
```
**Fordeler:** Enkel arkitektur, ett kontrollpunkt
**Ulemper:** APIM er single point of failure, cross-region latens
### Topologi 2: Multi-Region APIM, Regional Backends
```
Client → DNS (latency-based routing)
│
┌────────┴────────┐
▼ ▼
APIM Gateway APIM Gateway
(Norway East) (Sweden Central)
│ │
▼ ▼
OpenAI OpenAI
(Norway East) (Sweden Central)
```
**Fordeler:** Ingen regional single point of failure, lav latens
**Ulemper:** Krever APIM Premium, dyrere
**Bicep for multi-region APIM:**
```bicep
resource apim 'Microsoft.ApiManagement/service@2023-09-01-preview' = {
name: 'apim-ai-gateway'
location: 'norwayeast'
sku: {
name: 'Premium'
capacity: 1
}
properties: {
additionalLocations: [
{
location: 'swedencentral'
sku: {
name: 'Premium'
capacity: 1
}
}
]
}
}
```
### Topologi 3: Active-Active med Active-Passive Backends
Kombinerer regional redundans med kostnadsoptimalisering:
```
APIM Gateway (Norway East)
├── Active: OpenAI PTU (Norway East) Priority 1
├── Passive: OpenAI PAYGO (Norway East) Priority 2
└── Cross: OpenAI PAYGO (Sweden C.) Priority 3 (kun ved regional feil)
APIM Gateway (Sweden Central)
├── Active: OpenAI PTU (Sweden C.) Priority 1
├── Passive: OpenAI PAYGO (Sweden C.) Priority 2
└── Cross: OpenAI PAYGO (Norway East) Priority 3
```
**Regional policy routing:**
```xml
```
---
## Throttling og Retry-håndtering
### Smart Load Balancing
Når en backend returnerer 429 (Too Many Requests), skal gatewayen:
1. Lese `Retry-After`-headeren
2. Markere backend som utilgjengelig via circuit breaker
3. Umiddelbart retry til neste tilgjengelige backend i poolen
4. IKKE vente (ingen delay mellom retries til ulike backends)
```xml
```
### PTU + PAYGO Spillover-mønster
Det mest vanlige mønsteret for kostnadsoptimalisering:
```
Normal trafikk:
All trafikk → PTU (Priority 1, fast pris)
Ved throttling (PTU kapasitet brukt opp):
Circuit breaker utløst på PTU
Trafikk → PAYGO (Priority 2, pay-per-token)
Etter PTU recovery:
Circuit breaker reset
Trafikk → PTU (Priority 1, tilbake til fast pris)
```
| Fase | Backend | Kostnad | Latens |
|------|---------|---------|--------|
| Normal | PTU | Fast (forutsigbar) | Lav (garantert) |
| Spillover | PAYGO | Variabel (høyere) | Variabel |
| Recovery | PTU | Fast | Lav |
---
## Komplett Bicep-eksempel
```bicep
@description('Komplett AI Gateway med priority-based load balancing')
param location string = 'norwayeast'
param environment string = 'prod'
// Azure OpenAI instances
resource aoaiNorway 'Microsoft.CognitiveServices/accounts@2024-10-01' existing = {
name: 'aoai-norwayeast-${environment}'
}
resource aoaiSweden 'Microsoft.CognitiveServices/accounts@2024-10-01' existing = {
name: 'aoai-swedencentral-${environment}'
}
// APIM Instance
resource apim 'Microsoft.ApiManagement/service@2023-09-01-preview' = {
name: 'apim-ai-gw-${environment}'
location: location
sku: {
name: 'StandardV2'
capacity: 1
}
identity: {
type: 'SystemAssigned'
}
properties: {
publisherEmail: 'ai-team@example.no'
publisherName: 'AI Gateway'
}
}
// Backend: Norway East PTU
resource backendNorwayPTU 'Microsoft.ApiManagement/service/backends@2023-09-01-preview' = {
parent: apim
name: 'openai-norwayeast-ptu'
properties: {
url: '${aoaiNorway.properties.endpoint}openai'
protocol: 'http'
circuitBreaker: {
rules: [
{
name: 'throttle-protection'
failureCondition: {
count: 3
interval: 'PT1M'
statusCodeRanges: [
{ min: 429, max: 429 }
{ min: 500, max: 599 }
]
}
tripDuration: 'PT10S'
acceptRetryAfter: true
}
]
}
}
}
// Backend: Sweden Central PAYGO
resource backendSwedenPAYGO 'Microsoft.ApiManagement/service/backends@2023-09-01-preview' = {
parent: apim
name: 'openai-swedencentral-paygo'
properties: {
url: '${aoaiSweden.properties.endpoint}openai'
protocol: 'http'
circuitBreaker: {
rules: [
{
name: 'throttle-protection'
failureCondition: {
count: 3
interval: 'PT1M'
statusCodeRanges: [
{ min: 429, max: 429 }
{ min: 500, max: 599 }
]
}
tripDuration: 'PT10S'
acceptRetryAfter: true
}
]
}
}
}
// Backend Pool with priority-based routing
resource backendPool 'Microsoft.ApiManagement/service/backends@2023-09-01-preview' = {
parent: apim
name: 'openai-pool'
properties: {
type: 'Pool'
pool: {
services: [
{
id: '/backends/${backendNorwayPTU.name}'
weight: 3
priority: 1
}
{
id: '/backends/${backendSwedenPAYGO.name}'
weight: 1
priority: 2
}
]
}
}
}
```
---
## Overvåking og feilsøking
### Identifisere hvilken backend som serverte request
```xml
@(context.Backend?.Id ?? "unknown")
@(context.Backend?.Type ?? "unknown")
```
### KQL for load balancing-distribusjon
```kusto
ApiManagementGatewayLogs
| where OperationId == "ChatCompletions_Create"
| extend backendUrl = tostring(BackendUrl)
| summarize RequestCount = count() by backendUrl, bin(TimeGenerated, 1h)
| render columnchart
```
---
## For Cosmo
- Priority-based load balancing med PTU som Priority 1 og PAYGO som Priority 2 er det anbefalte mønsteret for enterprise AI-arkitekturer -- det maksimerer utnyttelsen av forhåndskjøpt kapasitet og faller automatisk tilbake til pay-per-use ved behov.
- Backend pools er approksimerte: ulike gateway-instanser synkroniserer ikke, så vektede fordelinger er omtrentlige. For AI-workloads er dette akseptabelt fordi Azure OpenAI selv håndterer throttling med 429/Retry-After.
- Session awareness er kritisk for Assistants API og chat-applikasjoner med stateful backends -- aktiver dette med cookie-basert sesjonsaffinitet i pool-konfigurasjonen.
- For norsk offentlig sektor med datasuverenitetskrav: prioriter Norway East og Sweden Central, bruk private endpoints, og vurder om cross-region failover til EU-regioner er akseptabelt under gjeldende regelverk.
- Kombiner alltid backend pools med circuit breaker (inkludert `acceptRetryAfter: true`) for intelligent failover ved 429-responser fra Azure OpenAI.