To make an existing animated GIF loop a set number of times (or stop looping entirely) from the command line, use gifsicle and its --loopcount option:
# Loop forever (the usual web default)
gifsicle --loopcount=forever in.gif -o out.gif
# Play through once and stop, no looping
gifsicle --no-loopcount in.gif -o once.gif
# Play once, then repeat 3 more times (4 plays total)
gifsicle --loopcount=3 in.gif -o loop3.gifThat is the whole job for most people. The rest of this page is the detail that actually trips people up: what the count number really means (it is not "how many times it plays"), the one value that does the opposite of what you expect (--loopcount=0 does not stop looping, it loops forever), verifying the result, and the separate, inverted way ffmpeg numbers loops when you are creating the GIF in the first place.
A GIF stores its loop behaviour in a small block called the Netscape Application Extension. It is the original 1990s convention every browser still honours: no extension means play once, an extension with a count of 0 means loop forever, and a non-zero count means loop that many times. gifsicle and ffmpeg are both just writing that one block. You do not need to re-encode the frames to change it, which is why these commands are instant.
Install gifsicle
# macOS
brew install gifsicle
# Debian / Ubuntu
sudo apt install gifsicle
# Fedora
sudo dnf install gifsiclegifsicle is a tiny, single-purpose tool from Eddie Kohler. It edits GIFs in place without the heavyweight dependency of ImageMagick, and it is the right tool for anything to do with loop state, frame timing, or optimizing an animated GIF.
The three loop modes
| You want | Option | What it writes |
|---|---|---|
| Loop forever | --loopcount=forever (or --loopcount=0) | Netscape extension, count 0 |
| Play once and stop | --no-loopcount | No loop extension at all |
| Loop a fixed number of times | --loopcount=N | Netscape extension, count N |
gifsicle --loopcount=forever spinner.gif -o spinner-forever.gif
gifsicle --no-loopcount banner.gif -o banner-once.gif
gifsicle --loopcount=5 wave.gif -o wave-5.gifThe trap here is --loopcount=0. It reads like "zero loops, so play once," but the gifsicle manual is explicit that --loopcount=0 is equivalent to --loopcount=forever, not to --no-loopcount. A count of 0 in the Netscape block is the format's signal for infinite looping. To actually stop a GIF looping you want --no-loopcount, which strips the loop extension entirely. That is also gifsicle's default when you do not pass any loop option at all:
gifsicle --no-loopcount in.gif -o once.gifSo if you run gifsicle for some other reason (resizing, optimizing) and forget to carry the loop setting through, you can silently turn a forever-looping GIF into a play-once one. Pass --loopcount=forever explicitly when you want the loop preserved.
The off-by-one that catches everyone
Here is the part the man page states plainly and almost everyone misreads. With --loopcount=N, N is the number of repeats after the first play, not the total number of plays. The animation runs once on its own, then loops N more times.
So --loopcount=3 gives you four plays in total: the initial run plus three loops. If you want a GIF to play exactly three times, you set the count to one less than that:
# Plays a total of 3 times: once, then 2 repeats
gifsicle --loopcount=2 in.gif -o play-three-times.gifThis is not a gifsicle quirk; it is how the Netscape loop count is defined at the format level. Every tool that writes that block inherits the same "count of repeats after the first" meaning, which is exactly why the next section gets confusing.
Verify what you actually wrote
Do not trust your viewer; trust the file. gifsicle --info (or gifsicle -I) dumps the GIF's metadata, including the loop block:
gifsicle --info out.gifA forever-looping GIF shows a line like loop forever. A fixed-count GIF shows the count (loop count 3). A play-once GIF shows no loop line at all, because there is no extension to report. If you are doing a lot of these, grep for it:
gifsicle --info out.gif | grep -i loopFor a fuller look at frame count, per-frame delays, and dimensions, see inspecting an animated GIF from the command line.
Setting the loop when you create the GIF with ffmpeg
If you are generating the GIF from a video rather than editing an existing one, ffmpeg's gif muxer has its own -loop option, and its numbering is the confusing inverse of gifsicle's. Memorise this table, because guessing it wrong is the single most common ffmpeg GIF complaint:
| You want | ffmpeg flag |
|---|---|
| Loop forever | -loop 0 (this is the default) |
| Play once, no loop | -loop -1 |
| Loop N times | -loop N |
# Loop forever (ffmpeg's default anyway)
ffmpeg -i in.mp4 -loop 0 out.gif
# Play once and stop
ffmpeg -i in.mp4 -loop -1 out.gif
# Loop 3 times
ffmpeg -i in.mp4 -loop 3 out.gifRead that against the gifsicle table and the inversion is in the stop value, not the forever value. Both tools agree that 0 means loop forever (in gifsicle --loopcount=0 equals --loopcount=forever; in ffmpeg -loop 0 is the infinite default). They diverge on how you switch looping off: gifsicle uses --no-loopcount (a named flag, because --loopcount=0 is already taken by "forever"), while ffmpeg overloads the same -loop option with a negative value, -loop -1. Same underlying Netscape block, two tools that reached for different idioms to express "play once." The -loop flag also has to come before the output filename in the ffmpeg command, or it is silently ignored.
ffmpeg's positive -loop N carries the same off-by-one as gifsicle: N is repeats after the first play, so -loop 3 plays four times total. For the full high-quality video-to-GIF pipeline (the palettegen/paletteuse two-pass that ffmpeg needs to produce a clean GIF), see the ffmpeg command cheat sheet.
A practical note: if you already have the GIF and only need to change its loop behaviour, reach for gifsicle, not ffmpeg. Rewriting the loop block with --loopcount leaves the frames untouched and is instant; running it back through ffmpeg re-encodes every frame and degrades quality unless you redo the palette work.
FAQ
See also
- Optimize and compress an animated GIF (gifsicle): the
--lossy,--colors, and downscale levers that actually shrink a GIF. - Inspect an animated GIF from the command line: frame count, per-frame delays, first frame, and animated-or-not.
- The ffmpeg command cheat sheet: the full video-to-GIF palette pipeline and every flag worth knowing.
Sources
Authoritative references this article was fact-checked against.





