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_objects": 234,
"size_mb": 2304.0,
"size_gb": 2.25,
"last_updated": "2025-01-20T15:30:00Z"
}
Quota Status Object
Only present when bucket has quotas set (max_size_bytes or max_objects).
{
"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
}
}
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)
- REST API
- Python
- JavaScript
curl -X PATCH \
'https://your-site.taruvi.cloud/api/apps/my-app/storage/buckets/user-avatars/' \
-H 'Authorization: Bearer YOUR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"max_size_bytes": 10737418240
}'
import requests
response = requests.patch(
"https://your-site.taruvi.cloud/api/apps/my-app/storage/buckets/user-avatars/",
headers={
"Authorization": "Bearer YOUR_TOKEN",
"Content-Type": "application/json",
},
json={"max_size_bytes": 10737418240}
)
result = response.json()
const response = await fetch(
"https://your-site.taruvi.cloud/api/apps/my-app/storage/buckets/user-avatars/",
{
method: "PATCH",
headers: {
"Authorization": "Bearer YOUR_TOKEN",
"Content-Type": "application/json",
},
body: JSON.stringify({ max_size_bytes: 10737418240 }),
}
);
const result = await response.json();
Set Object Count Quota (1000 files)
- REST API
- Python
- JavaScript
curl -X PATCH \
'https://your-site.taruvi.cloud/api/apps/my-app/storage/buckets/documents/' \
-H 'Authorization: Bearer YOUR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"max_objects": 1000
}'
import requests
response = requests.patch(
"https://your-site.taruvi.cloud/api/apps/my-app/storage/buckets/documents/",
headers={
"Authorization": "Bearer YOUR_TOKEN",
"Content-Type": "application/json",
},
json={"max_objects": 1000}
)
result = response.json()
const response = await fetch(
"https://your-site.taruvi.cloud/api/apps/my-app/storage/buckets/documents/",
{
method: "PATCH",
headers: {
"Authorization": "Bearer YOUR_TOKEN",
"Content-Type": "application/json",
},
body: JSON.stringify({ max_objects: 1000 }),
}
);
const result = await response.json();
Set Both Quotas (10GB + 1000 files)
- REST API
- Python
- JavaScript
curl -X PATCH \
'https://your-site.taruvi.cloud/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
}'
import requests
response = requests.patch(
"https://your-site.taruvi.cloud/api/apps/my-app/storage/buckets/media/",
headers={
"Authorization": "Bearer YOUR_TOKEN",
"Content-Type": "application/json",
},
json={
"max_size_bytes": 10737418240,
"max_objects": 1000,
}
)
result = response.json()
const response = await fetch(
"https://your-site.taruvi.cloud/api/apps/my-app/storage/buckets/media/",
{
method: "PATCH",
headers: {
"Authorization": "Bearer YOUR_TOKEN",
"Content-Type": "application/json",
},
body: JSON.stringify({
max_size_bytes: 10737418240,
max_objects: 1000,
}),
}
);
const result = await response.json();
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.
- REST API
- Python
- JavaScript
curl https://your-site.taruvi.cloud/api/apps/my-app/storage/buckets/user-avatars/ \
-H "Authorization: Bearer YOUR_TOKEN"
import requests
response = requests.get(
"https://your-site.taruvi.cloud/api/apps/my-app/storage/buckets/user-avatars/",
headers={"Authorization": "Bearer YOUR_TOKEN"}
)
bucket = response.json()
const response = await fetch(
"https://your-site.taruvi.cloud/api/apps/my-app/storage/buckets/user-avatars/",
{ headers: { "Authorization": "Bearer YOUR_TOKEN" } }
);
const bucket = await response.json();
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
- REST API
- Python
- JavaScript
curl https://your-site.taruvi.cloud/api/apps/my-app/storage/buckets/user-avatars/usage/ \
-H "Authorization: Bearer YOUR_TOKEN"
import requests
response = requests.get(
"https://your-site.taruvi.cloud/api/apps/my-app/storage/buckets/user-avatars/usage/",
headers={"Authorization": "Bearer YOUR_TOKEN"}
)
usage = response.json()
const response = await fetch(
"https://your-site.taruvi.cloud/api/apps/my-app/storage/buckets/user-avatars/usage/",
{ headers: { "Authorization": "Bearer YOUR_TOKEN" } }
);
const usage = await response.json();
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,
"objects": true,
"any": true
},
"percent_used": {
"size": 120.0,
"objects": 113.4
},
"overage": {
"size_bytes": 1073741824,
"size_mb": 1024.0,
"objects": 67
}
}
Removing Quotas
Set quota fields to null to remove limits.
Remove All Quotas
- REST API
- Python
- JavaScript
curl -X PATCH \
'https://your-site.taruvi.cloud/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
}'
import requests
response = requests.patch(
"https://your-site.taruvi.cloud/api/apps/my-app/storage/buckets/user-avatars/",
headers={
"Authorization": "Bearer YOUR_TOKEN",
"Content-Type": "application/json",
},
json={
"max_size_bytes": None,
"max_objects": None,
}
)
result = response.json()
const response = await fetch(
"https://your-site.taruvi.cloud/api/apps/my-app/storage/buckets/user-avatars/",
{
method: "PATCH",
headers: {
"Authorization": "Bearer YOUR_TOKEN",
"Content-Type": "application/json",
},
body: JSON.stringify({
max_size_bytes: null,
max_objects: null,
}),
}
);
const result = await response.json();
Remove Size Quota Only
- REST API
- Python
- JavaScript
curl -X PATCH \
'https://your-site.taruvi.cloud/api/apps/my-app/storage/buckets/user-avatars/' \
-H 'Authorization: Bearer YOUR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"max_size_bytes": null
}'
import requests
response = requests.patch(
"https://your-site.taruvi.cloud/api/apps/my-app/storage/buckets/user-avatars/",
headers={
"Authorization": "Bearer YOUR_TOKEN",
"Content-Type": "application/json",
},
json={"max_size_bytes": None}
)
result = response.json()
const response = await fetch(
"https://your-site.taruvi.cloud/api/apps/my-app/storage/buckets/user-avatars/",
{
method: "PATCH",
headers: {
"Authorization": "Bearer YOUR_TOKEN",
"Content-Type": "application/json",
},
body: JSON.stringify({ max_size_bytes: null }),
}
);
const result = await response.json();
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
- REST API
- Python
- JavaScript
# Get all buckets with quota status
curl https://your-site.taruvi.cloud/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
}
}
import requests
response = requests.get(
"https://your-site.taruvi.cloud/api/apps/my-app/storage/buckets/",
headers={"Authorization": "Bearer YOUR_TOKEN"}
)
buckets = response.json()["results"]
# Find buckets that have exceeded their quotas
exceeded = [b for b in buckets if b.get("quota_exceeded")]
for bucket in exceeded:
print(f"Bucket: {bucket['name']}")
print(f" Size used: {bucket['quota_status']['percent_used']['size']}%")
print(f" Objects used: {bucket['quota_status']['percent_used']['objects']}%")
const response = await fetch(
"https://your-site.taruvi.cloud/api/apps/my-app/storage/buckets/",
{ headers: { "Authorization": "Bearer YOUR_TOKEN" } }
);
const { results: buckets } = await response.json();
// Find buckets that have exceeded their quotas
const exceeded = buckets.filter((b: any) => b.quota_exceeded);
exceeded.forEach((bucket: any) => {
console.log(`Bucket: ${bucket.name}`);
console.log(` Size used: ${bucket.quota_status.percent_used.size}%`);
console.log(` Objects used: ${bucket.quota_status.percent_used.objects}%`);
});
Check Quota Before Upload (Client-Side)
- REST API
- Python
- JavaScript
# Get bucket details to check quota
curl https://your-site.taruvi.cloud/api/apps/my-app/storage/buckets/user-avatars/ \
-H "Authorization: Bearer YOUR_TOKEN"
import requests
response = requests.get(
"https://your-site.taruvi.cloud/api/apps/my-app/storage/buckets/user-avatars/",
headers={"Authorization": "Bearer YOUR_TOKEN"}
)
bucket = response.json()
# Check if quota would be exceeded
file_size = 5 * 1024 * 1024 # 5MB
current_usage = bucket["usage"]["total_size"]
max_size = bucket["max_size_bytes"]
if max_size and (current_usage + file_size) > max_size:
print("Warning: Upload would exceed quota")
# Show warning to user (but upload is still allowed)
// Fetch bucket quota status
const response = await fetch(
"https://your-site.taruvi.cloud/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
- REST API
- Python
- JavaScript
# Get current usage
CURRENT_MB=$(curl -s https://your-site.taruvi.cloud/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-site.taruvi.cloud/api/apps/my-app/storage/buckets/media/ \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d "{\"max_size_bytes\": $NEW_QUOTA}"
import requests
# Get current usage
response = requests.get(
"https://your-site.taruvi.cloud/api/apps/my-app/storage/buckets/media/usage/",
headers={"Authorization": "Bearer YOUR_TOKEN"}
)
usage = response.json()
current_mb = usage["usage"]["size_mb"]
# Set quota to 1.5x current usage (50% headroom)
new_quota = int(current_mb * 1.5 * 1024 * 1024)
requests.patch(
"https://your-site.taruvi.cloud/api/apps/my-app/storage/buckets/media/",
headers={
"Authorization": "Bearer YOUR_TOKEN",
"Content-Type": "application/json",
},
json={"max_size_bytes": new_quota}
)
// Get current usage
const usageResponse = await fetch(
"https://your-site.taruvi.cloud/api/apps/my-app/storage/buckets/media/usage/",
{ headers: { "Authorization": "Bearer YOUR_TOKEN" } }
);
const usage = await usageResponse.json();
const currentMb = usage.usage.size_mb;
// Set quota to 1.5x current usage (50% headroom)
const newQuota = Math.floor(currentMb * 1.5 * 1024 * 1024);
await fetch(
"https://your-site.taruvi.cloud/api/apps/my-app/storage/buckets/media/",
{
method: "PATCH",
headers: {
"Authorization": "Bearer YOUR_TOKEN",
"Content-Type": "application/json",
},
body: JSON.stringify({ max_size_bytes: newQuota }),
}
);
Best Practices
1. Set Appropriate Quotas
// User-generated content (avatars, profiles)
// Recommended: 1-5GB per bucket
{
"max_size_bytes": 5368709120,
"max_objects": 10000
}
// Document storage
// Recommended: 10-100GB per bucket
{
"max_size_bytes": 53687091200,
"max_objects": 50000
}
// Media files (videos, large images)
// Recommended: 100GB-1TB per bucket
{
"max_size_bytes": 107374182400,
"max_objects": 5000
}
2. Monitor Quota Usage
Check buckets approaching quota limit (>80%):
- REST API
- Python
- JavaScript
curl https://your-site.taruvi.cloud/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)
}'
import requests
response = requests.get(
"https://your-site.taruvi.cloud/api/apps/my-app/storage/buckets/",
headers={"Authorization": "Bearer YOUR_TOKEN"}
)
buckets = response.json()["results"]
# Find buckets approaching quota limit (>80%)
for bucket in buckets:
status = bucket.get("quota_status")
if status and status["percent_used"].get("size", 0) > 80:
label = "EXCEEDED" if bucket["quota_exceeded"] else "WARNING"
print(f"[{label}] {bucket['name']}: {status['percent_used']['size']}% used")
const response = await fetch(
"https://your-site.taruvi.cloud/api/apps/my-app/storage/buckets/",
{ headers: { "Authorization": "Bearer YOUR_TOKEN" } }
);
const { results: buckets } = await response.json();
// Find buckets approaching quota limit (>80%)
buckets.forEach((bucket: any) => {
const status = bucket.quota_status;
if (status && status.percent_used?.size > 80) {
const label = bucket.quota_exceeded ? "EXCEEDED" : "WARNING";
console.log(`[${label}] ${bucket.name}: ${status.percent_used.size}% used`);
}
});
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: