Optimize the size of .PNG images automatically on your webserver with optipng

Tired of the privacy invasion of the Chrome webbrowser? Worried about the risk of seeing ads everywhere? Give the Brave Browser a try. It supports all the same Chrome extensions, with none of the telemetry. It auto-blocks ads and helps support content creators like me.

Give the Brave browser a try »

Profile image of Mattias Geniar

Mattias Geniar, March 27, 2016

Follow me on Twitter as @mattiasgeniar

A couple of weeks ago I write a blogpost on the technical aspects of SEO. One of the readers translated it into French and reported an additional tip: my images in that post were way too big.

François was even kind enough to include a screenshot with the savings I missed out on.


I used to have a workflow where I ran every image through ImageOptim to compress them as much as possible. But it’s a manual step that’s too easy to ignore.

So here’s a way to automate it. These couple of scripts automatically run and compress your files for you, so you don’t have to think about them ever again. They use the optipng tool in the background.

Why even do this?

Now, normally, optimizing images is part of the build or release process. Before your images even hit your servers, they’re in its most optimal form. However, reality isn’t always that easy. If you run a dynamic site like WordPress or Drupal, anyone can upload images and they don’t necessarily have the same requirements for images like you do.

This technique catches those uploads, encodes them in a better format and nobody notices.

Nobody but you: your server uses less bandwidth and consumes less disk space. This technique also processes asynchronously: there is no delay in the uploads, images are processing a while after they’re uploaded.

Install optipng

You start by installing the optipng tool.

On Red Hat or CentOS:

$ yum install optipng

On Ubuntu / Debian:

$ apt-get install optipng

Now, let’s automate this.

Automatically optimise your new images every hour

Friendly reminder: before running any of these tools, make sure you have a back-up to restore from!

Update: just to very clear, this only optimises new images. It searches for them, every hour, and processes them. It does not keep processing the same images over and over. The search hardly demands any server resources.

The optipng tool itself works pretty simple. The most basic command is optipng image.png, which optimises the image called ‘image.png’ and replaces it on your server (so you lose the original!).

We can add some additional parameters that further reduce the size, increase the compression ratio and strip all META info from the PNG file you don’t need. Here’s my current command for the most optimal size.

$ optipng -o7 -f4 -strip all -quiet image.png

This takes the file called ‘image.png’, runs all sorts of optimisations over it, strips meta data and overwrites the file with the new and improved version.

Now, to run this automatically on your server, all you need is the following cronjob. Let this run every hour, and it’ll take all PNG files created in the last hour and optimises them for you.

$ find htdocs/wp-content/ -mmin -60 -name '*.png' -print0 | xargs -0 optipng -o7 -f4 -strip all -quiet -preserve

This essentially does these things:

  1. Find all *.png files in the ‘htdocs/wp-content’ directory that were created in the last hour (this is the directory where WordPress uploads its content)
  2. For each of those found files, run the optipng command on them

Add that to your crontab and you never have to think about it again.

$ crontab -l
0 * * * * find ~/htdocs/wp-content/ -mmin -60 -name '*.png' -print0 | xargs -0 optipng -o7 -f4 -strip all -quiet -preserve

All done!

Optimise all your existing images

If you’re only thinking about activating this after you have a bunch of files, you may want to run this tool over all your images – not just the ones modified in the last hour.

I’ll repeat myself, but here it goes: before you run this over all your files, have a back-up! These settings replace the original file, so you no longer have the original.

$ find ~/htdocs/wp-content/ -name '*.png' -print0 | xargs -0 optipng -o7 -f4 -strip all -quiet -preserve

That command searches for all ‘*.png’ files in the ~/htdocs/wp-content/ folder and runs the optipng command over all of them.

Want to subscribe to the cron.weekly newsletter?

I write a weekly-ish newsletter on Linux, open source & webdevelopment called cron.weekly.

It features the latest news, guides & tutorials and new open source projects. You can sign up via email below.

No spam. Just some good, practical Linux & open source content.