Docker Hub Pull Rate Limit Calculator

Work out whether you will hit Docker Hub's limit. Two things make the number worse than expected: it is counted per address, and a cached image still costs a pull.

Paste below, or drop a file anywhere on this panel

Or drop a file anywhere on this panel. Nothing is uploaded: the analysis runs in this tab.

The answer appears here

Paste on the left and press Calculate. Nothing leaves this tab.

Examples

Real input you can load into the tool above. Each one shows a different thing going wrong, because that is what the tool is for.

Anonymous pulls from a runner pool

The budget is shared across everything behind the gateway

pulls: 400
tier: anonymous
runners: 20

Within the free tier

Fits, and a cached image still costs a pull

pulls: 150
tier: free

Common mistakes

These are the ones that fail silently. The config is accepted, nothing raises an error, and the consequence arrives later.

  1. Pulling anonymously from CI

    The limit is per source address, so a runner pool behind one NAT gateway shares it and one busy pipeline exhausts it for everybody.

    Instead:Authenticate, even for public images. The limit then belongs to the account and roughly doubles.

  2. Counting only the images you actually download

    The limit counts manifest requests, so an image already on the node still costs a pull every time something checks it.

    Instead:Pin by digest where you can, and use imagePullPolicy: IfNotPresent rather than Always.

  3. Treating 429s as flaky CI

    They clear after the window and come back under load, which looks exactly like flakiness and is a quota.

    Instead:Check the rate limit headers on a pull before assuming the network is at fault.

The anonymous limit belongs to your IP address, not to you

Everything behind one address shares it: every CI runner, every developer on the office network, every container on the host. So somebody else's pipeline can exhaust your budget.

A cached image still costs a pull

The limit counts manifest requests, and a pull always fetches the manifest to check whether the local copy is current, even when every layer is already on disk. A multi-platform image costs more than one, because the index is fetched and then the platform manifest. So the pull count is higher than the number of times anything was transferred.

Kubernetes with imagePullPolicy: Always is the usual amplifier

Every pod start fetches the manifest. A deployment that restarts often, or a job that runs on a schedule, generates far more pulls than the image count suggests, and a node pool behind one NAT gateway shares the budget.

Authenticating is the single biggest change

It moves the counting from the address to the account and roughly doubles the number. It costs nothing and applies even to public images, which is the part people skip because pulling anonymously works right up until it does not.

A pull-through cache turns many pulls into one

A local registry in proxy mode fetches from Hub once and serves everything after that, so a fleet of runners costs one pull rather than one each. It also survives a Hub outage, which the rate limit discussion tends to overshadow.

The failure looks intermittent

Past the limit, pulls fail with a 429 and clear on their own after the window. In CI that is a build failure with no code change behind it that passes on a retry, which is why it gets attributed to flakiness rather than to a quota.

The numbers here are dated

Docker has changed the tiers and the figures several times, and a page in your browser cannot ask Hub what your current limit is. Treat the arithmetic as the useful part and check the figures against Docker's pricing page.

More docker tools

Docker Container Image Reference Parser Is that a registry or a Docker Hub user? Dockerfile Linter What this image will do to you later docker run to Kubernetes YAML And the flags that have no equivalent Docker Compose to Kubernetes And why depends_on has no equivalent Docker Logging Driver Generator json-file never rotates Dockerfile Non-Root USER Generator Numeric, or Kubernetes rejects it Docker OCI Image Labels Generator One of them actually does something Docker Registry Storage Calculator Deleting a tag frees nothing Docker Build Context Analyzer All of it uploads before anything runs Docker Compose to docker run Converter Names stop resolving Docker Compose Version Migrator version: is obsolete now Docker Compose Network and Port Viewer Everything reaches everything Docker Command Explainer Which flags hand over the host Docker BuildKit Cache Mount Generator apt deletes the cache you just mounted Docker BuildKit Secret Mount Generator ARG is in docker history forever Docker .dockerignore Pattern Tester *.log does not match logs/app.log Docker Image Manifest Viewer unknown/unknown is not broken Docker Image Config Viewer Anyone who can pull can read your Env Docker Registry Token Decoder Check the scope before the credentials Docker HEALTHCHECK Generator Docker does nothing when it fails Docker Network Subnet Calculator 31 networks, then it stops Docker History Analyzer The rm did not save anything Docker Run to Compose Converter Some flags have no equivalent Docker CMD and ENTRYPOINT Tester Why docker stop takes ten seconds Docker Port Mapping Tester -p reaches past your firewall Docker -v to --mount Converter -v invents missing directories Docker Restart Policy Simulator The backoff resets after ten seconds Docker Exit Code Explainer 137 is two different problems Docker CPU Limit Converter --cpu-shares limits nothing Docker Memory Limit Calculator -m 512m allows a gigabyte Docker Compose Interpolation Tester An unset variable is an empty string Docker Environment Variable Precedence Tester Your shell does not reach the container Docker Compose Override Merge Previewer An override can add a port, never remove one Dockerfile Multi-Stage Build Analyzer Which stages reach the image Dockerignore Validator It is not .gitignore

Elsewhere on the site