Reader Stacks

Compressing and Reducing Image Size on Upload in Laravel

Compression and resizing are two genuinely separate optimizations that Intervention Image happens to handle in the same fluent chain — applying both together is what typically produces the biggest file-size reduction.

Compressing and Reducing Image Size on Upload in Laravel

Storing an uploaded image at its original size and quality wastes both storage space and bandwidth — the intervention/image package is the standard way to compress and resize an image during upload in Laravel.

Installing Intervention Image

composer require intervention/image

Compressing an image's quality without resizing it

use Intervention\Image\Laravel\Facades\Image;

public function store(Request $request)
{
    $request->validate(['image' => 'required|image|max:5120']);

    $image = Image::read($request->file('image'));

    $filename = uniqid().'.jpg';
    $image->toJpeg(quality: 75)->save(storage_path('app/public/products/'.$filename));

    Product::create(['image' => 'products/'.$filename]);
}

quality: 75 (on a 0–100 scale) is a commonly used middle ground — noticeably reducing file size with minimal visible quality loss for most photographic content, though the ideal value genuinely depends on the specific images and how much quality loss is acceptable for the use case.

Resizing an image, in addition to compressing it

$image = Image::read($request->file('image'));

$image->scale(width: 1200); // resize, preserving aspect ratio

$filename = uniqid().'.jpg';
$image->toJpeg(quality: 80)->save(storage_path('app/public/products/'.$filename));

scale() resizes proportionally based on just one dimension, automatically calculating the other to preserve the original aspect ratio — combining this with quality compression is what typically produces the largest overall file-size reduction, since an oversized original image (say, 4000px wide from a phone camera) rarely needs to display at anywhere near that resolution on a web page.

Converting to WebP for further size reduction

$image->toWebp(quality: 80)->save(storage_path('app/public/products/'.$filename.'.webp'));

WebP typically produces meaningfully smaller file sizes than an equivalent-quality JPEG — worth using specifically when target browser support for WebP is confirmed acceptable for the application's actual user base.

Checking the actual size reduction achieved

$originalSize = $request->file('image')->getSize();
$compressedSize = filesize(storage_path('app/public/products/'.$filename));

$savingsPercent = round((1 - $compressedSize / $originalSize) * 100);

Why this should happen server-side, not just rely on client-side compression

A malicious or simply unusual client could bypass any client-side compression logic (like a JavaScript canvas-based resize) entirely and send an unoptimized original file directly to the endpoint — server-side compression, applied unconditionally to every upload regardless of what the client claims to have already done, is the only genuinely reliable way to guarantee stored images stay within a consistent size and quality target.

A performance consideration for high-volume uploads

Image processing (resizing and re-encoding) is CPU-intensive — for an application handling a high volume of uploads, dispatching the actual compression work to a queued job rather than processing it synchronously during the request keeps the upload response fast, deferring the heavier processing to a background worker instead.