DEV Community

JOHN MWACHARO
JOHN MWACHARO

Posted on

πŸ“¦ Best Practices for File Uploads in Laravel

βœ… 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)