Too many packets buffered? max_muxing_queue_size is the last fix

Your transcode ran for four minutes, wrote nothing to the output file, then died with Too many packets buffered for output stream 0:1. The usual advice is to paste -max_muxing_queue_size 9999 into the command and move on. That works often enough that nobody asks what the queue is for, which is why the same job fails again on a bigger file or a smaller container.
Quick answer: "Too many packets buffered for output stream" means FFmpeg's muxer is holding packets for one output stream while it waits for another output stream to produce its first packet, and that buffer hit its limit. Fix the cause before the symptom: map out the streams you never wanted (-map 0:v:0 -map 0:a:0 -dn -sn), then check whether an input seek is starting your streams at different timestamps, and only then raise-max_muxing_queue_sizeto 1024 or 2048. If you'd rather not size muxer queues against your server's RAM, FFmpeg Micro runs the same job as one API call with no servers to run.
What FFmpeg is actually buffering
Conventional wisdom says the queue is a bandwidth buffer, a place packets wait because the disk or the encoder can't keep up. Most stalled transcodes look exactly like that. But it isn't a throughput problem, it's an initialization problem: a container muxer can't write its header until it knows the codec parameters of every output stream, and for encoded streams those parameters (extradata, for instance) only exist after the encoder produces its first packet. So FFmpeg holds everything.
That's the whole mechanic. If your video encoder starts producing packets immediately and your audio stream has nothing until 00:03:12, every video packet from second zero to minute three sits in RAM. The stream named in the error message (0:1 above) is usually the victim, not the culprit. The culprit is the stream that hasn't spoken yet.
Why the same value works on one server and fails on another
The -max_muxing_queue_size flag hasn't meant one thing across FFmpeg versions, which is why copied-from-Stack-Overflow values behave inconsistently. Originally it was a flat packet count, default 128. FFmpeg commit 453b2f3 added a second condition: a data-size threshold, -muxing_queue_data_threshold, defaulting to 50 MB per output stream. In builds that have it, the queue can grow past 128 packets, doubling as needed, until total buffered data crosses 50 MB. Only then does the packet limit become a hard ceiling and the error fire.
On an Ubuntu 18.04 box running ffmpeg 3.4, you hit the wall at 128 packets no matter how small they are. On a current 7.x build, a 128-packet cap is invisible for a low-bitrate stream and arrives fast for 4K. Check what you're on before you trust a number someone posted in 2018:
ffmpeg -version | head -n 1
ffmpeg -h full 2>&1 | grep -A1 muxing_queue
Fix it in the order that actually holds
Raising the queue is the third fix, not the first. The two before it remove the cause instead of paying for it in RAM.
1. Drop the stream you never wanted
Check what's in the file before touching any flags. Most of these failures come from a stream nobody asked for: a tmcd timecode track in a MOV out of a camera or Final Cut, an mjpeg cover-art stream in an MP4 pulled from a podcast host, a bin_data or mov_text track in a DVR rip.
ffprobe -v error -show_entries stream=index,codec_type,codec_name \
-of csv=p=0 input.mov
If that prints four streams and you need two, say so explicitly. Explicit mapping is the single highest-value change:
ffmpeg -i input.mov \
-map 0:v:0 -map 0:a:0 -dn -sn \
-c:v libx264 -crf 20 -c:a aac -b:a 128k \
-movflags +faststart output.mp4
-dn drops data streams, -sn drops subtitles, and -map 0:v:0 -map 0:a:0 takes the first real video and audio stream and ignores attached pictures. A stream that isn't in the output can't hold the muxer hostage.
2. Check what your seek is doing to stream start times
Input seeking is the other reliable queue filler, and the one Jellyfin runs into constantly (issue 3960 on their tracker). When you write -ss 600 -i input.mp4, the demuxer seeks to the nearest keyframe for each stream independently. Audio and video land at different timestamps, sometimes seconds apart, and the stream that starts early queues while the other catches up. A subtitle track with no cue for another minute widens the gap further.
Keep -ss before -i for speed, but drop the sparse streams at the same time, and re-encode rather than stream-copy when offsets don't line up:
ffmpeg -ss 600 -i input.mp4 -t 60 \
-map 0:v:0 -map 0:a:0 -sn -dn \
-c:v libx264 -preset veryfast -crf 22 -c:a aac \
clip.mp4
Two-pass encodes and hardware encoders (NVENC, VAAPI, QSV) make this worse: encoder init takes a second or two while the demuxer hands you audio at full speed, so the queue is deep before the first video packet exists.
3. Then, and only then, raise the queue
When the deep queue is legitimate, raise it. -max_muxing_queue_size is a per-output-stream option, so it has to appear before the output filename, and it accepts a stream specifier:
ffmpeg -i input.mkv \
-map 0 -c:v libx264 -crf 20 -c:a copy \
-max_muxing_queue_size 2048 \
output.mkv
2048 is what Jellyfin settled on in its default transcode arguments. 1024 clears the overwhelming majority of real cases. If you're on a build with the data threshold and the packets are large, you may also need -muxing_queue_data_threshold 200M for the packet count to matter.
The failure people report as a hang
A filling muxing queue looks like a hung process, not an error. FFmpeg writes no output bytes while it buffers, so the destination file stays at zero or stops at the header. The frame= fps= time= progress line keeps updating, so the process is clearly alive. RSS climbs steadily. In n8n, Make, or a Zapier step wrapping a shell call, the node sits there until something times out.
Inside a container it gets worse. If the queue grows past the container's memory limit before it reaches the packet cap, the kernel OOM-kills ffmpeg and you get exit code 137 with no FFmpeg error message at all. That's the same class of problem as n8n running out of memory on large video files: the fix is architectural, not a bigger number.
This is also where a managed job earns its place. FFmpeg Micro sizes the machine to the media, so queue depth and container RAM aren't parameters you own. The FFmpeg API overview covers the job envelope.
What a big queue costs you in RAM
Every queued packet holds its full compressed payload, so the memory cost of -max_muxing_queue_size 9999 depends on the bitrate of the stream doing the waiting. The worst case, at 30 fps:
| Stream | Avg packet size | 1,024 packets | 9,999 packets |
|---|---|---|---|
| 1080p H.264 @ 8 Mbps | ~33 KB | ~34 MB | ~330 MB |
| 4K HEVC @ 40 Mbps | ~167 KB | ~170 MB | ~1.6 GB |
| ProRes 422 HQ 1080p @ 180 Mbps | ~750 KB | ~770 MB | ~7.3 GB |
On a 512 MB n8n container or a 1 GB Cloud Run instance, the 9999 that "fixed it" on your laptop is a guaranteed OOM kill for anything above 1080p. Pick a number you can afford to have resident.
Common pitfalls
The mistakes that cost the most debugging time are the ones that look like they worked:
- Confusing
-max_muxing_queue_sizewith-thread_queue_size.thread_queue_sizeis an unrelated input option, and its error reads "Thread message queue blocking; consider raising the thread_queue_size option." - Placing the flag after the output filename, or before
-i. It's an output option and belongs immediately before the output file. - Using
-map 0on an unknown input. Copying every stream from a user upload is how timecode, data, and cover-art tracks end up in your output. - Treating exit code 137 as a crash. It's the OOM killer, and it means your queue outgrew the container.
- Assuming a bigger queue fixes A/V drift. It doesn't touch timestamps. Misalignment after a successful job is a separate problem, covered in FFmpeg audio out of sync isn't the codec, it's the frame rate.
When tuning the queue is the wrong move entirely
Raising -max_muxing_queue_size is the wrong answer when the input itself is broken rather than merely awkward. A truncated upload with a missing moov atom, a stream with no packets, or a file whose audio track is empty will fill the queue and fail no matter what limit you set. Validate at ingest with ffprobe and reject the file instead of encoding it, the same pattern as fixing "moov atom not found" on uploaded videos.
Tuning the queue is also wrong inside a function runtime with a hard memory ceiling you can't raise. A deep queue on AWS Lambda or a small Cloud Run instance isn't a tuning problem, it's a placement problem. Move the encode to a machine with headroom, or hand the job to a service where queue sizing isn't the caller's problem.
Manual tuning vs. a managed job
Tuning queues yourself and sending the job to a service differ on five points:
| Self-hosted FFmpeg | FFmpeg Micro | |
|---|---|---|
| Queue tuning | Your flag, your RAM budget, per input | Handled server-side |
| Version drift | 3.4 vs 7.x change the flag's meaning | One managed toolkit |
| Long jobs | You babysit the process and the timeout | Submit, webhook, download |
| Memory ceiling | Your container's limit | Not your container |
| Cost to start | Server time | Free tier |
FAQ
What does "Too many packets buffered for output stream" actually mean?
The error means FFmpeg's muxer accumulated more packets for one output stream than its buffer allows, because another output stream hadn't produced its first packet yet and the muxer can't write the container header until every stream's codec parameters are known. The stream index in the message is the one that piled up, not the cause of the delay.
What's a safe value for -max_muxing_queue_size?
A value of 1024 clears most real cases, and 2048 is what Jellyfin uses in its default transcode arguments. Values like 9999 are safe only if you've checked the arithmetic: 9999 packets of 4K HEVC is roughly 1.6 GB of resident memory.
Does raising max_muxing_queue_size affect quality or A/V sync?
Raising -max_muxing_queue_size changes nothing about quality, bitrate, or timestamps. The flag only controls how many packets FFmpeg holds in RAM while waiting, so the only cost is memory.
Why does my command work locally but fail in Docker?
The same FFmpeg command fails in Docker for two reasons: the container's FFmpeg build may be older and enforce the flat 128-packet limit without the 50 MB data threshold, or the container's memory limit is lower than your laptop's RAM, so the OOM killer stops the process at exit code 137 before FFmpeg prints its error.
Is -max_muxing_queue_size the same as -thread_queue_size?
-max_muxing_queue_size and -thread_queue_size are two different options. -max_muxing_queue_size is an output option controlling packets held by the muxer, while -thread_queue_size is an input option controlling the demuxer's thread message queue and produces the separate "Thread message queue blocking" warning.
If you'd rather spend your time on the workflow than on which FFmpeg build is on which box, run the encode as a job instead of a process: send the input, take the webhook, download the result. Sign up free and try it against the file that's been failing.
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

FFmpeg Audio Out of Sync Isn't the Codec. It's the Frame Rate
FFmpeg audio out of sync is usually a variable-frame-rate source hitting a fixed -r. Detect VFR with ffprobe, then fix it with -fps_mode cfr and aresample.

Fix FFmpeg's "height not divisible by 2" Error on User Uploads
FFmpeg's "height not divisible by 2" error is a yuv420p chroma constraint, not a broken file. Three fixes (scale=-2, trunc, pad) with measured output sizes.

Non-monotonous DTS Isn't Noise. It's Truncating Your Joins.
Non-monotonous DTS in output stream: what the warning means, when -fflags +genpts or -reset_timestamps 1 is right, and when only a CFR re-encode fixes it.
Ready to process videos at scale?
Start using FFmpeg Micro's simple API today. No infrastructure required.
Get Started Free