TechEarl

How to Change the Speed of an Animated GIF (gifsicle and ffmpeg)

Speed up or slow down an animated GIF from the command line: set a uniform per-frame delay with gifsicle, re-time it with ffmpeg's setpts filter, and avoid the browser delay floor that quietly caps how fast a GIF can play.

Ishan Karunaratne⏱️ 8 min readUpdated
Share thisCopied
Change the speed of an animated GIF from the command line with gifsicle's per-frame delay or ffmpeg's setpts filter, and work around the browser minimum-delay floor.

The fastest way to change an animated GIF's playback speed from the command line is gifsicle: every frame in a GIF carries a delay value, and --delay overwrites all of them at once. Lower delay means a faster GIF:

bash
# Speed it up: 5 centiseconds per frame (20 fps)
gifsicle --delay 5 in.gif -o out.gif

# Slow it down: 20 centiseconds per frame (5 fps)
gifsicle --delay 20 in.gif -o out.gif

That is the whole job for most cases. The rest of this page is the detail: what that delay number actually means, the floor that makes very low delays misbehave, and when to reach for ffmpeg instead.

How GIF speed actually works

A GIF has no frame rate the way a video does. Each frame stores its own delay: how long it stays on screen before the next is drawn, measured in hundredths of a second (centiseconds). A delay of 10 holds each frame for 0.1 second (10 fps); a delay of 4 is 0.04 second (25 fps).

So changing a GIF's speed means changing those per-frame delays. There is no separate speed knob: lower the delay and it plays faster, raise it and it plays slower. gifsicle's --delay sets one uniform delay across every frame, which is what you want almost every time.

To see what a GIF currently uses, ask gifsicle for its info:

bash
gifsicle --info in.gif

Each frame line shows its delay, so you can see whether the source already has uniform timing or a mix of per-frame delays.

The delay floor that catches everyone

Here is the gotcha that sends people in circles: you can set --delay 1 and the file will store that 1-centisecond delay, but it will not play at 100 fps in a browser. Every major browser clamps very small delays up to a minimum. Modern Chrome and Firefox use a duration of 100 ms (10 fps) for any frame whose delay is 10 ms or less, that is, a delay value of 0 or 1 (a comment in Chromium's GIF decoder spells this out: ad-style frames asking for a near-zero duration get forced to 100 ms). A delay of 2 (20 ms) is the smallest value they honor, so the fastest a GIF reliably plays in a current browser is about 50 fps. Older Internet Explorer and early Firefox used a much higher floor, clamping anything under 100 ms up to 100 ms.

The practical consequence: a delay of 0 or 1 makes a slow GIF, not a blazing-fast one, because the renderer ignores your tiny value and falls back to its 10 fps default. For a genuinely fast GIF that plays consistently, keep the delay at 2 or higher. A delay of 2 is the floor on modern browsers; if you also care about ancient renderers, 3 is a conservative choice but it does not buy you anything on current Chrome or Firefox.

bash
# This does NOT play at ~100 fps. Browsers clamp delay 0 or 1 back to ~10 fps.
gifsicle --delay 1 in.gif -o too-fast.gif

# Delay 2 (20 ms, ~50 fps) is the fastest modern browsers actually honor.
gifsicle --delay 2 in.gif -o fast.gif

This is a property of the GIF format and the renderers, not of gifsicle. ffmpeg's approach runs into the same wall, because the output is still a GIF being drawn by the same renderers.

Changing speed with ffmpeg (setpts)

If ffmpeg is already in your pipeline, its setpts filter re-times the clip by rewriting each frame's presentation timestamp. A multiplier below 1 speeds it up; above 1 slows it down:

bash
# Double the speed (half the duration)
ffmpeg -i in.gif -vf "setpts=0.5*PTS" out.gif

# Half the speed
ffmpeg -i in.gif -vf "setpts=2.0*PTS" out.gif

setpts=0.5*PTS halves each frame's timestamp, so the whole animation runs in half the time. It is the opposite approach to gifsicle: gifsicle edits the stored delays directly, while ffmpeg re-times the stream and re-encodes the GIF from it.

Because re-encoding drops a GIF back to 256 colors, run a palette pass when quality matters, the same two-step flow used to convert a video to a GIF:

bash
ffmpeg -i in.gif -vf "setpts=0.5*PTS,split[s0][s1];[s0]palettegen[p];[s1][p]paletteuse" out.gif

For a simple speed change with no other editing, gifsicle is the lighter tool: it rewrites the timing in place without a full re-encode, so it is faster and does not touch the palette.

Speed up without changing the timing: drop frames

There are two distinct ways to make a GIF "faster," and they are not the same thing:

  • Change the delay (gifsicle --delay, ffmpeg setpts): the same frames play in less time. Smooth, but a very low delay hits the browser floor above.
  • Drop frames: keep the per-frame delay, but throw away every other frame so there is less to play. This shortens the GIF and shrinks the file, at the cost of looking choppier.

Dropping frames is the move when a GIF is already near the delay floor and lowering the delay cannot speed it up further. With gifsicle you select the frames to keep:

bash
# Keep frames 0,2,4,... (every other frame), then re-time the survivors
gifsicle in.gif $(seq -f '#%g' 0 2 98) --delay 4 -o out.gif

That keeps half the frames and sets a 4-centisecond delay on what remains. ffmpeg does the same with its fps or select filter if you prefer one pipeline. Frame-dropping plus a sane delay is also the core of shrinking a GIF's file size, covered in optimizing a GIF from the command line.

Rule of thumb: lower the delay first (down to 2, the modern browser floor), and only start dropping frames once you have hit that floor and still need it faster or smaller.

FAQ

See also

Sources

Authoritative references this article was fact-checked against.

TagsgifsicleffmpegGIFanimated gifCLIsetptsframe delay

Found this useful? Pass it on.

Copied

Ishan Karunaratne

Tech Architect · Software Engineer · AI/DevOps

Tech architect and software engineer with 20+ years building software, Linux systems, and DevOps infrastructure, and lately working AI into the stack. Currently Chief Technology Officer at a healthcare tech startup, which is where most of these field notes come from.

Keep reading

Related posts