Skip to main content

Storage Quotas API

Complete API reference for managing storage quotas. Set size limits and object count limits on buckets, monitor usage, and track quota violations.

Overview

Storage quotas allow you to:

  • Set maximum storage size limits (in bytes) per bucket
  • Set maximum object count limits per bucket
  • Monitor current usage and quota status
  • Track quota violations
  • Get detailed usage statistics

Key Features:

  • ✅ Flexible quota types (size-based, count-based, or both)
  • ✅ Fast usage retrieval from denormalized counters
  • ✅ Periodic updates via management command
  • ✅ Comprehensive quota status reporting
  • ✅ No upload blocking (quotas are for monitoring only)

Endpoints Overview

MethodEndpointDescription
PATCH/api/apps/{app_slug}/storage/buckets/{slug}/Set or update bucket quotas
GET/api/apps/{app_slug}/storage/buckets/{slug}/Get bucket with quota info
GET/api/apps/{app_slug}/storage/buckets/{slug}/usage/Get detailed usage statistics

Quota Fields

Bucket Model (Quota Fields)

FieldTypeWritableDescription
max_size_bytesinteger/null✅ YesMaximum total storage size in bytes (null = no limit)
max_size_mbfloat/null❌ NoMaximum size in MB (computed from max_size_bytes)
max_size_gbfloat/null❌ NoMaximum size in GB (computed from max_size_bytes)
max_objectsinteger/null✅ YesMaximum number of objects (null = no limit)
quota_exceededboolean❌ NoFlag indicating if bucket has exceeded quota
usageobject❌ NoCurrent usage statistics (computed)
quota_statusobject/null❌ NoComprehensive quota status (null if no quota set)

Usage Object

{
"total_size": 2415919104, // Total size in bytes
"total_objects": 234, // Total number of objects
"size_mb": 2304.0, // Size in megabytes
"size_gb": 2.25, // Size in gigabytes
"last_updated": "2025-01-20T15:30:00Z" // When counters were last updated (null if not yet calculated)
}

Quota Status Object

Only present when bucket has quotas set (max_size_bytes or max_objects).

{
"exceeded": {
"size": false, // Size quota exceeded?
"objects": false, // Object count quota exceeded?
"any": false // Any quota exceeded?
},
"percent_used": {
"size": 22.5, // Percentage of size quota used (null if no size quota)
"objects": 23.4 // Percentage of object quota used (null if no object quota)
},
"overage": {
"size_bytes": 0, // Bytes over limit (0 if not exceeded)
"size_mb": 0.0, // MB over limit
"objects": 0 // Objects over limit
}
}

Setting Quotas

Update bucket quotas using the PATCH endpoint.

Request

PATCH /api/apps/{app_slug}/storage/buckets/{slug}/
Authorization: Bearer YOUR_TOKEN
Content-Type: application/json

Examples

Set Size Quota (10GB)

curl -X PATCH \
'https://your-api.com/api/apps/my-app/storage/buckets/user-avatars/' \
-H 'Authorization: Bearer YOUR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"max_size_bytes": 10737418240
}'

Set Object Count Quota (1000 files)

curl -X PATCH \
'https://your-api.com/api/apps/my-app/storage/buckets/documents/' \
-H 'Authorization: Bearer YOUR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"max_objects": 1000
}'

Set Both Quotas (10GB + 1000 files)

curl -X PATCH \
'https://your-api.com/api/apps/my-app/storage/buckets/media/' \
-H 'Authorization: Bearer YOUR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"max_size_bytes": 10737418240,
"max_objects": 1000
}'

Response

{
"id": 5,
"uuid": "550e8400-e29b-41d4-a716-446655440000",
"name": "User Avatars",
"slug": "user-avatars",
"visibility": "private",

// Quota fields
"max_size_bytes": 10737418240,
"max_size_mb": 10240.0,
"max_size_gb": 10.0,
"max_objects": 1000,
"quota_exceeded": false,

// Usage statistics
"usage": {
"total_size": 2415919104,
"total_objects": 234,
"size_mb": 2304.0,
"size_gb": 2.25,
"last_updated": "2025-01-20T15:30:00Z"
},

// Quota status
"quota_status": {
"exceeded": {
"size": false,
"objects": false,
"any": false
},
"percent_used": {
"size": 22.5,
"objects": 23.4
},
"overage": {
"size_bytes": 0,
"size_mb": 0.0,
"objects": 0
}
},

// Other bucket fields...
"object_count": 234,
"created_at": "2025-01-15T10:00:00Z",
"updated_at": "2025-01-20T15:30:00Z"
}

