Skip to content

Comments

util/resolver/limited: make registry concurrency configurable via BUILDKIT_MAX_REGISTRY_CONCURRENCY#6517

Open
omerXfaruq wants to merge 1 commit intomoby:masterfrom
omerXfaruq:configurable-registry-concurrency
Open

util/resolver/limited: make registry concurrency configurable via BUILDKIT_MAX_REGISTRY_CONCURRENCY#6517
omerXfaruq wants to merge 1 commit intomoby:masterfrom
omerXfaruq:configurable-registry-concurrency

Conversation

@omerXfaruq
Copy link

Summary

  • Add BUILDKIT_MAX_REGISTRY_CONCURRENCY environment variable to allow overriding the default max concurrency of 4 connections per registry
  • Users with high-bandwidth networks pulling large images (10+ GB) are bottlenecked by the hardcoded 4 concurrent connections
  • The env var approach requires no config schema changes and works with any deployment method (docker buildx create --driver-opt env.BUILDKIT_MAX_REGISTRY_CONCURRENCY=20, Kubernetes pod env, etc.)

Relates to #6123

Changes

  • util/resolver/limited/group.go: Replace hardcoded DefaultMaxConcurrency int64 = 4 with a getMaxConcurrency() function that reads the env var at init time, falling back to 4 if unset/invalid
  • util/resolver/limited/group_test.go: Add table-driven test for getMaxConcurrency() covering valid values, zero, negative, and non-numeric input

Test plan

  • Unit test verifies env var parsing for valid, zero, negative, and non-numeric values
  • Manual test: run buildkitd with BUILDKIT_MAX_REGISTRY_CONCURRENCY=20 and verify increased parallelism on large image pulls

🤖 Generated with Claude Code

… var

Add BUILDKIT_MAX_REGISTRY_CONCURRENCY environment variable to allow
users to override the default max concurrency of 4 connections per
registry. Users with high-bandwidth networks pulling large images are
bottlenecked by the hardcoded limit.

Signed-off-by: omerXfaruq <omerXfaruq@users.noreply.github.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@omerXfaruq
Copy link
Author

hi @tonistiigi @AkihiroSuda who would be the right person to review this PR? never contributed to buildkit before :)

Copy link
Member

@tonistiigi tonistiigi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd prefer if this would be in the buildkitd toml config instead of env.

@thaJeztah
Copy link
Member

(Drive-by comment) I know on the dockerd daemon we have options to limit concurrent push/pulls, but ISTR there were some issues with the containerd image store integrations that still needed work; maybe it was that it didn't limit the total (but only per operation 🤔) (but perhaps was resolved);

      --max-concurrent-downloads int          Set the max concurrent downloads (default 3)
      --max-concurrent-uploads int            Set the max concurrent uploads (default 5)
      --max-download-attempts int             Set the max download attempts for each pull (default 5)

@omerXfaruq
Copy link
Author

omerXfaruq commented Feb 12, 2026

I'd prefer if this would be in the buildkitd toml config instead of env.

@tonistiigi yup, i was hesitant about that part as well, since it'd be easier to build it with i took that path. open to alternative solutions.

my previous discussion regarding this with claude:

For an upstream PR to `moby/buildkit`, I'd recommend **sticking with the env var**. Here's my reasoning:

**Why env var is the better choice for this PR:**

1. **Merge probability** -- BuildKit maintainers are cautious about config schema changes. Adding a new key to `buildkitd.toml` means they need to commit to its name, location, and semantics forever. An env var is considered more "informal" and easier to accept as a first step.

2. **Scope of change** -- A config option would require touching:
   - The TOML config struct (`config/config.go` or similar)
   - The config parser/loader
   - Plumbing the value from the daemon entrypoint down to `util/resolver/limited/group.go`
   - Config documentation
   
   That's 4-5 files instead of 1, and each one is a potential review debate.

3. **Precedent** -- BuildKit already uses env vars for runtime tunables (e.g., `BUILDKIT_DEBUG_EXEC_OUTPUT`, `BUILDKIT_DEBUG_PANIC_ON_ERROR`). The pattern exists.

4. **Config can come later** -- If maintainers like the feature and want it promoted to a first-class config option, that's a natural follow-up PR. The env var can remain as a fallback/override. This is a common pattern in infrastructure projects: env var first, config later.

5. **Deployment ease** -- For most users, setting an env var is actually *easier* than modifying `buildkitd.toml`:
   - `docker buildx create --driver-opt env.BUILDKIT_MAX_REGISTRY_CONCURRENCY=20`
   - Kubernetes pod `env:` block
   - No need to mount a custom config file

**The one argument for config** is discoverability -- users reading `buildkitd.toml` docs might never find the env var. But that's solved by mentioning it in the PR description and docs, and can be upgraded later.

I'd say go with the env var as planned, and mention in the PR description: *"If maintainers prefer this as a `buildkitd.toml` option, happy to refactor."* That signals openness without front-loading the work.

@omerXfaruq
Copy link
Author

⏺ Here are the actual measured results with BUILDKIT_MAX_REGISTRY_CONCURRENCY=20:

  Network Throughput — Per Second

  Peak:  947 MB/s (t+1s)  — all 20 layers downloading simultaneously
  2nd:   688 MB/s (t+2s)
  3rd:   478 MB/s (t+3s)
  Sustained (t+4s–t+23s): 350–440 MB/s — 4 large layers active
  Tail (t+24s–t+35s): 138–283 MB/s — 2 then 1 layer remaining

  Summary
  ┌─────────────────────────┬────────────────────────────────────────────────────────┐
  │         Metric          │                         Value                          │
  ├─────────────────────────┼────────────────────────────────────────────────────────┤
  │ Peak download speed     │ 947 MB/s (~7.6 Gbps)                                   │
  ├─────────────────────────┼────────────────────────────────────────────────────────┤
  │ Sustained (multi-layer) │ 350–440 MB/s (~3.0–3.5 Gbps)                           │
  ├─────────────────────────┼────────────────────────────────────────────────────────┤
  │ Total downloaded        │ 12,699 MB (~12.4 GB)                                   │
  ├─────────────────────────┼────────────────────────────────────────────────────────┤
  │ Pull time               │ 34.9s (t+36s onward was OCI tarball export, 0 network) │
  ├─────────────────────────┼────────────────────────────────────────────────────────┤
  │ Average during pull     │ 364 MB/s (12,699 MB / 35s)                             │
  └─────────────────────────┴────────────────────────────────────────────────────────┘

@tonistiigi
Copy link
Member

my previous discussion regarding this with claude:

Still prefer config.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants