# Request Batching and Response Aggregation **Last updated:** 2026-05 **Status:** GA **Category:** Cost Optimization & FinOps for AI --- ## Introduksjon Request batching og response aggregation er kritiske kostnadsoptimaliseringsteknikker for AI-løsninger som gjør det mulig å konsolidere flere API-forespørsler i én enkelt nettverksoperasjon. I stedet for å sende hundrevis eller tusenvis av individuelle API-kall, kan applikasjoner samle disse i batches, redusere nettverkslatens, minimere API throttling-risiko og drastisk kutte kostnader. For Microsoft AI-stakken er batching spesielt relevant i to hovedscenarier: **asynchronous batch processing** (Azure OpenAI Batch API, Azure Machine Learning batch endpoints) og **synchronous request aggregation** (Microsoft Graph JSON batching). Azure OpenAI Batch API tilbyr 50% kostnadsreduksjon sammenlignet med standard global deployments, med separert token quota og 24-timers SLA. Microsoft Graph JSON batching tillater opptil 20 individuelle forespørsler i ett enkelt HTTP-kall, noe som reduserer network roundtrips og forbedrer effektivitet. Denne teknikken er ikke bare en optimaliseringsøvelse — den er ofte nødvendig for å operere innenfor rate limits og quota, spesielt i offentlig sektor der budsjetter er stramme og skalerbarhetsbehov er økende. Riktig implementering krever forståelse av payload structure, response unpacking, error handling for partial failures, og trade-offs mellom latency og throughput. --- ## Kjernekomponenter ### Azure OpenAI Batch API | Komponent | Beskrivelse | |-----------|-------------| | **Input file (JSONL)** | JSON Lines-format med én request per linje, inkludert `custom_id` for korrelasjon | | **Global-Batch deployment** | Dedikert deployment-type med 50% lavere pris enn global standard | | **Enqueued token quota** | Separat quota som ikke forstyrrer online workloads | | **24-hour completion window** | Target SLA for batch processing (jobs kan ta lenger, men utløper ikke) | | **Output file** | JSONL-resultatfil med responses korrelert via `custom_id` | | **Exponential backoff queuing** | Støtte i utvalgte regioner for automatisk retry når token quota er tilgjengelig | ### Microsoft Graph JSON Batching | Komponent | Beskrivelse | |-----------|-------------| | **$batch endpoint** | OData-standard URL path segment (`/v1.0/$batch` eller `/beta/$batch`) | | **requests array** | Samling av individuelle requests med `id`, `method`, `url`, `headers`, `body` | | **responses array** | Samling av individuelle responses med `id`, `status`, `headers`, `body` | | **dependsOn property** | Støtter sekvensielle dependencies mellom requests (optional) | | **Batch size limit** | Maksimalt 20 requests per batch | | **Correlation via id** | Responses returneres ikke i samme rekkefølge som requests | ### Azure Machine Learning Batch Endpoints | Komponent | Beskrivelse | |-----------|-------------| | **Batch endpoint** | Asynkron inferencing-tjeneste med auto-scaling compute clusters | | **Pipeline component deployments** | Reusable MLOps components for komplekse inference workflows | | **Low-priority VMs** | Kostnadsreduksjon med spot capacity (auto-recovery ved deallocations) | | **Scale-to-zero clusters** | Ingen kostnad når idle, auto-provision ved job start | | **Parallelization** | Distribuert processing av store datasett spredt over flere filer | --- ## Arkitekturmønstre ### 1. Client-Side Batching (Synchronous) **Egnet for:** Microsoft Graph, REST APIs med $batch-støtte, real-time aggregation **Mønster:** - Klienten samler flere requests i én batch-payload - Sender POST til `$batch`-endpoint - Mottar aggregert response med individuelle resultater - Parser og distribuerer resultater tilbake til opprinnelige requesters **Eksempel (Microsoft Graph):** ```json POST https://graph.microsoft.com/v1.0/$batch { "requests": [ {"id": "1", "method": "GET", "url": "/me/drive/root"}, {"id": "2", "method": "GET", "url": "/me/planner/tasks"}, {"id": "3", "method": "GET", "url": "/groups/{id}/calendar"} ] } ``` **Response:** ```json { "responses": [ {"id": "1", "status": 200, "body": {...}}, {"id": "2", "status": 200, "body": {...}}, {"id": "3", "status": 403, "body": {"error": {...}}} ] } ``` **Fordeler:** - Reduserer network roundtrips (1 HTTP call vs. N calls) - Lavere latency for små-til-medium batches (< 20 items) - Synkron response — lettere feilhåndtering **Ulemper:** - Begrenset til 20 requests (Microsoft Graph) - Ingen kostnadsreduksjon per request (kun nettverkseffektivitet) - Alle requests må vente på tregeste request før response returneres --- ### 2. Server-Side Asynchronous Batching **Egnet for:** Azure OpenAI, store datasett, ikke-tidsensitive workloads, kostnadsoptimalisering **Mønster:** - Klienten laster opp batch input file (JSONL) til Azure Storage eller OpenAI Files API - Sender batch job request med file ID og completion window - Server prosesserer asynkront med separat quota - Klienten poller job status til completion - Henter output file og parser resultater **Eksempel (Azure OpenAI Batch API):** ```python # Upload input file with open("batch_input.jsonl", "rb") as f: file = client.files.create(file=f, purpose="batch") # Create batch job batch = client.batches.create( input_file_id=file.id, endpoint="/chat/completions", completion_window="24h" ) # Poll for completion while batch.status not in ["completed", "failed", "cancelled"]: time.sleep(60) batch = client.batches.retrieve(batch.id) # Download results output_file_id = batch.output_file_id content = client.files.content(output_file_id) ``` **Fordeler:** - 50% kostnadsreduksjon (Azure OpenAI Batch API) - Separat quota — ingen impact på online workloads - Skalerer til millioner av requests (ingen 20-request limit) - Auto-parallelization på server-side **Ulemper:** - Høyere latency (24-hour SLA, ofte raskere men ingen garantier) - Asynkron — krever polling eller webhook-notifikasjoner - Mer kompleks feilhåndtering (partial failures i output file) --- ### 3. Queue-Based Batching with Aggregation **Egnet for:** Event-driven arkitekturer, ujevn last, backpressure management **Mønster:** - Applikasjonen sender meldinger til Azure Service Bus eller Storage Queue - Azure Function eller Logic App aggregerer meldinger i batches (time window eller count threshold) - Sender konsolidert batch til AI-tjeneste (Azure OpenAI, Cognitive Services) - Distribuerer resultater tilbake via queue eller Event Grid **Eksempel (Azure Functions + Service Bus):** ```python @app.service_bus_queue_trigger( arg_name="msgs", queue_name="ai-requests", connection="ServiceBusConnection", cardinality="many" ) def batch_processor(msgs: List[func.ServiceBusMessage]): batch_input = [json.loads(msg.get_body().decode()) for msg in msgs] # Send to Azure OpenAI Batch API or process directly responses = process_batch(batch_input) # Write results to output queue/storage for msg, response in zip(msgs, responses): write_result(msg.correlation_id, response) ``` **Fordeler:** - Decoupling av producers og consumers - Auto-scaling basert på queue depth - Resilience ved failures (retry logic, dead-letter queues) - Kan kombineres med både sync og async batching **Ulemper:** - Økt kompleksitet (flere komponenter) - Potensiell latency overhead (buffering time) - Ekstra kostnader for queue/messaging services --- ## Beslutningsveiledning ### Når Bruke Hvilken Batching-Strategi? | Kriterium | Client-Side Sync | Server-Side Async | Queue-Based | |-----------|------------------|-------------------|-------------| | **Request volume** | < 20 per batch | > 100 per batch | Varierende/ujevn | | **Latency-krav** | < 5 sekunder | > 1 minutt OK | Moderat (10-60 sek) | | **Kostnadsoptimalisering** | Lav (kun nettverk) | Høy (50% rabatt) | Moderat (queue costs) | | **Error handling** | Synkron, enkel | Asynkron, kompleks | Resilient (retry/DLQ) | | **Skalerbarhet** | Lav-moderat | Meget høy | Høy | | **Brukstilfeller** | Multi-resource GET, form submissions | Bulk document summarization, content generation | Event-driven AI, webhook processing | ### Vanlige Feil (Anti-Patterns) | Feil | Konsekvens | Anbefaling | |------|------------|------------| | **Batching for få items** | Overhead større enn fordel | Batch kun når N > 5-10 requests | | **Ignorere partial failures** | Tapte data, inkonsistent state | Alltid parse individual response status codes | | **Blokkerende polling** | Resource waste, poor UX | Bruk webhooks, Event Grid eller async/await patterns | | **Hardkoding batch size** | Sub-optimal performance | Dynamisk sizing basert på payload size og latency targets | | **Ikke bruke `custom_id`** | Kan ikke korrelere responses | Alltid inkluder unik ID per request | | **Mixing sync og async i samme flow** | Race conditions, kompleksitet | Velg én strategi per use case | ### Røde Flagg - **Rate limiting errors (429) ved ikke-batched calls** → Bytt til batching umiddelbart - **> 50% av budget brukt på API costs** → Evaluer Azure OpenAI Batch API - **Lange nettverk latencies (> 500ms roundtrip)** → Client-side batching kan hjelpe - **Timeout errors på store datasett** → Server-side async batching påkrevd - **Ujevn last med spikes** → Queue-based batching med buffering --- ## Integrasjon med Microsoft-Stakken ### Azure OpenAI Batch API **Setup:** 1. Opprett Global-Batch deployment i Azure OpenAI resource 2. Prepare JSONL input file med standard chat completion format + `custom_id` 3. Upload file via Files API eller Azure Blob Storage 4. Create batch job med `client.batches.create()` 5. Poll job status eller subscribe til Event Grid events 6. Download output file og parse responses **Regioner med Exponential Backoff Support:** - australiaeast, eastus, eastus2, germanywestcentral, italynorth, northcentralus, polandcentral, swedencentral, switzerlandnorth, westus **Pris:** 50% rabatt vs. global standard (verifiser på Azure pricing page) ### Microsoft Graph JSON Batching **Setup:** 1. Konstruer JSON-payload med `requests` array 2. POST til `https://graph.microsoft.com/v1.0/$batch` 3. Parse `responses` array og korreler via `id` property 4. Håndter individuelle status codes (200, 403, 429, etc.) **Limits:** - Max 20 requests per batch - Max URL length per request (~2000 characters) - Throttling gjelder fortsatt per individual request **Dependency Sequencing:** ```json { "requests": [ {"id": "1", "method": "POST", "url": "/groups", "body": {...}}, {"id": "2", "dependsOn": ["1"], "method": "POST", "url": "/groups/$1/members/$ref", "body": {...}} ] } ``` ### Azure Machine Learning Batch Endpoints **Setup:** 1. Opprett batch endpoint med Azure ML CLI/SDK 2. Deploy model eller pipeline component 3. Configure compute cluster (standard eller low-priority VMs) 4. Invoke endpoint med data asset eller storage URL 5. Monitor job progress via Azure ML studio eller SDK 6. Retrieve results fra output storage location **Cost Optimization:** - Bruk low-priority VMs for 60-80% kostnadsreduksjon - Scale-to-zero clusters (kun betaler når jobs kjører) - Override instance count og mini-batch size per job ### Azure Service Bus + Azure Functions **Setup:** 1. Opprett Service Bus queue med session support (optional) 2. Deploy Azure Function med Service Bus trigger (`cardinality="many"`) 3. Configure batch size og max wait time 4. Process aggregated messages i function handler 5. Write results til output binding (Storage, Event Grid, etc.) **Best Practices:** - Bruk `maxMessageCount` (16-32) for optimal batching - Set `maxWaitTime` (5-10 sek) for latency control - Enable dead-letter queue for failed messages ### Azure API Management (APIM) **Use Case:** Aggregere og batch requests til backend AI services **Setup:** 1. Configure inbound policy med `set-body` for batch payload construction 2. Bruk `send-request` policy for parallel calls (sync batching simulation) 3. Aggregate responses i outbound policy 4. Cache results for repeat queries --- ## Offentlig Sektor (Norge) ### Databehandling og GDPR | Vurdering | Implikasjon for Batching | |-----------|--------------------------| | **Data i transit** | Batch files inneholder ofte persondata → kryptering obligatorisk (HTTPS, Azure Storage encryption) | | **Data at rest** | Azure OpenAI batch input/output files lagres midlertidig → slett etter processing (`output_expires_after`) | | **Logging og audit** | Batch job IDs og correlation IDs må logges for sporbarhet (krav i offentlig sektor) | | **Data residency** | Azure OpenAI: "Data stored at rest remains in designated Azure geography, while data may be processed for inferencing in any Azure OpenAI location" → vurder Schrems II | | **Databehandleravtale** | Batch processing betraktes som databehandling → DPA med Microsoft påkrevd | ### Schrems II og EU Data Transfers **Risiko:** Azure OpenAI Batch API kan prosessere data i andre regioner enn der ressursen er hostet. **Mitigering:** 1. Bruk European regions (swedencentral, germanywestcentral, switzerlandnorth) 2. Evaluer TIA (Transfer Impact Assessment) for batch workloads 3. Vurder Azure AI Foundry med dedikert regional processing (når tilgjengelig) 4. Alternativt: Azure Machine Learning batch endpoints med regional compute ### Budsjettprosesser og Kostnadsforutsigbarhet | Faktor | Anbefaling | |--------|------------| | **Cost estimation** | Azure OpenAI Batch API: 50% rabatt på token prices → oppdater budsjett-modeller | | **Quota management** | Separert batch quota → dedikert budsjettpost for batch vs. online | | **Month-to-month variance** | Batch workloads ofte mer forutsigbare (scheduled jobs) → lettere forecasting | | **Pilot phase** | Start med små batches (100-1000 requests) → måle cost-per-request før full rollout | ### Tilgjengelighet og SLA **Azure OpenAI Batch API SLA:** 24-timer target (best-effort, ikke garantert) **Konsekvens for offentlig sektor:** - Ikke egnet for kritiske, tidsensitive tjenester (bruk online deployments) - OK for batch rapportering, nattlige summarizations, periodiske analyser - Kombiner med online fallback for høy-prioritets requests --- ## Kostnad og Lisensiering ### Azure OpenAI Batch API Prismodell | Deployment Type | Pris (relativ) | Use Case | |-----------------|----------------|----------| | **Global Standard** | 100% (baseline) | Online chat, real-time inference | | **Global Batch** | 50% | Bulk processing, content generation, document analysis | | **Provisioned Throughput** | Varierer (reservation-based) | Høy throughput, forutsigbar latency | **Eksempel (GPT-4o, Januar 2026 priser — verifiser på Azure pricing page):** - Global Standard: ~$5 per 1M input tokens, ~$15 per 1M output tokens - Global Batch: ~$2.50 per 1M input tokens, ~$7.50 per 1M output tokens - **Besparelse:** 50% for identiske workloads **NOK Conversion (indikativt, 1 USD = 11 NOK):** - Global Standard: ~55 kr / 1M input tokens, ~165 kr / 1M output tokens - Global Batch: ~27.50 kr / 1M input tokens, ~82.50 kr / 1M output tokens ### Microsoft Graph JSON Batching **Pris:** Ingen ekstra kostnad — standard Graph API pricing gjelder per individual request i batchen. **Fordel:** Kun nettverkseffektivitet, ikke direkte kostnadsreduksjon på API calls. ### Azure Machine Learning Batch Endpoints **Prismodell:** - **Compute costs:** Per VM-time (AML compute clusters) - **Storage costs:** Input/output data i Azure Storage - **Ingen deployment costs:** Batch endpoints er gratis (betaler kun compute) **Low-Priority VMs:** - **Rabatt:** 60-80% vs. standard VMs - **Risk:** Kan deallocates når Azure trenger capacity - **Mitigering:** AML batch endpoints har auto-recovery (resumes fra siste checkpoint) **Eksempel (Standard_D4s_v3, ca. 0.35 USD/time):** - Standard VM: ~3.85 kr/time - Low-Priority VM: ~0.77-1.54 kr/time **Cost Optimization Tips:** 1. **Scale-to-zero:** Cluster auto-scales ned til 0 nodes når idle 2. **Mini-batch size tuning:** Større mini-batches → fewer VM-hours (men høyere memory usage) 3. **Instance count override:** Dynamisk øke parallelism for rush jobs, redusere for lavprioritets workloads 4. **Spot VMs:** Kombiner low-priority VMs med retry logic for max savings --- ## For Arkitekten (Cosmo) ### Spørsmål å Stille Klienten 1. **Volumetrics og Timing:** - "Hvor mange AI-requests forventer du daglig/månedlig?" - "Er det akseptabelt med 1-24 timers latency for disse requestene?" - "Har du spikes i last, eller er det jevnt distribuert?" 2. **Kostnadsbudsjett:** - "Hva er din totale AI API-budsjett per måned (NOK)?" - "Har dere beregnet cost-per-request for dagens løsning?" - "Er 50% kostnadsreduksjon viktig nok til å akseptere høyere latency?" 3. **Data og Compliance:** - "Inneholder batch requests personopplysninger?" - "Har dere TIA (Transfer Impact Assessment) for Schrems II?" - "Må data prosesseres i spesifikk Azure region (Norge/EU)?" 4. **Failure Handling:** - "Hva skjer hvis én request i en batch feiler? Retry hele batchen eller kun failed items?" - "Trenger dere transactional guarantees (all-or-nothing)?" - "Har dere monitoring og alerting for batch job failures?" 5. **Existing Infrastructure:** - "Bruker dere allerede Azure Service Bus, Event Grid eller Storage Queues?" - "Har dere CI/CD for deploying batch processing logic?" - "Er teamet komfortabelt med async programming patterns (polling, webhooks)?" 6. **Performance Targets:** - "Hva er max akseptabel latency per request?" - "Trenger dere real-time feedback til brukere, eller kan de vente på batch completion?" - "Har dere SLA-krav overfor egne sluttbrukere?" 7. **Scaling Plans:** - "Forventer dere 10x, 100x volum-økning neste år?" - "Vil dere trenge multi-region failover for batch processing?" ### Fallgruver å Unngå | Fallgruve | Hvorfor Det Er Farlig | Mitigering | |-----------|------------------------|------------| | **Over-batching** | Latency skyter i været, timeout errors | Dynamisk batch sizing (max 500-1000 items for Graph, 10K-100K for OpenAI) | | **Under-batching** | Ikke utnytter kostnadsbesparelser | Bruk buffering windows (5-10 sek) for å samle requests | | **Ignorere `custom_id` correlation** | Kan ikke matche responses til opprinnelige requests | Alltid generer UUID eller bruk business ID som `custom_id` | | **Hardkoding batch file paths** | Konflikter i concurrent jobs | Bruk timestamp eller GUID i filnavn (`batch_20260204_1423_uuid.jsonl`) | | **Ikke slette output files** | GDPR-brudd (persondata liggende etter processing) | Set `output_expires_after` (14-30 dager) eller slett manuelt post-processing | | **Blind retry av failed batches** | Cost explosion ved systematic failures | Inspiser failure reasons først, fix underliggende issue, deretter retry | | **Mixing batch og online i samme deployment** | Quota conflicts, unpredictable performance | Separate deployments for batch vs. online workloads | ### Anbefalinger per Modenhetsnivå **Level 1 (Proof-of-Concept):** - Start med Microsoft Graph JSON batching (enkelt, synkron) - Mål network latency improvement (før/etter batching) - Max 50-100 requests i første iterasjon **Level 2 (Pilot):** - Implementer Azure OpenAI Batch API for ikke-kritiske workloads (rapportering, summarization) - Kjør side-by-side med online deployment → sammenlign cost og latency - Etabler monitoring (batch job completion time, failure rate) **Level 3 (Production):** - Queue-based batching med Azure Service Bus + Functions - Auto-scaling compute basert på queue depth - Exponential backoff retry logic for transient failures - Dead-letter queue for systematic failures **Level 4 (Enterprise-Scale):** - Multi-region batch processing for resilience - Event-driven orchestration (Event Grid → Logic Apps → Batch API) - Cost allocation per business unit (tagging av batch jobs) - FinOps dashboard (cost-per-request tracking, budget alerts) ### Decision Matrix: Batch vs. Online Bruk denne matrisen for raskt å avgjøre om batching er riktig: | Kriterium | Batch ✅ | Online ✅ | |-----------|----------|-----------| | Latency SLA < 5 sek | ❌ | ✅ | | Volum > 1000 requests/dag | ✅ | ❌ (dyrere) | | Budget-begrenset | ✅ (50% rabatt) | ❌ | | Real-time user interaction | ❌ | ✅ | | Scheduled/nightly jobs | ✅ | ❌ (waste quota) | | Personopplysninger uten TIA | ❌ (data residency risk) | ✅ (regional control) | | Proof-of-concept | 🔶 (start online) | ✅ | | Production scale | ✅ | 🔶 (hybrid) | --- ## Kilder og Verifisering ### Microsoft Learn (Verified via MCP) 1. **Azure OpenAI Batch API:** - [Getting started with Azure OpenAI batch deployments](https://learn.microsoft.com/en-us/azure/ai-foundry/openai/how-to/batch) — **Verified 2026-02** - Dekker: JSONL input format, Global-Batch deployment, 50% cost reduction, exponential backoff queuing 2. **Microsoft Graph JSON Batching:** - [Combine multiple HTTP requests using JSON batching](https://learn.microsoft.com/en-us/graph/json-batching) — **Verified 2026-02** - Dekker: $batch endpoint, request/response correlation, dependsOn sequencing, 20-request limit 3. **Azure Machine Learning Batch Endpoints:** - [Batch endpoints](https://learn.microsoft.com/en-us/azure/machine-learning/concept-endpoints-batch?view=azureml-api-2) — **Verified 2026-02** - Dekker: Asynchronous inferencing, pipeline component deployments, low-priority VMs, scale-to-zero 4. **Code Samples (Python):** - [Azure OpenAI Batch API - Create batch job](https://learn.microsoft.com/en-us/azure/ai-foundry/openai/how-to/batch?pivots=programming-language-python#create-batch-job) — **Verified 2026-02** - [Azure Cosmos DB Transactional Batch](https://learn.microsoft.com/en-us/azure/cosmos-db/transactional-batch#how-to-create-a-transactional-batch-operation) — **Baseline (ikke AI-spesifikk, men relevant pattern)** ### Konfidensnivå per Seksjon | Seksjon | Konfidens | Kilde | |---------|-----------|-------| | Azure OpenAI Batch API | **Verified** | Microsoft Learn MCP (2026-02) | | Microsoft Graph JSON Batching | **Verified** | Microsoft Learn MCP (2026-02) | | Azure ML Batch Endpoints | **Verified** | Microsoft Learn MCP (2026-02) | | Prismodell (50% rabatt) | **Verified** | Azure OpenAI pricing page (referenced in docs) | | NOK conversion | **Baseline** | Modell-kunnskap (indikativ valutakurs) | | Schrems II implications | **Baseline** | Modell-kunnskap (juridisk interpretasjon) | | FinOps best practices | **Baseline** | Modell-kunnskap (generell FinOps-prinsipper) | | Queue-based patterns | **Baseline** | Modell-kunnskap (Azure Functions + Service Bus) | ### Relaterte Ressurser - [Azure OpenAI pricing](https://azure.microsoft.com/pricing/details/cognitive-services/openai-service/) - [Azure Machine Learning pricing](https://azure.microsoft.com/pricing/details/machine-learning/) - [Azure Service Bus pricing](https://azure.microsoft.com/pricing/details/service-bus/) - [OData $batch specification](http://docs.oasis-open.org/odata/odata-json-format/v4.01/odata-json-format-v4.01.html#sec_BatchRequestsandResponses) --- **Slutt av Referanse**