Managing Multi‑Tenant Storage in Harbor with Project Quotas
Harbor’s Project Quotas let admins cap storage per project, preventing a single team from exhausting shared registry space. Learn how to set limits, enforce them during image pushes, and monitor usage – plus best‑practice trade‑offs.
28 May 2026, 14:31 UTC

Problem
In a shared Harbor instance, a single team can easily consume the majority of the storage backend, leaving no room for others. This can bring CI/CD pipelines to a halt and force administrators to manually intervene. The core issue is the lack of a built‑in mechanism to cap how much disk or object‑store space a project may use.
Why Project Quotas Matter
Harbor’s Project Quotas feature lets an administrator set a hard limit on the total size of all images, tags, and layers that belong to a specific project. When a push would exceed that limit, Harbor rejects the request with a clear error. This protects the registry from runaway growth and keeps resources fair across teams.
Setting a Quota – UI and API
- Via the UI:
- Create or open a project (e.g.,
dev-team). - Navigate to Project Settings > Quota.
- Enter a value such as
10 GBand click Save.
- Create or open a project (e.g.,
- Via the REST API (requires Harbor administrator role):
curl -k -u admin:HarborPass \ -X POST \ -H "Content-Type: application/json" \ -d '{"project_id":123,"storage_limit":"10GB"}' \ https://harbor.example.com/api/v2.0/quotasReplace
123with the numeric project ID, which you can find in the project’s URL or viaGET /api/v2.0/projects.
Enforcement During Push
When a client pushes an image, Harbor calculates the projected new usage. If the sum would exceed the quota, the registry responds with HTTP 400 and a JSON body containing message: "Quota exceeded". The push is aborted before any data is written to the backend, ensuring no wasted bandwidth.
Example push that hits the limit:
docker tag alpine:latest registry.example.com/dev-team/large:latest
# This image is ~12 GB after layers are added to the registry
# The quota is set to 10 GB
docker push registry.example.com/dev-team/large:latest
# Response
# HTTP/1.1 400 Bad Request
# Content-Type: application/json
# {"message":"Quota exceeded","code":400}
Monitoring Usage
Harbor exposes current usage in two ways:
- Dashboard – each project’s overview page shows a
Storage Usedmetric. - API –
GET /api/v2.0/projects/123/quotasreturns thestorage_limitandstorage_usedfields.
Because Harbor aggregates size from the underlying storage driver, the reported value may lag a few minutes behind actual changes, especially after garbage collection.
Trade‑Offs & Best Practices
| Consideration | Impact |
|---|---|
| Quota Too Low | CI/CD pipelines may fail unexpectedly during image pushes. |
| Garbage Collection Lag | Reported usage may overstate actual consumption until GC runs. |
| No Automatic Cleanup | Exceeding the quota only blocks new pushes; old images remain until manually pruned. |
To mitigate these issues:
- Set quotas slightly higher than the expected peak, allowing a buffer for transient growth.
- Schedule regular garbage collection (e.g., nightly) to free space and keep usage metrics accurate.
- Combine quotas with Harbor’s Garbage Collection feature or external cleanup scripts.
Conclusion
Project Quotas give Harbor administrators a simple, enforceable way to guarantee fair storage distribution in a multi‑tenant registry. By configuring limits, monitoring usage, and pairing quotas with garbage collection, teams can avoid unexpected pipeline failures and keep the registry healthy without constant manual intervention.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.