When Google announced on March 16th that they were releasing a new open source JPEG encoder “that creates high quality JPEG images with file sizes 35% smaller,” I got excited. Like, super excited. Very few companies (if any) have the development resources of a Google, and their incredible reach allows the creation of near-instant standards.

I sent a few slightly tipsy St. Patrick’s day Slack messages asking our dev team what it meant for product images and for Pixelz. Specifically, I wanted to know:

Is quality really better? Are file sizes really smaller? What’s the catch?

The immediate answers were “Maybe,” “It depends,” and “Holy shit, it’s SLOOOOW!”

By “slow,” we found that encoding an image as JPEG via Guetzli can take literally 1000 times as long as our current preferred method, MozJPEG. Encoding that currently takes 2-4 seconds was taking 30 minutes or more in tests. 30 minutes for a single image!

Screenshot of mac osx activity monitor CPU time during google guetzli encoding

Activity Monitor while Guetzli encoding one 48 MPix image, over two hours of real time and 1h32m of CPU time in.

Guetzli was consistently several hundred times slower than MozJPEG, regularly measuring in minutes what MozJPEG did in tenths of a second.

There are a few other significant tradeoffs as well: Guetzli doesn’t support progressive image loading (where images load from blurry to sharp, instead of top to bottom) and only supports sRGB. Using sRGB is a best practice for images on the web, but so is progressive loading. Its absence is a big loss.

Pixelz Verdict: MozJPEG Remains First Choice for Product Images on the Web

  • MozJPEG files had fewer bytes 6 out of 8 times
  • MozJPEG and Guetzli were visually indistinguishable
  • MozJPEG encoded literally hundreds to a thousand times faster than Guetzli
  • MozJPEG supports progressive loading

I had to see it for myself (Could it really be THAT slow? And what about quality?), so I ran more tests on my own lightweight system.

My testing results were the same as our dev team’s, and as I read deeper I saw they mostly aligned with Google’s own documentation. Maybe Google Guetzli just isn’t intended for e-commerce or for use on larger images. Perhaps it’s a proof of concept for psychovisual perceptual encoding rather than a practical tool...

Maybe Guetzli will continue to improve, but the bottom line is that at this time there are better solutions for compressing product images.

A Brief History of JPEG Encoders

Before we dive into the tests, let’s take a quick walk down memory lane to get some context on JPEG encoding. If you don’t care, skip straight to the tests.

JPEG is an image file format that’s been around since the early 1990s, and it uses lossy compression. Ever since its introduction, people have worked on improving the compression algorithms with three different (and sometimes conflicting) goals: speeding up encoding time, increasing quality, and reducing byte size.

The JPEG Tripod: Speed, Quality, Byte Size

Encoding time is how long it takes to compress or decompress a JPEG. For example, if you capture an image in-camera using JPEG as your file format, the time it takes to save your photo is encoding time. When you’re working on an image in Photoshop and select “Save as JPEG,” the time it takes to save your image is encoding time.

Quality is more difficult to quantify. Most compressors let you pick a JPEG quality number from 1-100, but this isn’t actually standardized. Because JPEG is a lossy format, information is lost every time you compress; however, not all information is created equal. Algorithm improvements are usually based around increased knowledge of human visual perception. If the eye doesn’t notice it, why store it?

File byte size is determined by image dimensions, quality, and encoding method. Reducing file size saves on disk space and bandwidth, which provides cost savings while accelerating web page loading speed.

Comparing Current JPEG Encoders

libjpeg logo
libjpeg-turbo logo
Mozjpeg logo
Google Guetzli logo

Libjpeg is the baseline JPEG encoder built into Windows and Mac operating systems, maintained by an informal independent group and iterating occasionally. It tries to balance encoding speed, quality, and file size.

Libjpeg-turbo is intended to be a higher performance replacement for libjpeg, and it is in fact the default library for most Linux distributions. “Performance” in this scenario means using less CPU time during encoding and decoding. Libjpeg-turbo forked libjpeg in 2010 and claims to be “generally 2-6x as fast as libjpeg, all else being equal.”

