DEV Community

Cover image for How to Optimize PrestaShop Images Using ShortPixel Optimizer CLI
Bianca Rus
Bianca Rus

Posted on • Edited on

How to Optimize PrestaShop Images Using ShortPixel Optimizer CLI

If you run a PrestaShop store of any meaningful size, you already know the pain: the images folder quietly grows into gigabytes of JPGs and PNGs, Lighthouse yells at you about LCP, and every "optimize images" module either wants a subscription, a cron job you can't see, or both. At some point, image optimization stops being a "nice to have" and turns into a real performance bottleneck.

I wanted something I could drop onto the server over SSH, point at img/, and walk away. So I've been using ShortPixel Optimizer CLI, a single bash script from ShortPixel that batch-optimizes images via the ShortPixel API. No Node, no PHP module, no Composer. Just bash and curl. There are other ways to do this (PrestaShop modules, external SaaS tools, desktop apps), but I wanted something simple, scriptable, server-side and inexpensive.

This post walks through how I use it specifically on PrestaShop: what to point it at, how to handle the multi-resolution thumbnail tree, how to convert everything to WebP/AVIF, and how to schedule it so new product images get optimized automatically.

Why ShortPixel Optimizer CLI for PrestaShop specifically

PrestaShop's image pipeline is… a lot. For every product image you upload, PrestaShop generates a fan of resized copies, cart_default, home_default, large_default, medium_default, and whatever custom types your theme adds. They all live under img/p/ in a sharded directory tree (img/p/1/2/3/123-large_default.jpg and so on).

A good PrestaShop module can optimize these as they're generated. But if you're inheriting a store with 40,000 existing product images that were never optimized, you don't want to re-upload anything, you want to sweep the whole img/ tree in one pass. That's where a CLI tool earns its keep.

ShortPixel Optimizer CLI is built for exactly that shape of problem:

  • It walks directories recursively.
  • It keeps a per-folder state file (.splog) so re-runs skip already-optimized images.
  • It mirrors originals to a backup tree before touching anything.
  • It runs multiple workers in parallel via a FIFO semaphore.
  • It prints (and optionally emails) an analytics dashboard on exit.

And the dependency list is literally bash and curl. On a stock shared host where you can't apt install things, this matters.

Installation

SSH into your server and clone the repo somewhere outside the webroot:

cd ~
git clone https://github.com/short-pixel-optimizer/shortpixel-sh.git
cd shortpixel-sh
chmod +x shortpixel-optimize.sh
Enter fullscreen mode Exit fullscreen mode

First run triggers an interactive wizard that writes a .env file. It asks for your ShortPixel API key, compression level, worker count, backup directory, and optionally an email for reports. Hit Enter through the defaults if you want, they're sensible.

If you'd rather skip the wizard (e.g. you're scripting the install), just create .env yourself:

API_KEY=your_shortpixel_key_here
LOSSY=1                    # 0=lossless, 1=lossy, 2=glossy
CONCURRENCY=4
BACKUP_DIR=/home/youruser/sp-backups
EMAIL=ops@yourshop.com
Enter fullscreen mode Exit fullscreen mode

The first big sweep

Assuming your PrestaShop install is at /var/www/yourshop, the interesting folder is /var/www/yourshop/img. Before you let a script loose on it, make a snapshot backup — yes, the tool keeps its own backups, but belt-and-suspenders with production images is free.

Then a dry initial run on a subset to make sure everything's wired up:

./shortpixel-optimize.sh -j 4 /var/www/yourshop/img/c
Enter fullscreen mode Exit fullscreen mode

img/c is the category images folder — small, finite, a good smoke test. You'll see a progress line and, on exit, a dashboard with counts and savings in MB/GB.

If that looks healthy, go for the whole tree:

./shortpixel-optimize.sh -j 4 /var/www/yourshop/img
Enter fullscreen mode Exit fullscreen mode

A few notes on flags for the PrestaShop case:

  • -j 4, four parallel workers. The script uses a FIFO as a semaphore, so workers block cleanly when the pool is full.
  • No --overwrite on the first run. By default, optimized files land in an optimized/ subfolder next to each source directory, which lets you spot-check before committing. When you're confident, re-run with --overwrite to replace originals in place. (Backups still happen either way.)
  • .splog files will appear inside each processed directory. They're a pipe-delimited record of what got optimized, hash, filename, original size, optimized size, savings percentage, timestamp. Re-runs skip anything already listed there, so you can Ctrl-C mid-sweep and resume later with no wasted API credits.

