Skip to main content

Container Registry limits

Reviewed on · View on GitHub

Technical limits​

Push throughput and timeouts​

LimitValueReason
Ingress proxy read timeout3600 sNGINX ingress proxy-read-timeout and proxy-send-timeout annotations raised from the 60 s default (ref: registry.expose.ingress.annotations)
Ingress proxy send timeout3600 sSame as above
Observed push throughput~4–5 MB/sMeasured during preproduction blackbox tests (2 GB blob upload completed in ~489 s)
Recommended blob (layer) size< ~300 MBKeeps a single-blob upload comfortably within the 3600 s window even with degraded throughput
Theoretical single-blob ceiling~16 GB3600 s at ~4.5 MB/s; uploads approaching this size are at risk and should be split
Blob upload modes

The registry supports the OCI distribution specification chunked blob upload (POST → PATCH → PUT) and the monolithic single-PUT upload. Standard clients (Docker, Podman, Buildah, skopeo, BuildKit) use chunked or streamed uploads. Only raw, hand-written clients that push an entire blob in a single PUT are exposed to the full timeout window at once.

Known issues​

IssueImpactWorkaroundStatus
unexpected EOF error during a large image pushPush fails mid-transfer on multi-gigabyte monolithic blob uploads (single PUT exceeding the ingress proxy timeout, previously 60 s)Use standard clients that stream or chunk blob uploads (Docker, Podman, BuildKit, skopeo); keep layers small with multi-stage builds and .dockerignoreResolved — proxy timeout raised to 3600 s

Background​

Prior to the timeout increase, the shared ingress controller only set use-proxy-protocol: true for the registry virtual host. NGINX proxy timeouts therefore applied their 60 s defaults, and any blob upload whose single request exceeded 60 s was cut off by the proxy (unexpected EOF). The per-service annotations in registry.expose.ingress.annotations now raise both proxy-read-timeout and proxy-send-timeout to 3600 s.

Even with the raised timeout, splitting images into smaller layers remains the recommended practice: it improves push resilience (a failed layer is retried alone), cache efficiency, and pull performance.