← All tutorials

Performance

How to Automate Image and Video Compression on Ubuntu 24.04 with ImageMagick and FFmpeg

Published October 27, 2026 · 7 min read

On this page
  1. Prerequisites
  2. Step-by-Step Guide
  3. Conclusion

Large images and videos are the most common reason pages load slowly. This guide builds one Bash script that converts images to WebP, re-encodes videos for streaming and optionally uploads results to an Amazon S3 bucket with long-lived cache headers.

Prerequisites

Step-by-Step Guide

Step 1: Install the tools

sudo apt update
sudo apt install -y ffmpeg imagemagick webp
ffmpeg -version | head -n 1

Step 2: Write the optimization script

Save as optimize.sh. Files already converted are skipped, so reruns are fast.

#!/usr/bin/env bash
set -euo pipefail

SRC="${1:?Usage: optimize.sh SOURCE_DIR OUTPUT_DIR}"
OUT="${2:?Usage: optimize.sh SOURCE_DIR OUTPUT_DIR}"
mkdir -p "$OUT"

find "$SRC" -type f \( -iname '*.jpg' -o -iname '*.jpeg' -o -iname '*.png' \) -print0 |
while IFS= read -r -d '' f; do
  name="$(basename "${f%.*}")"
  [ -f "$OUT/$name.webp" ] && continue
  convert "$f" -auto-orient -strip -resize '1600x>' -quality 80 "$OUT/$name.webp"
done

find "$SRC" -type f \( -iname '*.mp4' -o -iname '*.mov' \) -print0 |
while IFS= read -r -d '' f; do
  name="$(basename "${f%.*}")"
  [ -f "$OUT/$name.mp4" ] && continue
  ffmpeg -nostdin -loglevel error -i "$f" \
    -c:v libx264 -crf 23 -preset medium -vf "scale='min(1280,iw)':-2" \
    -c:a aac -b:a 128k -movflags +faststart "$OUT/$name.mp4"
done
echo "Optimization finished."

Step 3: Run it and compare sizes

chmod 750 optimize.sh
./optimize.sh /srv/uploads /srv/optimized
du -sh /srv/uploads /srv/optimized

Step 4: Upload to S3 with cache headers (optional)

aws s3 sync /srv/optimized s3://your-bucket-name/media/ \
  --cache-control "public, max-age=31536000, immutable"

Replace your-bucket-name with your bucket. The one-year immutable header is only safe if a changed file always gets a new name, for example hero-v2.webp.

Step 5: Schedule it

Add this line with crontab -e to run nightly at 02:00:

0 2 * * * /home/ubuntu/optimize.sh /srv/uploads /srv/optimized >> /tmp/optimize.log 2>&1

Adjust the script path to match your user's home directory.

Conclusion

Media is now compressed consistently and ready for a CDN. Keep original files, review the log weekly, keep names unique, and test visual quality on a few samples before bulk conversion.

Keep reading