β
1. Organize Files with Subdirectories
Avoid dumping everything into /storage/app/uploads.
Use date-based or hash-based structures:
storage/app/leave/documents/2024/06/filename.pdf
storage/app/uploads/a1/b2/filename.jpg
β
2. Use Laravelβs Storage Facade
This abstracts filesystem logic and supports multiple disks:
Storage::put('leave/documents/filename.pdf', $fileContent);
Supports:
Local
S3
DigitalOcean
Dropbox
FTP/SFTP
Set default in config/filesystems.php.
β 3. Use Spatie MediaLibrary for Complex Needs
$model->addMedia($request->file('photo'))->toMediaCollection('profile_photos');
Get:
Versioning
Multi-disk support
Model linking
Image conversions
β
4. Offload to Cloud (for Scale)
βοΈ Cloud Storage Options & Cost Comparison
`
`
| Provider | Free Tier | Paid Tier | Pros | Best For |
| ----------------------- | ---------------------------- | ------------------------------------ | --------------------------- | ------------------------------ |
| Amazon S3 | 5GB + 20K GETs/month | \$0.023/GB + request fees | Highly scalable, reliable | Enterprise systems |
| DigitalOcean Spaces | No free tier | \$5/month for 250GB + 1TB transfer | Flat pricing, S3-compatible | Laravel apps, growing startups |
| Dropbox (API) | ~2GB free on personal plans | \$15/user/month (business unlimited) | Simple, fast setup | Dev tools, personal projects |
| Backblaze B2 | 10GB free + 1GB download/day | \$0.005/GB stored, \$0.01/GB egress | Cheapest overall, S3 API | Budget solutions |
| Wasabi | No egress fees | \$6.99/month for 1TB (3-month min) | Unlimited downloads | Video-heavy or backup apps |
`
`
β
5. Secure Your Files
Never expose storage/app directly.
S3: Use temporary signed URLs:
Storage::disk('s3')->temporaryUrl('file.pdf', now()->addMinutes(5));
Local: Serve via a controller:
if (Auth::user()->can('view', $file)) {
return response()->file(storage_path("app/leave/$file"));
}
β
6. Use Queues for Heavy Work
Avoid doing this during the HTTP request:
PDF generation
Image conversion
Malware scanning
Instead:
dispatch(new ProcessMediaJob($file));
β
7. Validate & Sanitize Everything
$request->validate([
'document' => 'required|file|mimes:pdf,jpg,png|max:2048',
]);
Prevent:
Malicious files
Path traversal
Storage abuse
β
8. Monitor Disk Usage
Set up a daily cron:
php artisan schedule:run
Use Storage::size() to log large files or send alerts.
π¬ Final Takeaway
If a simple chmod issue can break uploads for a month, imagine the risk when youβre dealing with hundreds of users and gigabytes of uploads.
By using proper Laravel abstractions, secure patterns, and cloud storage smartly, you avoid:
Downtime
Data loss
Scaling nightmares
β
My New Upload Strategy
Use Laravel's Storage facade only
Auto-organize files by date
Offload to DigitalOcean Spaces for new environments
Queue image processing jobs
Run weekly disk usage audits
And most importantly β never ignore permission errors again
Top comments (0)