Every other tool decodes and re-encodes. This one rewrites the timing bytes.
A GIF stores how long to hold each frame in a few bytes next to the frame. Change those and the animation runs at a new speed with the image data byte-for-byte untouched. No colour banding, no dithering artefacts, no generation loss.
Drop or click to upload
Drag & drop or paste from clipboard
Animated GIF — 60MB max
Speed
Playback
The usual approach is to decode the GIF into frames, change the timing, and encode a new GIF. That sounds harmless and is not, because encoding a GIF is lossy in a way people forget: a GIF frame can hold at most 256 colours, so the encoder must quantise and dither. Do that to an image that was already quantised and dithered once and you get a second, different approximation stacked on the first. Flat areas band, gradients speckle, and edges pick up noise.
None of that is necessary, because speed is not stored in the pixels.
A GIF is a sequence of labelled blocks. Before most frames sits a small Graphic Control Extension, and inside it is a two-byte field: the delay before the next frame, measured in hundredths of a second. The frame's actual image data is a separate block of LZW-compressed bytes that follows it.
So changing playback speed is a matter of rewriting those two-byte fields and copying every other byte of the file across unchanged. That is what this page does. The compressed image data is never decoded, never re-quantised, and never re-encoded. Your output is pixel-identical to your input, and the file size barely moves.
Reversing, trimming and dropping frames work the same way, by reordering or omitting whole blocks rather than rebuilding them. Which brings up the one honest caveat.
Many GIFs store each frame as a full picture. Plenty of others store frames as differences from the frame before, painting only the pixels that changed. That is a big saving, and it means those frames are not independent: frame 40 is meaningless without frames 1 to 39 having been drawn first.
For files like that, reversing or dropping frames would produce visible garbage, so this tool checks first and disables those options when it is not safe, telling you why. Speed changes are always safe, because timing has nothing to do with how a frame was stored.
Delay is stored in hundredths of a second, so the smallest value a GIF can express is 1, which is 10 milliseconds, or 100 frames a second. That is already the floor. But there is a second, stricter limit that trips people up:
Browsers treat a delay of 0 or 1 as 10. It is a decades-old compatibility rule, inherited from early animated GIFs that specified absurdly fast timing, and every major browser still applies it. The practical consequence is that a GIF asking for 1 hundredth of a second per frame plays at 10 hundredths, roughly 10fps, no matter what the file says.
So when you ask for a speed that would push frames below that floor, this page tells you the request cannot be met and shows the speed you will actually get, rather than writing a number that browsers will quietly ignore. When that happens, dropping frames is the real fix: half as many frames at the same delay genuinely plays twice as fast.
| Delay written | What browsers do | Effective rate |
|---|---|---|
0 or 1 (0-10ms) | Clamped to 10 | ~10 fps |
2 (20ms) | Honoured | 50 fps |
4 (40ms) | Honoured | 25 fps |
10 (100ms) | Honoured | 10 fps |
This tool never writes a delay below 2, because 2 is the fastest value that is actually respected. Writing 1 would look like a faster GIF and play slower.
The file is read into memory, the timing bytes are rewritten, and a new blob is handed straight back to you. There is no server in the path, which is also why the result appears the instant you move the slider instead of after a round trip and a queue.
Keep going without re-uploading — your image carries over to the next tool automatically.