How to Reverse a Video with FFmpeg (and Build a Boomerang Loop)

You ran ffmpeg -i input.mp4 -vf reverse out.mp4 on a three second clip and it finished instantly. You ran the same command on a 12 minute screen recording and the process climbed to 100% of available memory, sat there, and got killed. Same command, same machine, and nothing in the error output explains why.
Quick answer: The ffmpeg reverse video command isffmpeg -i input.mp4 -vf reverse -af areverse reversed.mp4, but thereversefilter has to buffer every decoded frame of the stream in RAM before it can emit the first one, which is roughly 93 MB per second of 1080p30 footage. Trim to the segment you actually want at the input (-ss 2 -t 3), reverse that, then concat forward plus reversed for a boomerang loop. If you'd rather not size a machine around raw frame buffers, FFmpeg Micro runs the same job as one API call and hands back the finished loop.
The reverse filter is a buffer, not a stream
FFmpeg's reverse filter can't stream. The last frame of the input is the first frame of the output, so the filter has to hold the whole decoded clip before it knows what to write. FFmpeg's own filter documentation says as much and recommends trimming, which is easy to skim past until a job dies in production.
The math is not subtle. A 1080p frame in yuv420p is 1920 × 1080 × 1.5 bytes, about 3.1 MB, and those are decoded frames, not compressed ones. Your 40 MB MP4 is not what gets buffered.
| Source | Per frame | Per second at 30 fps | 10 seconds | 60 seconds |
|---|---|---|---|---|
| 720p | 1.4 MB | 41 MB | 410 MB | 2.5 GB |
| 1080p (or 1080×1920 vertical) | 3.1 MB | 93 MB | 933 MB | 5.6 GB |
| 4K UHD | 12.4 MB | 373 MB | 3.7 GB | 22 GB |
Treat those as a floor, since FFmpeg carries per-frame overhead on top of the pixel data. This is why a reverse job dies with exit 137 on a container that transcodes 4K all day without complaint: the container limit was sized for a transcode's working set, and reverse wants the entire clip resident. We wrote up that failure mode in more detail in self-hosting FFmpeg on Railway, and the shape is identical here.
Reverse a short clip the safe way
Reversing works fine as long as you decide up front how much footage the filter is allowed to hold. Put -ss and -t before -i so FFmpeg stops reading the file after three seconds instead of decoding twelve minutes and throwing most of it away:
ffmpeg -ss 2 -t 3 -i input.mp4 \
-vf reverse -af areverse \
-c:v libx264 -crf 18 -pix_fmt yuv420p \
reversed.mp4
There's a real difference between the input-level trim above and the trim filter. The trim filter caps what reverse buffers, but FFmpeg still decodes every frame of the source to get there. Input-level -ss/-t stops the decode too, which is the difference between a 0.8 second job and a 40 second one on a long file.
-af areverse is not optional if your clip has sound. The video filter chain and the audio filter chain are separate, so -vf reverse alone reverses the picture and leaves the audio running forward.
Build a boomerang loop from one clip
A boomerang is the source segment played forward, then the same segment played backward, concatenated into one file. The whole effect fits in a single filter_complex:
ffmpeg -ss 2 -t 3 -i input.mp4 -filter_complex \
"[0:v]fps=30,format=yuv420p,split[fwd][tmp];\
[tmp]reverse,trim=start_frame=1,setpts=PTS-STARTPTS[rev];\
[fwd][rev]concat=n=2:v=1:a=0[out]" \
-map "[out]" -an -c:v libx264 -crf 20 -movflags +faststart boomerang.mp4
The piece that people leave out is trim=start_frame=1. Without it, the last frame of the forward pass and the first frame of the reversed pass are the same frame, so the loop holds for two frame durations at the turnaround and reads as a stutter. Dropping one frame off the front of the reversed stream removes the duplicate. The same duplication happens at the wrap point if you loop the file, so trim a frame off the end of the forward pass too when the clip will play on repeat.
fps=30 up front matters more than it looks. Phone recordings and screen captures are often variable frame rate, and reverse inverts frame order without inventing sane timestamps for VFR input, which shows up as a boomerang that drifts or plays back at the wrong speed. Normalizing to constant frame rate before the split avoids the whole class of problem.
If you'd rather keep the steps separate and inspect the middle, the two-file version is easier to debug:
- Cut the segment:
ffmpeg -ss 2 -t 3 -i input.mp4 -an -c:v libx264 -crf 18 fwd.mp4 - Reverse it:
ffmpeg -i fwd.mp4 -vf reverse -an -c:v libx264 -crf 18 rev.mp4 - Concat: write
file 'fwd.mp4'andfile 'rev.mp4'intolist.txt, thenffmpeg -f concat -safe 0 -i list.txt -c copy boomerang.mp4
The concat demuxer with -c copy only works because both files came out of the same encoder settings. Mismatched resolution, pixel format, or time base and it fails or produces garbage. The rules are the same ones covered in our composition API primer on concatenating clips.
Reverse a long video without running out of memory
Reversing a full 12 minute recording is possible, it just can't be one reverse call. Split the source into chunks, reverse each chunk independently, then concatenate the chunks in reverse order:
ffmpeg -i long.mp4 -c copy -map 0 -f segment -segment_time 10 \
-reset_timestamps 1 seg_%04d.mp4
for f in seg_*.mp4; do
ffmpeg -i "$f" -vf reverse -af areverse -c:v libx264 -crf 18 "rev_$f"
done
ls -1 rev_seg_*.mp4 | sort -r | sed "s/^/file '/;s/$/'/" > list.txt
ffmpeg -f concat -safe 0 -i list.txt -c copy fully_reversed.mp4
Peak memory now tracks segment length, not source length, so 10 second chunks of 1080p30 cap the buffer around 933 MB no matter how long the input is. Two caveats: -c copy segmenting cuts at keyframes, so segment durations vary a little, and every chunk gets re-encoded in step two, so pick a CRF you can live with. Reversing is always a re-encode. There is no stream-copy path.
This is the point where a hosted job stops being a convenience and starts being the cheaper answer. If the reverse step lives inside an n8n, Make, or Zapier workflow, none of those runtimes want to hold a multi-gigabyte frame buffer, and n8n disabled the Execute Command node by default in v2.0 anyway. Sending the clip to the FFmpeg Micro API keeps the same three steps you'd run locally, submit a job, take a webhook or poll, download the output, with no encoder to host and no memory ceiling to guess at.
Pitfalls that show up in real clips
Most reverse failures are not syntax errors. They're the second-order effects of playing frames backward.
Audio that reverses into noise is the common one. Speech played backward is unusable, so for boomerangs the normal move is -an on the output and a music bed added separately. Reversed audio is only worth keeping for effects and ambience.
Motion-heavy footage gets bigger, not smaller. Backward motion breaks the temporal prediction that H.264 relies on, so a reversed clip at the same CRF often lands 10 to 20 percent larger than the forward original. Budget for it if you're hitting a platform upload cap.
Boomerangs read badly on clips with a hard cut or a big camera move, because the pivot point becomes obvious. Pick a segment with continuous motion in one direction, two to four seconds, and the turnaround disappears.
And if the target is a GIF rather than an MP4, generate the boomerang MP4 first and convert after. Reversing inside a GIF encode fights the palette generation, which is its own topic covered in the palette method for MP4 to GIF.
When a local reverse is the wrong call
Running reverse on your own machine is right when you have one clip, a laptop with headroom, and no schedule. It stops being right the moment reversing is a step in a pipeline that other people's uploads flow through, because you no longer control the input duration or resolution, and the memory requirement scales with both.
If you're assembling many boomerangs on a schedule, the boomerang blueprint is the one-click version of everything above: upload a clip, get the forward-plus-reverse loop back with the pivot frame already handled. It's the same job this post walks through by hand, minus sizing a box around 93 MB per second.
FAQ
Does FFmpeg reverse audio along with the video?
FFmpeg does not reverse audio automatically. -vf reverse only touches the video stream, so you need -af areverse in the same command to reverse sound, and areverse buffers the audio stream in memory the same way the video filter does.
How long a clip can FFmpeg reverse before it runs out of memory?
The limit is your available RAM divided by roughly 3.1 MB per 1080p frame. On a machine with 4 GB free, a 1080p30 source tops out around 40 seconds before the reverse filter is at risk, and 4K drops that to about 10 seconds.
Why does my boomerang stutter in the middle?
The stutter is a duplicate frame at the turnaround: the final frame of the forward pass and the opening frame of the reversed pass are the same image, held for two frame durations. Adding trim=start_frame=1 after reverse in the filter chain drops the copy and the pivot plays clean.
Can I reverse a video without re-encoding it?
Reversing always requires a full decode and re-encode, because the compressed bitstream depends on frames that come before each frame in play order. There is no -c copy path for reversal, so choose a CRF around 18 to 20 to keep the quality loss invisible.
Does the reverse filter work on variable frame rate video?
The reverse filter handles VFR input poorly, since inverting frame order on irregular timestamps produces playback that drifts or runs at the wrong speed. Insert fps=30 (or your source's nominal rate) before reverse in the filter chain to force constant frame rate first.
Grab a clip, cut three seconds out of the middle, and run the boomerang command above to see where the pivot lands. When you want that same loop running against every upload without babysitting memory, sign up free and send the first one through the API.
About Javid Jamae
Founder & CEO at FFmpeg Micro
Javid is a software engineer, author, and entrepreneur with over 25 years of professional software development experience across enterprise, startup, and consulting environments. He founded FFmpeg Micro to make video processing accessible to developers through a simple, automation-first REST API.
You might also like

Stop Re-Exporting. Encoding a Video Once Covers Every Platform.
Encoding a video once and deriving every delivery version from it: the mezzanine command, CRF and preset per rung, social crops, and the one-call version.

How to Turn a Screen Recording into a GIF for Your README
Turn a screen recording to GIF for your README: crop to the app window, drop to 12 fps, and run FFmpeg's palette pass to land under GitHub's 10 MB cap.

FFmpeg Subtitle Delay Isn't a Slider Drag. Use -itsoffset
Fix ffmpeg subtitle delay with -itsoffset: shift an SRT by a constant, spot framerate drift that no offset fixes, and generate synced captions from the API.
Skip the command line
The Boomerang Loop blueprint builds the seamless loop for you: upload a short clip, done.
Run it (free)