Supporting a 35-year-old “video” format

Raphaël Zumer
Vimeo Engineering Blog
4 min readFeb 24, 2021


The year is 2021 A.D. Video coding is entirely dominated by modern codecs like AV1. Well, not entirely… One small, indomitable format still holds out against the invaders. And life is not easy for the engineers who seek to improve video quality…

Sintel by the Blender Institute/CC BY. GIF made on Vimeo.

Even today, the Graphics Interchange Format, or GIF (pronounced “jif”), created in 1987, remains the most portable, widely supported way to transmit short animated animations or videos. Though it supports only up to 256 colors per frame, offers poor compression performance, and can’t include audio tracks, the simplicity of the format has enabled it to remain dominant in applications like email, forums, and social media, and in legacy systems that don’t support modern alternatives. Because of the format’s limitations, many platforms ([1], [2]) that claim to support GIFs are actually using newer formats like h.264 that are configured to loop and play without audio to simulate actual GIFs. Browsers and mobile devices have no problem playing them back, and they offer much lower file size at the same or better quality. However, GIF still has the upper hand when it comes to ubiquitous support.

At Vimeo, we recently released a feature that enables our members to create GIFs from their videos for embedding in emails and sharing on any platform. As with any video encoding system, we needed to consider how to keep quality as high as possible while maintaining reasonable file sizes and encoding times, but because of the limited compression capabilities of the format, we had to solve some problems unique to it related to color quantization, temporal optimization, rate control, and performance.

Behind the scenes is a system composed of libimagequant and FFmpeg. We use libimagequant to quantize images — reducing the number of colors used in each frame to satisfy the restrictions of the format — while minimizing the quality impact of that process. This optimization step is complex and is the most time-consuming part of the encoder. libimagequant also applies dithering, which can look similar to film grain, and conceals any color banding that may arise from the quantization in the resulting GIF. FFmpeg then takes the quantized and dithered images and their color palettes and encodes them to the actual GIF format.

To improve the quantization quality and compressibility, we apply a pre-processing step to reduce temporal redundancy. GIFs can have transparent pixels, and in animated GIFs, this can be used to change only some of the pixels between different frames, keeping others static. If the background in a video doesn’t change between frames, we can avoid encoding its colors multiple times by comparing each pixel of consecutive frames and making them transparent in the latter frames when they are very similar. We use a simple perceptual color distance measure to determine the pixels to make transparent so that this doesn’t compromise quality as seen by the human eye.

This system enables us to encode GIFs with some quality parameters governing frame rate and size, quantization quality, and pixel distance thresholds for pixel transparency, but there is one more problem we needed to solve: rate control. Since GIF is an old format that isn’t optimized for video encoding, we can’t use the same settings to encode every video indiscriminately and expect reasonable sizes for use in email and platforms that have hard size limits. Modern video encoders usually include internal rate control mechanisms that adjust quality in order to hit a target size, but with GIF, there are limited ways to manage file size: reducing the number of colors per frame, reducing the number of frames, and reducing the size of frames. To keep file sizes reasonable without sacrificing quality unless necessary, we run multiple encodes, downgrading quality from our default parameters gradually as needed until we reach an appropriate level that compromises quality as little as possible.

Encoding the same video multiple times does result in higher overall response time, so we parallelize them at multiple levels to keep waiting time reasonable. We currently run encodes in fixed-size batches before collecting results and picking the final one, and each encode also runs the main bottleneck, color quantization, on multiple frames simultaneously. The general architecture and program flow of the system is described in the activity diagram below.

Activity diagram for the GIF creation system.

Due to the age and low complexity of the format, GIFs will never look quite as good as their source videos, but we still have some improvements in the works targeting both quality and performance. Sharing GIF snippets is a good way to create interest for a video among friends or followers by email or social media.

This feature is available to all our members right now, so if you want to share a video on Vimeo through email or social media, find the GIF option in your video settings and give it a try!

Interested in flexing your engineering chops at Vimeo? Join our team!