Instagram Reels need 30 FPS minimum: conform a 24 fps AI clip

Instagram's Reel help page lists a 30 FPS minimum. Probe a clip's frame rate, then conform 24 or 25 fps footage to 30 with Sume's video trim output.fps.

2 min readSume
All posts

Instagram's help page on Reel size lists a minimum frame rate of 30 FPS, so a 24 fps clip sits below it. Conform the clip to 30 fps before you publish, and read its frame rate first so you only re-encode files that need it.

The page, Reel size & aspect ratios on Instagram (read 2026-10-03), gives three rules: an aspect ratio between 1.91:1 and 9:16, a minimum frame rate of 30 FPS, and a minimum resolution of 720 pixels. This post covers the frame rate only. Footage cut for cinema, or assembled from several sources, often runs at 24 or 25 fps.

Read the frame rate first

Video inspect reads one Sume-hosted clip and returns a probe object. probe.fps is the frame rate, and frames: false asks for the probe without stills. The clip has to be on media.sume.com already, so import a file from elsewhere first. Inspect is billed by its Modal compute rather than a flat rate, so confirm the live figure in the catalog before a big batch.

Conform with video trim

Video trim takes an optional output object with width, height and fps, where fps is 24, 25, 30 or 60. It only works with the default exact precision, a frame-accurate re-encode; the keyframe stream copy refuses an output field. Set start to 0 and duration to the clip length to keep the whole clip. A trim costs $0.02 per job, and a source can run up to 1800 seconds with an output of up to 900.

What 24 to 30 does to motion

A different rate cannot be reached without inventing or dropping frames. The Timeline docs describe the mechanism: a rate that differs from a source's is met by repeating or dropping a frame every few frames, which shows as judder on motion. The arithmetic for each common source rate is below.

Frames repeated or dropped per second to reach 30 fps; arithmetic from Instagram's 30 FPS minimum (read 2026-10-03)
Source fpsChange per second at 30 fpsAction
246 frames repeatedConform to 30
255 frames repeatedConform to 30
30NoneLeave alone
60Not below the minimumLeave alone

Probe, then conform only if needed

The script probes a clip and submits a trim only when fps is under 30. Set SUME_API_KEY first.

import json, os, time, urllib.request as u

def call(method, path, body=None, key=None):
    h = {"Authorization": "Bearer " + os.environ["SUME_API_KEY"],
         "Content-Type": "application/json"}
    if key:
        h["Idempotency-Key"] = key
    data = json.dumps(body).encode() if body is not None else None
    req = u.Request("https://api.sume.com" + path, data, h, method=method)
    with u.urlopen(req) as r:
        out = json.load(r)
    return out.get("data", out)

def probe(url, key):
    d = call("POST", "/v1/video-inspect", {"video_url": url, "frames": False}, key)
    for _ in range(30):
        if d.get("probe"):
            return d["probe"]
        time.sleep(2)
        d = call("GET", "/v1/video-inspect/" + d["id"])
    raise TimeoutError("probe not ready")

URL = "https://media.sume.com/artifacts/artf_demo/clip.mp4"
p = probe(URL, "probe-clip-001")
if p["fps"] and p["fps"] < 30:
    call("POST", "/v1/video-trim", {"video_url": URL, "start": 0,
         "duration": p["duration_seconds"], "output": {"fps": 30}}, "conform-clip-001")

If the clip goes into a Timeline render anyway

Skip the separate trim and set output.fps to 30 on the Timeline render. The docs say an omitted output.fps renders at the rate the sources already run at, so a set of 24 fps clips comes out at 24 unless you ask. Setting 30 does one encode instead of one per clip, and the render reports output_fps_resamples_sources so you can see the resample happened.

I could not confirm from the help page what Instagram does to a file under 30 FPS, so treat the figure as a gate for your own checks rather than a documented rejection.

Sources

Related posts

More in Media tools

All Media tools posts

Written by Sume