FFmpeg Instagram Reels Settings: Every Flag, Sourced

Sep 20, 2026

Instagram does publish encoder-level requirements for Reels — profile, entropy coder, B-frames, GOP length, chroma subsampling — but they sit inside a collapsed "Additional technical details" block that you have to click open to see. Almost nothing written about FFmpeg settings for Reels quotes that block, which is why most of the commands you will find are somebody's preference dressed up as a spec.

This page does the boring thing instead: every line Instagram actually wrote, mapped to the flag that expresses it, with the publishing channel it belongs to.

The command

ffmpeg -i input.mov \
  -c:v libx264 -profile:v high -coder 1 -bf 2 \
  -flags +cgop -g 15 -pix_fmt yuv420p -r 30 \
  -crf 20 -maxrate 25M -bufsize 50M \
  -c:a aac -ar 48000 -ac 2 -b:a 128k \
  -movflags +faststart reel.mp4

One thing has to be said plainly: Instagram does not publish FFmpeg commands. It describes the file it wants. The flags above express that description, and FFmpeg's own documentation is where to confirm what each one does on your build. Where Instagram is silent, this page says so rather than filling the gap.

What each flag does, and where the requirement comes from

Instagram's help centre page on Reel size and aspect ratios carries a collapsed section that opens with this sentence, verbatim:

"The requirements listed above should work for most people who are sharing a reel to Instagram. However, if you need more technical details to help you upload, please follow the requirements listed below."

Under Video codec, that block lists exactly six lines. Here they are with their FFmpeg counterparts:

Instagram's line (verbatim)Flag
"Progressive scan (no interlacing)."deinterlace the source if it is interlaced
"High profile."-profile:v high
"CABAC."-coder 1
"2 consecutive B frames."-bf 2
"Closed GOP. GOP of half the frame rate."-flags +cgop and -g
"Chroma subsampling: 4:2:0."-pix_fmt yuv420p

Three of those deserve more than a table row.

"GOP of half the frame rate" carries a real instruction and gets ignored everywhere. The keyframe interval is tied to your frame rate, not to a fixed number of seconds: at 30 fps that is -g 15, at 60 fps -g 30, at 24 fps -g 12. Instagram is asking for a keyframe every half second. If you change -r, change -g with it or you have quietly stopped following the spec.

"Closed GOP" is a separate requirement from the length. FFmpeg exposes a closed-GOP flag; whether your encoder already produces one by default depends on the build, so check ffmpeg -h encoder=libx264 rather than assuming.

"Progressive scan (no interlacing)" only matters for interlaced sources — camcorder footage, broadcast captures. FFmpeg ships several deinterlacing filters; pick one from the official filter documentation.

Under Audio codec, the same block lists two lines: "Channels: Stereo or Stereo + 5.1." and "Sample rate 96khz or 48khz." Note what is not there — no codec name, no bitrate.

The half of the command Instagram's help page never mentions

Here is the trap. That block gives you profile, entropy coder, B-frames, GOP and chroma — and names no video codec, no bitrate, no file size and no duration. libx264, -crf, -maxrate and -movflags are not in it.

Those come from a document with a different scope: Meta's Graph API Reel specifications, which govern posting through a scheduling tool or your own integration, not tapping Share in the app. Verbatim:

"Container: MOV or MP4 (MPEG-4 Part 14), no edit lists, moov atom at the front of the file." "Video codec: HEVC or H264, progressive scan, closed GOP, 4:2:0 chroma subsampling." "Audio codec: AAC, 48khz sample rate maximum, 1 or 2 channels (mono or stereo)." "Frame rate: 23-60 FPS." "Video bitrate: VBR, 25Mbps maximum" "Audio bitrate: 128kbps" "Maximum columns (horizontal pixels): 1920"

So -c:v libx264 is defensible because the API page names H264. -maxrate 25M exists because the API caps video bitrate at 25 Mbps and asks for VBR — -crf is a variable-bitrate mode, and -maxrate with -bufsize puts a ceiling on it. -bufsize 50M is two seconds of buffer at that ceiling; that number is a choice, not Instagram's.

-movflags +faststart maps to "moov atom at the front of the file", paired with "no edit lists" in the same sentence. It explains files that are valid MP4s with correct parameters and still fail an API upload — see FFmpeg faststart and the moov atom for the container-only version.

-ar 48000 -ac 2 -b:a 128k is the intersection of the two lists. The help centre allows 96 kHz or 48 kHz and stereo or stereo + 5.1; the API allows 48 kHz maximum and one or two channels. 48 kHz stereo is the only combination on both. The 128 kbps figure is the API's.