Validation

  • max_size_bytes must be a positive integer (> 0)
  • max_objects must be a positive integer (> 0)
  • Both fields can be set to null to remove quotas

Error Response (Invalid Value):

{
"max_size_bytes": ["Maximum size must be a positive number"]
}

Viewing Quotas & Usage

Get Bucket Details

Standard bucket GET endpoint includes quota information.

curl https://your-api.com/api/apps/my-app/storage/buckets/user-avatars/ \
-H "Authorization: Bearer YOUR_TOKEN"

Response: Same as PATCH response above (includes all quota fields).

Get Detailed Usage Statistics

Dedicated endpoint for comprehensive usage and quota information.

GET /api/apps/{app_slug}/storage/buckets/{slug}/usage/
Authorization: Bearer YOUR_TOKEN

Example Request

curl https://your-api.com/api/apps/my-app/storage/buckets/user-avatars/usage/ \
-H "Authorization: Bearer YOUR_TOKEN"

Response

{
"bucket": {
"id": 5,
"name": "User Avatars",
"slug": "user-avatars",
"has_quota": true
},
"quota": {
"max_size_bytes": 10737418240,
"max_size_mb": 10240.0,
"max_size_gb": 10.0,
"max_objects": 1000
},
"usage": {
"total_size": 2415919104,
"total_objects": 234,
"size_mb": 2304.0,
"size_gb": 2.25,
"last_updated": "2025-01-20T15:30:00Z"
},
"exceeded": {
"size": false,
"objects": false,
"any": false
},
"percent_used": {
"size": 22.5,
"objects": 23.4
},
"overage": {
"size_bytes": 0,
"size_mb": 0.0,
"objects": 0
}
}

Response When Quota Exceeded

{
"bucket": {
"id": 6,
"name": "Documents",
"slug": "documents",
"has_quota": true
},
"quota": {
"max_size_bytes": 5368709120,
"max_size_mb": 5120.0,
"max_size_gb": 5.0,
"max_objects": 500
},
"usage": {
"total_size": 6442450944,
"total_objects": 567,
"size_mb": 6144.0,
"size_gb": 6.0,
"last_updated": "2025-01-20T15:30:00Z"
},
"exceeded": {
"size": true, // ⚠️ Size quota exceeded
"objects": true, // ⚠️ Object quota exceeded
"any": true
},
"percent_used": {
"size": 120.0, // 120% of quota used
"objects": 113.4 // 113.4% of quota used
},
"overage": {
"size_bytes": 1073741824, // 1GB over limit
"size_mb": 1024.0,
"objects": 67 // 67 files over limit
}
}

Removing Quotas

Set quota fields to null to remove limits.

Remove All Quotas

curl -X PATCH \
'https://your-api.com/api/apps/my-app/storage/buckets/user-avatars/' \
-H 'Authorization: Bearer YOUR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"max_size_bytes": null,
"max_objects": null
}'

Remove Size Quota Only

curl -X PATCH \
'https://your-api.com/api/apps/my-app/storage/buckets/user-avatars/' \
-H 'Authorization: Bearer YOUR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"max_size_bytes": null
}'

Response: Bucket with quotas removed (fields will be null).

Common Quota Sizes

Quick reference for common quota values:

SizeBytesJSON Value
100 MB104,857,600104857600
500 MB524,288,000524288000
1 GB1,073,741,8241073741824
5 GB5,368,709,1205368709120
10 GB10,737,418,24010737418240
50 GB53,687,091,20053687091200
100 GB107,374,182,400107374182400
500 GB536,870,912,000536870912000
1 TB1,099,511,627,7761099511627776

Usage Examples

Monitor All Buckets for Quota Violations

# Get all buckets with quota status
curl https://your-api.com/api/apps/my-app/storage/buckets/ \
-H "Authorization: Bearer YOUR_TOKEN" \
| jq '.results[] | select(.quota_exceeded == true) | {
name: .name,
quota_exceeded: .quota_exceeded,
percent_used: .quota_status.percent_used
}'

Output:

{
"name": "Documents",
"quota_exceeded": true,
"percent_used": {
"size": 120.0,
"objects": 113.4
}
}

Check Quota Before Upload (Client-Side)

// Fetch bucket quota status
const response = await fetch(
'https://your-api.com/api/apps/my-app/storage/buckets/user-avatars/',
{
headers: {
'Authorization': `Bearer ${token}`
}
}
);

const bucket = await response.json();

// Check if quota would be exceeded
const fileSize = uploadFile.size; // bytes
const currentUsage = bucket.usage.total_size;
const maxSize = bucket.max_size_bytes;

if (maxSize && (currentUsage + fileSize) > maxSize) {
console.warn('⚠️ Upload would exceed quota');
// Show warning to user (but upload is still allowed)
}

Set Dynamic Quota Based on Usage

# Get current usage
CURRENT_MB=$(curl -s https://your-api.com/api/apps/my-app/storage/buckets/media/usage/ \
-H "Authorization: Bearer YOUR_TOKEN" \
| jq -r '.usage.size_mb')

# Set quota to 1.5x current usage (50% headroom)
NEW_QUOTA=$(echo "$CURRENT_MB * 1.5 * 1024 * 1024" | bc | cut -d'.' -f1)

curl -X PATCH \
https://your-api.com/api/apps/my-app/storage/buckets/media/ \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d "{\"max_size_bytes\": $NEW_QUOTA}"

Best Practices

1. Set Appropriate Quotas

# User-generated content (avatars, profiles)
# Recommended: 1-5GB per bucket
{
"max_size_bytes": 5368709120, // 5GB
"max_objects": 10000
}

# Document storage
# Recommended: 10-100GB per bucket
{
"max_size_bytes": 53687091200, // 50GB
"max_objects": 50000
}

# Media files (videos, large images)
# Recommended: 100GB-1TB per bucket
{
"max_size_bytes": 107374182400, // 100GB
"max_objects": 5000
}

2. Monitor Quota Usage

Check buckets approaching quota limit (>80%):

curl https://your-api.com/api/apps/my-app/storage/buckets/ \
-H "Authorization: Bearer YOUR_TOKEN" \
| jq '.results[] |
select(.quota_status != null) |
select(.quota_status.percent_used.size > 80) |
{
name: .name,
percent_used: .quota_status.percent_used.size,
status: (if .quota_exceeded then "EXCEEDED" else "WARNING" end)
}'

3. Use Dedicated Usage Endpoint

For monitoring and analytics, use the /usage/ endpoint instead of the standard bucket endpoint:

# ✅ Better for monitoring (focused data)
GET /api/apps/{app_slug}/storage/buckets/{slug}/usage/

# ⚠️ Less efficient for monitoring (includes all bucket fields)
GET /api/apps/{app_slug}/storage/buckets/{slug}/

4. Understand Counter Updates

  • Usage counters are updated by the management command check_storage_quotas
  • Counters are stored in the database for fast retrieval
  • Data may be stale between command runs (check last_updated field)
  • Recommended to run the command daily or as needed for your use case

5. Quota as Monitoring, Not Blocking

Important: Quotas are for monitoring and alerting only. They do not block uploads.

  • Users can still upload files even when quota is exceeded
  • Use quota_exceeded flag to show warnings/notifications
  • Implement client-side warnings before upload
  • Set up backend alerts for quota violations

Integration Examples

React Component

function BucketQuotaStatus({ bucketSlug }) {
const [status, setStatus] = useState(null);

useEffect(() => {
fetch(`/api/apps/my-app/storage/buckets/${bucketSlug}/usage/`, {
headers: { 'Authorization': `Bearer ${token}` }
})
.then(res => res.json())
.then(data => setStatus(data));
}, [bucketSlug]);

if (!status?.bucket.has_quota) return null;

return (
<div className="quota-status">
<h3>Storage Usage</h3>
<ProgressBar
value={status.percent_used.size}
max={100}
variant={status.exceeded.any ? 'danger' : 'success'}
/>
<p>
{status.usage.size_gb} GB / {status.quota.max_size_gb} GB
({status.percent_used.size}%)
</p>
{status.exceeded.any && (
<Alert variant="warning">
⚠️ Storage quota exceeded by {status.overage.size_gb} GB
</Alert>
)}
</div>
);
}

Python/Django

from cloud_site.storage.models import Bucket
from cloud_site.storage.quota_service import QuotaService

# Set quota
bucket = Bucket.objects.get(slug='user-avatars')
bucket.max_size_bytes = 10 * 1024 * 1024 * 1024 # 10GB
bucket.max_objects = 1000
bucket.save()

# Check quota status
status = QuotaService.get_bucket_quota_status(bucket)

if status['exceeded']['any']:
print(f"⚠️ Quota exceeded!")
print(f"Overage: {status['overage']['size_mb']} MB")
# Send notification, log event, etc.

# Pre-upload check
file_size = 5 * 1024 * 1024 # 5MB
check = QuotaService.can_add_object(bucket, file_size)

if not check['can_add']:
print(f"⚠️ Upload would exceed quota")

Support

For questions or issues with storage quotas, please refer to: