Skip to content

Comments

feat: enforce per-org cache storage quotas#1

Merged
haasonsaas merged 3 commits intomainfrom
feature/storage-quotas
Oct 17, 2025
Merged

feat: enforce per-org cache storage quotas#1
haasonsaas merged 3 commits intomainfrom
feature/storage-quotas

Conversation

@haasonsaas
Copy link
Contributor

Summary

  • add per-org quota tracking for cache proxy and docker cache
  • expose configuration via - NIMBUS_CACHE_ORG_QUOTA_BYTES
    • NIMBUS_DOCKER_ORG_QUOTA_BYTES
  • reject writes exceeding configured quota and account for evictions

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

victims = self.metrics.oldest_blobs(limit=1)
if not victims:
break
digest, size = victims[0]
path = self.blob_path(digest)
if path.exists():
path.unlink(missing_ok=True)

P1 Badge Subtract org bytes when docker cache evicts blobs

When the cache exceeds its global size limit, ensure_storage_limit removes blob files and deletes their metric rows but never decrements the per‑org usage counters. As a result, an org’s recorded usage only ever increases and quota checks will eventually reject new uploads even though their earlier blobs have been evicted. The eviction loop should look up each victim’s org and call update_org_usage(..., -size) before deleting the record.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting

Comment on lines 504 to +568
bytes_written = await state.backend.head(namespaced_key)
new_total = state.update_org_usage(org_id, bytes_written)
quota = state.settings.org_storage_quota_bytes
if quota is not None and new_total > quota:
state.update_org_usage(org_id, -bytes_written)

Choose a reason for hiding this comment

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

P1 Badge Delete cache object when rejecting on org quota

The PUT handler increments the org’s byte counter only after the blob has been written, and when the quota is exceeded it merely subtracts the counter and returns 413 but never removes the already-written object. This allows rejected writes to remain stored and retrievable, so disk usage can exceed the configured quota while metrics claim otherwise. Consider deleting the object (e.g. via the backend) before raising the exception so quota enforcement actually prevents the artifact from being cached.

Useful? React with 👍 / 👎.

Comment on lines +594 to +598
quota = state.settings.org_storage_quota_bytes
new_total = state.update_org_usage(token.organization_id, final_session.size)
if quota is not None and new_total > quota:
state.update_org_usage(token.organization_id, -final_session.size)
final_session.file_path.unlink(missing_ok=True)

Choose a reason for hiding this comment

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

P1 Badge Avoid counting deduplicated blobs toward org quota

update_org_usage is called before checking whether the uploaded digest already exists. Re‑pushing a blob that is already present (a common case with Docker layers) bumps the org’s stored byte total even though the file is discarded in the target_path.exists() branch. This will cause quotas to trip even when no additional disk space is consumed. The quota update should happen only when a new blob is stored or should be rolled back when deduplication occurs.

Useful? React with 👍 / 👎.

Copy link
Contributor Author

@haasonsaas haasonsaas left a comment

Choose a reason for hiding this comment

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

Fixes look great now—checksum lookup matches the computed digest, cache quota rollbacks cleanly delete artifacts, and docker evictions correctly adjust org usage. Tests all green. Ship it.

@haasonsaas haasonsaas merged commit 50b3b1e into main Oct 17, 2025
1 check passed
@haasonsaas haasonsaas deleted the feature/storage-quotas branch October 17, 2025 04:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant