Symptom
When downloading BC artifacts from bcartifacts-exdbf9fwegejdqak.b02.azurefd.net on hosted CI runners (GitHub Actions ubuntu-latest, also reproduced on hosted Azure DevOps agents), wall-clock download time varies wildly between runs against the same artifact and from the same runner pool:
- Fast path (typical): ~30 s for app (~850 MB) + platform (~1.3 GB) — i.e. ~70-90 MB/s aggregate.
- Slow path (occasional): 5-6 min for the same payload — effective rate drops to <5 MB/s.
There's no error, no retry, no timeout — the GETs just complete slowly. So curl --retry doesn't help: the connection is "successful", just slow.
Evidence
A recent run on a Microsoft-hosted ubuntu-latest runner that hit the fast path:
[artifacts] App URL: https://bcartifacts-exdbf9fwegejdqak.b02.azurefd.net/sandbox/27.5.46862.48612/w1
[artifacts] Platform URL: https://bcartifacts-exdbf9fwegejdqak.b02.azurefd.net/sandbox/27.5.46862.48612/platform
[artifacts] Downloading app + platform in parallel...
[artifacts] Downloaded: app=856M platform=1.3G in 23546ms (~88 MB/s)
[artifacts] Extracting app...
[artifacts] Extracted in 27094ms | Total: 50654ms | Disk: 3.0G
So the network and runner are clearly capable of ~88 MB/s. But other runs against the same URL on the same runner type take 5-6 min for the same bytes.
Download shape
Two concurrent HTTP/1.1 GETs (one for <type>/<version>/<country>, one for <type>/<version>/platform), each on a single TCP connection:
curl -sSL --retry 3 --retry-all-errors --http1.1 "$APP_URL" -o app.zip &
curl -sSL --retry 3 --retry-all-errors --http1.1 "$PLATFORM_URL" -o platform.zip &
wait
--http1.1 is intentional — without it, HTTP/2 multiplexing on AFD made things consistently worse in our testing.
Suspected cause
The host is Azure Front Door (.azurefd.net), which has documented per-route knobs:
responseTimeoutSeconds (origin-fetch + total response budget)
- per-connection bandwidth caps / origin pool sizing
- origin fetch behaviour on cold cache miss
The slow runs have the shape of a per-connection bandwidth cap that's set tight, or an origin-fetch timeout that's just barely large enough on the fast path and falls back to a slower path on the slow one. Since we use one connection per file, there's no way for the client to compensate when AFD throttles that connection.
What's been tried client-side (and why it doesn't fix it)
- ✅ Forcing HTTP/1.1 — helps, but doesn't eliminate the slow path
- ✅ Parallelising app + platform — lifts aggregate, but each connection is still capped
- ❌
curl --retry — the slow connection completes "successfully", so retry never triggers
- ❌ Range-request parallelism (4-8 byte ranges per file) would multiply throughput on the slow path, but it's a non-trivial rewrite and shouldn't be necessary if AFD limits are right
The ask
Could the AFD route limits for bcartifacts-exdbf9fwegejdqak.b02.azurefd.net be reviewed? Specifically:
responseTimeoutSeconds and origin-fetch timeout for the /sandbox/<version>/... and /onprem/<version>/... routes
- Whether there's a per-connection bandwidth cap, and if so what it's set to
- Whether cold-cache misses on these blobs go through a slower origin path that could be warmed up or cached more aggressively
Stefan mentioned in our discussion that he remembers a previous request like this leading to some AFD values being adjusted — same thing, please. 🙂
Affects
navcontainerhelper artifact downloads (same URL, same shape)
- The
download-artifacts.sh used by StefanMaron/MsDyn365Bc.On.Linux (Linux BC runtime), which is what surfaced this for me
- Likely anyone hitting
bcartifacts-exdbf9fwegejdqak.b02.azurefd.net from CI
cc Freddy Kristiansen (@freddydk)
Symptom
When downloading BC artifacts from
bcartifacts-exdbf9fwegejdqak.b02.azurefd.neton hosted CI runners (GitHub Actionsubuntu-latest, also reproduced on hosted Azure DevOps agents), wall-clock download time varies wildly between runs against the same artifact and from the same runner pool:There's no error, no retry, no timeout — the GETs just complete slowly. So
curl --retrydoesn't help: the connection is "successful", just slow.Evidence
A recent run on a Microsoft-hosted
ubuntu-latestrunner that hit the fast path:So the network and runner are clearly capable of ~88 MB/s. But other runs against the same URL on the same runner type take 5-6 min for the same bytes.
Download shape
Two concurrent HTTP/1.1 GETs (one for
<type>/<version>/<country>, one for<type>/<version>/platform), each on a single TCP connection:--http1.1is intentional — without it, HTTP/2 multiplexing on AFD made things consistently worse in our testing.Suspected cause
The host is Azure Front Door (
.azurefd.net), which has documented per-route knobs:responseTimeoutSeconds(origin-fetch + total response budget)The slow runs have the shape of a per-connection bandwidth cap that's set tight, or an origin-fetch timeout that's just barely large enough on the fast path and falls back to a slower path on the slow one. Since we use one connection per file, there's no way for the client to compensate when AFD throttles that connection.
What's been tried client-side (and why it doesn't fix it)
curl --retry— the slow connection completes "successfully", so retry never triggersThe ask
Could the AFD route limits for
bcartifacts-exdbf9fwegejdqak.b02.azurefd.netbe reviewed? Specifically:responseTimeoutSecondsand origin-fetch timeout for the/sandbox/<version>/...and/onprem/<version>/...routesStefan mentioned in our discussion that he remembers a previous request like this leading to some AFD values being adjusted — same thing, please. 🙂
Affects
navcontainerhelperartifact downloads (same URL, same shape)download-artifacts.shused by StefanMaron/MsDyn365Bc.On.Linux (Linux BC runtime), which is what surfaced this for mebcartifacts-exdbf9fwegejdqak.b02.azurefd.netfrom CIcc Freddy Kristiansen (@freddydk)