Storage backends
SpeedyFiles supports two storage backends behind a single StorageBackend Protocol: local filesystem (default) and S3-compatible object storage. Switch via env var or per-package.
Local storage (default)
Files live on disk under a configurable root (default /srv/files). Best for:
- Single-server deployments
- When you want bytes to flow through your server (so you can do UDP acceleration, BYO-CDN, etc.)
- Hosting providers where you have local disk but no S3 access
Directory layout
/srv/files/
├── packages/
│ └── <package_id>/ (mode 0700, per-package isolation)
│ └── <file_id>--<sanitized-original-name>
└── tmp/ (atomic-write staging)
Filesystem recommendations
- XFS for large single files (typical media workflow)
- ext4 works fine for most uses
- Mount with
noatime— uploads don't need atime tracking - Separate volume from
/— protects the OS from runaway uploads filling /
Permissions
chown -R speedyfiles:speedyfiles /srv/files
chmod 0750 /srv/files
S3 storage
For multi-server deployments, large data volumes, or when you want object-storage durability guarantees. Compatible with:
- AWS S3
- Wasabi, Backblaze B2, DigitalOcean Spaces, Cloudflare R2
- Self-hosted: MinIO, Garage, SeaweedFS
Configuration
# .env or environment variables
STORAGE_BACKEND=s3
S3_BUCKET=speedyfiles-prod
S3_REGION=us-east-1
S3_PREFIX=packages
# Standard AWS creds via env or ~/.aws/credentials
AWS_ACCESS_KEY_ID=AKIAxxxxxxx
AWS_SECRET_ACCESS_KEY=xxxxxxxxxxxxxxxxxxxxxxxxx
# Optional: custom endpoint for non-AWS providers
# AWS_ENDPOINT_URL=https://<account>.r2.cloudflarestorage.com
How downloads work with S3
Instead of streaming bytes through the SpeedyFiles process, the app generates a 15-minute presigned URL and 302s the recipient to it. Pros:
- Massive bandwidth savings on your app server
- S3's parallel-range downloads are faster than uvicorn streaming
- CDN-friendly (CloudFront, Cloudflare R2 with CF in front)
How uploads work with S3
The app uses S3 multipart upload internally (5 MiB minimum chunks). Bytes flow:
customer → uvicorn → aioboto3 → S3. A future enhancement will issue presigned PUTs so the customer's browser uploads directly to S3; track in issues.
Switching between backends
Set STORAGE_BACKEND=local or STORAGE_BACKEND=s3 in your env. Restart the app. New packages use the new backend. Existing packages keep their backend (the choice is recorded per-package in the DB) — so you can have a hybrid state while migrating.
Disk space monitoring
The admin Settings → Storage page shows free/used space on the local volume, total bytes per package, and a "sweep stale tmp/ files" button. Set up alerting in your monitoring system on df output or expose the /api/v1/admin/storage/stats endpoint to Prometheus / Datadog.