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
| Method | Endpoint | Description |
|---|---|---|
| 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)
| Field | Type | Writable | Description |
|---|---|---|---|
max_size_bytes | integer/null | ✅ Yes | Maximum total storage size in bytes (null = no limit) |
max_size_mb | float/null | ❌ No | Maximum size in MB (computed from max_size_bytes) |
max_size_gb | float/null | ❌ No | Maximum size in GB (computed from max_size_bytes) |
max_objects | integer/null | ✅ Yes | Maximum number of objects (null = no limit) |
quota_exceeded | boolean | ❌ No | Flag indicating if bucket has exceeded quota |
usage | object | ❌ No | Current usage statistics (computed) |
quota_status | object/null | ❌ No | Comprehensive 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_bytesmust be a positive integer (> 0)max_objectsmust be a positive integer (> 0)- Both fields can be set to
nullto 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:
| Size | Bytes | JSON Value |
|---|---|---|
| 100 MB | 104,857,600 | 104857600 |
| 500 MB | 524,288,000 | 524288000 |
| 1 GB | 1,073,741,824 | 1073741824 |
| 5 GB | 5,368,709,120 | 5368709120 |
| 10 GB | 10,737,418,240 | 10737418240 |
| 50 GB | 53,687,091,200 | 53687091200 |
| 100 GB | 107,374,182,400 | 107374182400 |
| 500 GB | 536,870,912,000 | 536870912000 |
| 1 TB | 1,099,511,627,776 | 1099511627776 |
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_updatedfield) - 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_exceededflag 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")
Related Documentation
- Storage Buckets API - Bucket management
- Storage Objects API - File upload/download
- Storage Quickstart - Getting started guide
- Storage Advanced - Advanced features
Support
For questions or issues with storage quotas, please refer to: