APIM Backend Fan-out: Shared Backend + rewrite-uri vs One Backend Per API (A Real Benchmark)

APIM Backend Fan-out: Shared Backend + rewrite-uri vs One Backend Per API (A Real Benchmark)


🎯 TL;DR: Shared Backend + rewrite-uri is performance-equivalent to one Backend per API.

The question: if you point 100+ APIs at a single APIM Backend entity and use rewrite-uri to reconstruct the path, do you pay a measurable latency / throughput / reliability penalty versus modelling one Backend entity per API?

Two identical APIM Premium instances, same Function App backend, same k6 load. Across 1.67M requests and ~32 minutes of stepped load (50 → 100 → 200 VUs): 882 vs 874 req/s, 146 vs 153 ms p95, 0 errors on both sides. All three pass/fail thresholds satisfied. Pick the pattern on operational simplicity, not performance.

Bonus finding: backend cold-scale will lie to you. The first run made the shared-backend pattern look 2× slower, that was Flex Consumption scaling up during APIM-A’s window, not a pattern difference. Always warm your backend before measuring.

Full benchmark, IaC, k6 scripts, KQL, and interactive dashboard: github.com/Ricky-G/azure-scenario-hub/tree/main/src/apim-backend-fanout-benchmark

Recently I ran into a scenario worth benchmarking properly: an APIM Premium estate with 100+ APIs that all ultimately call the same upstream service. The architectural choice is whether to model those APIs against a single APIM Backend entity and use rewrite-uri to reconstruct the right path on the way out, or to create one Backend entity per API. One backend is one thing to manage, one health probe, one circuit breaker, one place to flip URLs during a migration. One hundred is, well, one hundred.

Intuition splits cleanly down the middle on whether the shared pattern carries a hidden cost (connection pools are per-backend, surely?) or none at all (it’s just a string concat). I couldn’t find a clean controlled benchmark of this specific question, so I built one, fully reproducible in the Azure Scenario Hub. What follows is the methodology, the numbers, and the wrong answer the first run produced.

The Two Patterns

flowchart LR
    subgraph A["APIM-A · Premium 1 unit · SHARED backend + rewrite-uri"]
      A_API1[api-shared-01 /svc01/v1]
      A_API2[api-shared-02 /svc02/v1]
      A_APIn[...10 APIs]
      A_FRAG{policy fragment
set-backend-service
+ rewrite-uri} A_BE[(1 Backend entity)] A_API1 --> A_FRAG A_API2 --> A_FRAG A_APIn --> A_FRAG A_FRAG --> A_BE end subgraph B["APIM-B · Premium 1 unit · PER-API backend"] B_API1[api-perapi-01 /svc01/v1] --> B_BE1[(Backend 01)] B_API2[api-perapi-02 /svc02/v1] --> B_BE2[(Backend 02)] B_APIn[...10 APIs] --> B_BEN[(Backend 10)] end A_BE --> Func[(Same Mock Backend
Function App · 5ms baseline)] B_BE1 --> Func B_BE2 --> Func B_BEN --> Func
Read more
Preserving Custom Query String Parameters Through Azure App Service Easy Auth

Preserving Custom Query String Parameters Through Azure App Service Easy Auth


🎯 TL;DR

Azure App Service’s built-in authentication (“Easy Auth”) preserves the original path and query string, every custom parameter included, across the Microsoft Entra ID OAuth round trip. Your app gets the request back with the query string fully intact and zero authentication code. (URL fragments need a separate opt-in, see Gotchas.)

The mechanism is the standard OAuth 2.0 state parameter: Easy Auth encodes the original path + query into state, Entra echoes it back, Easy Auth 302s the browser to the original URL after sign-in.

Bonus finding from the captured traces: an inbound login_hint on the request is forwarded to Entra so the sign-in page is pre-populated, no loginParameters configuration needed.

Full reproducible scenario (Bicep + sample app + deploy scripts) in the Azure Scenario Hub: src/app-service-easy-auth. Clone, ./deploy-infra.ps1, watch the round-trip in your own browser in ~3 minutes.

A question I ran into recently:

If we put a login_hint, a recordId, and a bunch of other custom things in the query string, and let Easy Auth redirect to Entra for sign-in, will those query string parameters come back to us after authentication? Or do we have to write code to stash them somewhere first?

The answer is yes, they come back, and no, you don’t have to write any code. Easy Auth handles it natively. This post walks through how, with HTTP traces captured byte-for-byte from a live deployment, all reproducible from the Azure Scenario Hub.

Read more