Frame rate and picture size

The help centre says Reels "should have a minimum frame rate of 30 FPS (frames per second) and minimum resolution of 720 pixels." The API says "23-60 FPS." So 30–60 fps satisfies both, while a 24 fps film-look export satisfies the API and falls below what the help centre asks. If your source is already in that window, drop -r rather than resampling for no reason.

On picture size, note what the pages actually say. The help centre's "minimum resolution of 720 pixels" does not state whether that is width or height. The API's maximum of 1920 horizontal pixels is not a constraint a vertical 9:16 Reel will hit; it bites landscape and square masters. Aspect ratio in the app is "between 1.91:1 and 9:16"; the API accepts "between 0.01:1 and 10:1 but we recommend 9:16 to avoid cropping or blank space."

The 1080x1920 that every specs listicle calls the official Reels resolution is on neither page. Its real source is Meta's ads guide, under Instagram Feed video ads for the Awareness objective — while the Reels ads page recommends 1440 x 2560 for the Awareness objective. Neither is the in-app spec; the three-way comparison is in Instagram Reels video specs.

Variations

Source already in range, just fix the container:

ffmpeg -i input.mp4 -c copy -movflags +faststart reel.mp4

60 fps source: keep the frame rate and move the GOP with it — drop -r 30 and use -g 30. Everything else in the main command is unchanged.

Posting through the API, where a 300MB ceiling and a 15-minute duration limit apply (both API-only figures): raise -crf before you touch resolution. Instagram publishes no file size limit at all for in-app posting — see Instagram Reels file size limit for why the widely quoted 650MB has no source.

If you would rather not install FFmpeg

For a one-off clip that is simply too big for the upload you are attempting, the same job runs in a browser tab:

Try it right here

Runs in your browser. Your file is not uploaded anywhere.

Loading tool…

The file is read from disk, re-encoded locally and handed back — nothing is uploaded on the way to fixing an upload, which matters for unpublished footage. Be clear about the trade: the vertical-video compressor gives you a sane H.264 MP4, not a checkbox for GOP length or entropy coder. For the flags Instagram names, the command line is the right tool. The rest are at all Clapr tools.

Troubleshooting

The API returns a container ID but the Reel never publishes. Meta documents that "Video uploads are asynchronous, so receiving a container ID does not guarantee that the upload was successful," and tells you to poll status_code until it reads FINISHED. If it reads ERROR, Meta's only explanation is "The container failed to complete the publishing process" — no reason given, so check faststart and edit lists first.

Audio is fine locally but a scheduling tool rejects the upload. The API allows "1 or 2 channels (mono or stereo)." A 5.1 mix is allowed by the help centre for in-app posting and is outside the API's list. -ac 2 resolves it.

The clip looks softer after posting. Instagram has never published its transcoding target, so nobody can tell you what it re-encodes to. What is documented is an upload-quality toggle you have to turn on yourself: in the app, Menu → "Below Your app and media, tap Media quality" → "Next to Upload at highest quality, tap Toggle to turn on."

FAQ

What FFmpeg settings does Instagram officially require for Reels? For in-app posting, the help centre lists High profile, CABAC, 2 consecutive B frames, closed GOP of half the frame rate, 4:2:0 chroma and progressive scan — no codec name, no bitrate. Codec, bitrate, duration and file size come from the separate Graph API page.

What GOP size should I use for Instagram Reels? Half your frame rate, per Instagram's own wording: -g 15 at 30 fps, -g 30 at 60 fps. It must be a closed GOP.

Is 1080x1920 the official Instagram Reels resolution? No. That figure comes from Meta's ads guide for Instagram Feed video ads. The in-app help page only states a minimum resolution of 720 pixels — without specifying width or height — and Meta's Reels ads page recommends 1440 x 2560 for the Awareness objective.

What bitrate should I encode a Reel at? Instagram publishes no recommended or minimum bitrate for in-app posting. The only official number is the API's ceiling: "VBR, 25Mbps maximum". Use CRF for quality and -maxrate as a cap if you are posting through the API.

Do I need -movflags +faststart? It is named in the API specifications ("moov atom at the front of the file") and is not mentioned in the in-app help page. It costs one remux, so there is no reason to skip it.


Instagram quotes are from the official help centre page on Reel size and aspect ratios, and from Meta's IG User Media and ads guide documentation, checked 16 September 2026. Meta revises these pages and its three sets of specs disagree with each other — verify before relying on any single number. More command-line write-ups are in our ffmpeg guides.

Clapr team

Clapr team

FFmpeg Instagram Reels Settings: Every Flag, Sourced | Clapr Blog