Skip to main content
RunBook Academy

CephXLVI · RGW Users and CredentialsRGW Users and Credentials

Applying RGW quotas in practice

Intermediate⏱ ~16 minradosgw-admin

What you'll learn

  • Apply user, bucket, and default quotas
  • Monitor consumption against limits
  • Track aggregate issued quota against capacity
  • Respond to a tenant at their limit

Prerequisites

None — start here.

Verified against Ceph Tentacle 20.2.x · Ceph Squid 19.2.x (supported previous) · cephadm matches the verified Ceph release · podman 4.x · csi-rbd and csi-cephfs current · RBD / CephFS / RGW current (matches Ceph release) · Linux kernel 5.15+ (5.10 minimum) · Ubuntu 24.04 LTS (Ceph host baseline) · Debian 12 (Bookworm) (Ceph host baseline) · Rocky Linux / RHEL / AlmaLinux 9.x (Ceph host baseline) · Proxmox VE 9.x (cross-course integration) · Kubernetes 1.31+ (cross-course integration) · 2026-08-18

Not yet marked complete on this device.

Why this matters in production

Quotas are what stop one tenant consuming everyone’s capacity, and RGW has no view of whether the quotas you have issued fit the cluster. Tracking that sum is a responsibility the tool does not take on.

The levels

# default for users created from now on
radosgw-admin global quota set --quota-scope=user --max-size=1T --max-objects=10000000
radosgw-admin global quota enable --quota-scope=user

# per user
radosgw-admin quota set --uid=analytics --quota-scope=user \
    --max-size=20T --max-objects=50000000
radosgw-admin quota enable --uid=analytics --quota-scope=user

# per bucket
radosgw-admin quota set --uid=analytics --bucket=scratch \
    --quota-scope=bucket --max-size=2T
radosgw-admin quota enable --uid=analytics --bucket=scratch --quota-scope=bucket

The global default is the important one: without it, a newly-created user is unlimited until someone remembers.

Monitoring

radosgw-admin quota show --uid=analytics --quota-scope=user
radosgw-admin user stats --uid=analytics --sync-stats
radosgw-admin bucket stats --bucket=scratch

--sync-stats forces a recalculation from the bucket index rather than reading the cached figure. Use it when the numbers look wrong; avoid it in a monitoring loop, since it is expensive on large buckets.

Aggregate tracking

# sum of issued user quotas
for u in $(radosgw-admin user list | jq -r '.[]'); do
  radosgw-admin quota show --uid="$u" --quota-scope=user | \
    jq -r --arg u "$u" '"\($u) \(.max_size)"'
done

Compare that sum against usable capacity. Over-committing is a legitimate strategy — most tenants never fill their allocation — but only when it is deliberate and monitored.

When a tenant hits their limit

HTTP 403 QuotaExceeded
# confirm from the cluster side
radosgw-admin user stats --uid=analytics --sync-stats
radosgw-admin quota show --uid=analytics --quota-scope=user

# raise it, if capacity allows
radosgw-admin quota set --uid=analytics --quota-scope=user --max-size=30T

Raising a quota takes effect on the next quota check, so the tenant resumes within the refresh interval rather than immediately.

Object count quotas

radosgw-admin quota set --uid=analytics --quota-scope=user --max-objects=50000000

Worth setting alongside the size quota: a tenant writing billions of tiny objects consumes index capacity and gateway resources disproportionately to the bytes involved, and a size quota does not bound that.

Quiz

Knowledge check · 4 questions

  1. Q1. Why set an object-count quota alongside a size quota?

  2. Q2. RGW prevents the sum of issued quotas from exceeding usable cluster capacity.

  3. Q3. Respond to a tenant reporting QuotaExceeded errors.

    A tenant reports 403 QuotaExceeded on uploads. Their contract allows 20 TB. `radosgw-admin user stats` shows 21.3 TB used against a 20 TB quota.

  4. Q4. Why should `--sync-stats` be avoided in a monitoring loop?

Passing score: 75%. Answers are checked in this browser.

Production discipline

Set a conservative global default quota before onboarding anyone, so no user is ever unlimited by omission. Track the aggregate issued quota against usable capacity yourself — RGW enforces each limit individually and has no view of whether they collectively fit.

Cross-course references

  • Kubernetes: ResourceQuota per namespace with no cluster-wide sum check is the same gap
  • Linux: filesystem quotas similarly permit over-allocation without warning