Compress and optimise WordPress images with Linux command-line tools

Image optimisation is one of the highest-impact performance improvements you can make to a WordPress site — unoptimised JPEG and PNG files from cameras or design tools often weigh 2–8MB, while a properly compressed version for web use should be under 200KB for most content images. On a VPS or dedicated server, you can automate image optimisation directly on the command line using free tools: jpegoptim (lossy and lossless JPEG compression), optipng and pngquant (PNG optimisation), cwebp (convert to WebP), and convert from ImageMagick (resize, format conversion, and batch processing). These tools process files in-place or to a target directory, making them ideal for a one-time bulk optimisation of an existing WordPress upload library or as part of a deployment script. Combining find with -exec (as covered in the Linux commands guide) lets you recurse through the entire wp-content/uploads/ directory and process every image in a single command. For new uploads, either use a WordPress plugin (Imagify, ShortPixel, Smush) or set up an inotifywait-based watcher. The WebP conversion approach complements the WebP serving guide and together they represent a complete server-side image optimisation workflow.

Problem: Your WordPress wp-content/uploads/ directory contains unoptimised images that are slowing down page load times and you want to compress them in bulk from the command line.

Solution: Run the following commands via SSH on your server:

# ── Install tools (Ubuntu / Debian) ──────────────────────────────────────────
sudo apt update
sudo apt install -y jpegoptim optipng pngquant webp imagemagick

# ── Bulk optimise all JPEGs under uploads/ (max quality 85, strip metadata) ──
find /var/www/html/helloadmin/wp-content/uploads/ -type f \( -iname "*.jpg" -o -iname "*.jpeg" \)   -exec jpegoptim --max=85 --strip-all --quiet {} \;

# ── Bulk optimise all PNGs (lossless, up to 7 compression passes) ─────────────
find /var/www/html/helloadmin/wp-content/uploads/ -type f -iname "*.png"   -exec optipng -o5 -quiet {} \;

# ── Lossy PNG compression with pngquant (reduces colour depth, much smaller) ──
find /var/www/html/helloadmin/wp-content/uploads/ -type f -iname "*.png"   -exec pngquant --quality=70-85 --ext=.png --force {} \;

# ── Convert all JPEGs to WebP (quality 82, keep originals) ───────────────────
find /var/www/html/helloadmin/wp-content/uploads/ -type f \( -iname "*.jpg" -o -iname "*.jpeg" \) | while read f; do
    cwebp -q 82 -quiet "$f" -o "${f%.*}.webp"
done

# ── Resize oversized images to max 1920px wide with ImageMagick ───────────────
find /var/www/html/helloadmin/wp-content/uploads/ -type f \( -iname "*.jpg" -o -iname "*.jpeg" \)   -exec convert {} -resize '1920x>' -quality 85 {} \;

# ── Check total savings: before and after sizes ───────────────────────────────
du -sh /var/www/html/helloadmin/wp-content/uploads/

# ── Run as a one-liner cron job every night at 2 AM ──────────────────────────
# 0 2 * * * find /var/www/.../uploads/ -mtime -1 -iname "*.jpg" -exec jpegoptim --max=85 --strip-all {} \;

NOTE: Run jpegoptim and optipng on a staging copy of your uploads directory first — lossy compression is irreversible and quality settings are subjective. A quality setting of 85 for JPEG is a good balance between file size and visual quality for blog images; go to 80 for even smaller files or 90 for photography. Always keep a backup before bulk-processing the production uploads/ folder. The -mtime -1 flag in the cron example restricts processing to files modified in the last 24 hours — essential for not re-processing the entire library on every run.