Converting the whole catalog to WebP

This is the one that actually moves Lighthouse scores. WebP alone can cut image weight by 40–60% on most product catalogs, and ShortPixel can emit WebP/AVIF alongside (or instead of) the optimized original:

./shortpixel-optimize.sh \
  -k YOUR_API_KEY \
  -l 1 \
  --convertto +webp \
  -j 4 \
  /var/www/yourshop/img
Enter fullscreen mode Exit fullscreen mode

The +webp syntax tells ShortPixel to add WebP versions. You'll want your PrestaShop theme (or an .htaccess/nginx rule) to actually serve them, that part is outside the script's job, but a standard content-negotiation rewrite on Accept: image/webp does the trick:

location ~* ^/img/.+\.(jpe?g|png)$ {
    add_header Vary Accept;
    try_files $uri$webp_suffix $uri =404;
}
Enter fullscreen mode Exit fullscreen mode

…with $webp_suffix set based on the Accept header in your http {} block. (There are plenty of snippets for this; point is, once you have .webp siblings on disk, serving them is a config problem, not a generation problem.)

Automating with cron

This is the part most store owners actually want: new product images get optimized automatically, without anyone remembering to run anything.

Because .splog skips already-optimized files, you can run the sweep on a schedule and it'll only burn credits on genuinely new images. Add to your crontab:

# Every night at 03:17, optimize any new images in the shop
17 3 * * * cd /home/youruser/shortpixel-sh && ./shortpixel-optimize.sh --overwrite -j 4 /var/www/yourshop/img >> /var/log/shortpixel.log 2>&1
Enter fullscreen mode Exit fullscreen mode

Two things worth knowing about cron mode:

  • The onboarding wizard skips itself automatically when there's no TTY attached, so cron won't hang on a prompt.
  • If you set EMAIL= in .env, the dashboard gets mailed after each run. The script auto-detects mail or sendmail; if neither is on the box, set MAIL_CMD= explicitly.

I like the email report because it's a passive health check, if one night's run suddenly shows zero files processed, I know something's up (API key expired, disk full, whatever) without having to tail a log.

When things go wrong: backup and restore

The script mirrors every original to BACKUP_DIR before the API call, and verifies the backup exists and is non-zero before touching anything. If the backup verification fails, the source is skipped and flagged as an error, your original is never at risk.

If an optimization run produces results you don't like (too aggressive, visible artifacts on product photos, whatever), roll back the whole tree:

./shortpixel-optimize.sh --restore /var/www/yourshop/img
Enter fullscreen mode Exit fullscreen mode

That copies every backed-up original back to its source location, writes a restore_audit.log, and wipes the .splog files so the next run treats everything as fresh.

For storage hygiene, purge old backups once you're confident in the results:

./shortpixel-optimize.sh --purge-backups 30 /var/www/yourshop/img
Enter fullscreen mode Exit fullscreen mode

This only deletes backup files that are both older than 30 days and have a corresponding .splog entry, so anything that failed or was skipped stays safe.

What I'd actually do on a new client store

Putting it together, my first-day playbook for a neglected PrestaShop install looks like this:

  1. Clone the repo, run the wizard, set LOSSY=1 and an email.
  2. Snapshot img/ at the filesystem level (rsync, LVM, whatever).
  3. Smoke test on img/c without --overwrite.
  4. Full sweep on img/ with --overwrite --convertto +webp -j 4.
  5. Add the nginx/Apache rule to serve .webp to browsers that accept it.
  6. Drop a nightly cron that re-runs the same command.
  7. After two weeks of clean runs, --purge-backups 14.

Total hands-on time is maybe 20 minutes, and the only ongoing cost is ShortPixel API credits on new uploads. No module to update, no dashboard to log into, nothing in the PrestaShop admin to break on the next minor version. If you're dealing with a bloated PrestaShop install, this is one of the fastest wins you can get without touching the frontend.

ShortPixel Optimizer CLI can be found here. Help is comprehensive if you want to dig into the less common flags (custom output dirs, extension exclusions, lossless mode for line art, etc.).

Top comments (0)