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.