MozJPEG is intended for a specific use case: images on the web. Mozilla forked libjpeg-turbo in 2014 so they could focus on reducing file size in order to reduce bandwidth and get images on the web to load faster. It does this through progressive coding and trellis quantization that sacrifices some encoding time, in the range of 4-7x. You can read the libjpeg-turbo creator’s thoughts on MozJPEG and why their two projects’ goals are incompatible.

Guetzli is what brings us here today, and it is focused on image quality. Google uses a new perceptual psychovisual model to decide where image quality loss will be the least noticeable. It sacrifices encoding time, on the order of 800-1000x slower than MozJPEG. Google claims file byte size is about 20-30% smaller than libjpeg, which is comparable to MozJPEG.

Google Guetzli vs MozJPEG Head-to-Head Comparison

Macbook Air 13 inch 2015

Test Computer Overview

MacBook Air (13-inch, Early 2015)

Processor: 1.6 GHz Intel Core i5

Memory: 4 GB 1600 MHz DDR3

Encoders

Mozilla MozJPEG

Google Guetzli

Methodology

I’m going to export product images from Photoshop as quality 100 JPG and then run each through both MozJPEG and Guetzli at quality 90. I’ll give before-and-after images for quality comparison, record CPU encoding time, and compare file sizes.

Commands:

$ time mozcjpeg -quality 90 -progressive [input] > [output]

$ time guetzli --quality 90 [input] [output]

I’ll compare images in a range of Megapixel sizes, from 1MPix to 48MPix. Our product image report shows that 1MPix is the most common size for a product image, but it’s a plurality and not a majority. Product image dimensions are all over the map.

I’m also trying out a wide variety of MPix because I want to see how accurate two of Google’s usage notes on Guetzli are:

Note: Guetzli uses a large amount of memory. You should provide 300MB of memory per 1MPix of the input image.

Okay, that might matter once I get past 12 MPix images. How long should this take, anyway?

Note: Guetzli uses a significant amount of CPU time. You should count on using about 1 minute of CPU per 1 MPix of input image.

That's pretty dramatic. Hmmm.... Without further ado, let’s get cracking!

Guetzli vs MozJPEG at 1 Megapixel

1 MPix JPEGs exported as quality 100 and 90 from Photoshop. Quality 100 then compressed via MozJPEG and Guetzli with byte size, real encoding time, and CPU encoding time provided.

1MP Photoshop Quality 100 boot

Original
172 KB
1200x857
(1 MPix)

1MP Photoshop Quality 90

Photoshop 90
126 KB

MozJPEG 1 MPix boot product image

MozJPEG
40 KB
real 0.197s
cpu 0.166s

Guetzli 1 MPix boot product image

Guetzli
54 KB
real 55.043s
cpu 53.937s

1MP Photoshop export quality 100

Original
530 KB
1200x800
(1 MPix)

1MP Photoshop export quality 90

Photoshop 90
369 KB

mozjpeg 1MP photoshop export model duffel

MozJPEG
137 KB
real 0.307s
cpu 0.277s

guetzli 1MP photoshop export model duffel

Guetzli
174 KB
real 1m27.901s
cpu 1m25.005s

1MP Photoshop quality 100 model face product photo

Original
791 KB
800x1200
(1 MPix)

1MP Photoshop quality 90 model face product photo

Photoshop 90
550 KB

Mozjpeg compressed product image with model's face

MozJPEG
204 KB
real 0.497s
cpu 0.380s

Guetzli compressed product image of model's face

Guetzli
210 KB
real 1m43.810s
cpu 1m41.016s

1 MPix Photoshop quality 100 red sweater product image

Original
1.1 MB
904x1200
(1 MPix)

1 MPix Photoshop quality 90 red sweater e-commerce photo

Photoshop 90
770 KB

Mozjpeg compressed 1 MPix red sweater product image

MozJPEG
281 KB
real 0.585s
cpu 0.549s

Guetzli compressed 1 MPix red sweater product image

Guetzli
258 KB
real 1m40.167s
cpu 1m28.336s

Lightning Analysis

Average results, rounded to hundredths:

1 MPix product image compression averages (JPG quality from 100 to 90)
  Byte Compression Encoding Real Time Encoding CPU Time
MozJPEG 74.47% 0.40s 0.34s
Guetzli 74.59% 1m26.73s 1m24.57s

Bytes: Byte size is a wash. In three of four instances Moz produced smaller images, but the average tilts marginally in Guetzli’s favor because the one instance it won was the largest image.

Time: Look at those encoding times! Moz averaged less than half a second, while Guetzli was pushing a minute and a half. If you’re processing hundreds or thousands of images (or in our case, tens of thousands of images a day), that really adds up.

Quality: I can’t tell the difference. Can you?

Let’s take a look at larger images and see how that effects our results.

Guetzli vs MozJPEG at 12 MPix - 48 MPix

JPEGs exported as quality 100 and 90 from Photoshop. Quality 100 then compressed via MozJPEG and Guetzli with byte size, real encoding time, and CPU encoding time provided.

12 megapixel photoshop quality 100 product image of model in dress

Original
6.6 MB
2804 × 4205
(12 MPix)

12 megapixel photoshop quality 90 product image of model in dress

Photoshop 90
4.4 MB

Mozjpeg compressed 12 MPix product image of model in dress

MozJPEG
1.6 MB
real 2.773s
cpu 2.708s

Guetzli compressed 12 MPix product image of model in dress

Guetzli
1.7 MB
real 25m13.057s
cpu 21m14.924s

Photoshop export at JPEG quality 100 of 16 MPix brown boot on white background

Original
2 MB
4789 × 3421
(16 MPix)

Photoshop export at JPEG quality 90 of 16 MPix brown boot on white background

Photoshop 90
1.5 MB

Mozjpeg compressed 16 MPix product image of boot on white background

MozJPEG
433 KB
real 2.245s
cpu 2.178s

Guetzli compressed 16 MPix product image of boot on white background

Guetzli
670 KB
real 20m2.125s
cpu 18m29.1237

Photoshop export of JPEG quality 100 21 MPix red sweater product image

Original
14.2 MB
4021 × 5334
(21 MPix)

Photoshop export of JPEG quality 90 21 MPix red sweater product image

Photoshop 90
10.1 MB

Mozjpeg compressed 21 MPix red sweater product image

MozJPEG
3.6 MB
real 6.472s
cpu 6.367s

Guetzli compressed 21 MPix red sweater product image

Guetzli
3.5 MB
real 40m42.399s
cpu 37m41.174

Photoshop export of 48 MPix JPEG quality 100 product image of model in red sweater holding duffel bag

Original
18 MB
8510 × 5674
(48 MPix)

Photoshop export of 48 MPix JPEG quality 90 product image of model in red sweater holding duffel bag

Photoshop 90
12.7 MB

Mozjpeg compressed 48 MPix product image of model in red sweater holding duffel bag

MozJPEG
4.6 MB
real 10.585s
cpu 10.406s

Guetzli compressed 48 MPix product image of model in red sweater holding duffel bag

Guetzli
5.9 MB
real 188m21.088s
cpu 118m33.993s

Lightning Analysis

Average results:

12-48 MPix product image compression averages (JPG quality from 100 to 90)
  Byte Compression Encoding Real Time Encoding CPU Time
MozJPEG 74.92% 5.52s 5.41s
Guetzli 71.12% 68m34.67s 48m59.81s

Bytes: MozJPEG averaged 3.8% better byte compression, which makes them about equal when you consider the small sample size.

Time: Again, wow! The fastest Guetzli encoding was 20 minutes, while the slowest was over 3 hours. If you’re a photographer or someone else looking to store full size JPGs locally, Guetzli is completely impractical. Even iPhones shoot 12MPix these days, and our test at that size took 25 minutes to encode.

Parting Google Guetzli Thoughts

The idea of perceptual psycho-visual encoding improvements sounds cool. It is cool. At this time, however, there simply isn’t enough of a visual improvement to make Google Guetzli worth the absolutely astonishing processing time it takes—at least not for e-commerce.

In the interest of fairness, I should note that our test uses a small sample size and is for a specific use case: product photography workflows. Product images typically have simple backgrounds, full focus, and a high megapixel count; maybe Guetzli would perform better with another kind of image. We also care deeply about encoding speed because getting images from the studio to the web as fast as possible is critical to e-commerce success.

If you’re compressing product images for use on the web, MozJPEG remains the encoder of choice.