File-size cap and max length: the average bitrate ceiling
Divide a platform's size cap by its longest allowed video to get an average bitrate ceiling: LinkedIn about 2.2 Mbps, TikTok 6.7, Pinterest 17.8. Python check.

Each platform caps file size and length separately, so a long video has to fit under an average bitrate that you can compute. Divide the cap in bits by the longest allowed length in seconds. The longest LinkedIn ad lands near 2.2 Mbps, while a maximum-length Pinterest ad can run near 17.8 Mbps.
What are the caps? (read 2026-10-09)
Sizes are taken as decimal (1 MB is 1,000,000 bytes); a binary reading lowers the ceiling slightly. A shorter video can use a higher rate. TikTok also lists a 516 kbps floor for non-Spark ads.
| Platform and format | Size cap | Max length | Average ceiling |
|---|---|---|---|
| LinkedIn video ad | 500 MB | 30 min | about 2.2 Mbps |
| TikTok non-Spark ad | 500 MB | 10 min | about 6.7 Mbps |
| Pinterest video ad | 2 GB | 15 min | about 17.8 Mbps |
| Instagram Reels ad | 4 GB | 15 min | about 35.6 Mbps |
| X video, default | 8 GB | 20 min | about 53.3 Mbps |
| X video, Premium | 16 GB | 125 min | about 17.1 Mbps |
How do you read your own file?
The video_inspect probe returns size_bytes and duration_seconds but no bitrate field, so compute it. The probe is billed by its Modal compute, not a fixed fee, and the source can be up to 1800 seconds.
def mbps(size_bytes, seconds):
return size_bytes * 8 / seconds / 1e6
def ceiling(cap_mb, minutes):
return cap_mb * 8 / (minutes * 60)
# replace with values from your own probe
probe = {"size_bytes": 310_000_000, "duration_seconds": 1500.0}
actual = mbps(probe["size_bytes"], probe["duration_seconds"])
print(f"actual {actual:.2f} Mbps")
for name, cap, mins in [("LinkedIn", 500, 30), ("TikTok", 500, 10), ("Pinterest", 2000, 15)]:
c = ceiling(cap, mins)
print(name, f"{c:.1f} Mbps", "ok" if actual <= c else "over")What do you do if the file is over?
Two cautions. First, the ceiling is an average over the longest permitted video, so a 60-second clip can run far above it and still fit the size cap. Second, a size cap is not a quality target: a platform may re-encode your upload anyway. Use the number to catch files that will be rejected, not to tune picture quality.
- Cut it shorter with video_trim ($0.02 per job); size falls with length.
- Re-encode smaller with the trim output option (width and height 256 to 2160, fps 24, 25, 30 or 60), valid for precision exact.
- Docs do not expose a bitrate setting on these tools, so lowering resolution or frame rate is the lever Sume offers.
Sources
Related posts
More in Developers
- Before a 20-clip MCP burst: dry_run, admission preview, max_spend_usd
A single Sume MCP create needs none of these. A 20-job burst should use dry_run or generation_admission_preview, set max_spend_usd, and wait in one jobs_wait.
- Duration dropdown from supported_durations: 27, 29 and 8 choices
Seedance 2.5 offers 27 lengths, Wan 3.0 29, Omni Flash 1.1 8. Map supported_durations to options in TypeScript, with the price of the longest option.
- Timeline body from a cut list in TypeScript: starts and coverage
Turn a cut list of source ranges into Timeline slots: starts are running sums rounded to 3 decimals, and 3 ranges of 3.55, 4.68 and 3.36 s make 11.59 s.
- Build the pricing_skus key from the resolution string: 4K is uppercase
Omni Flash 1.1 rates sit at per-video-second-360p, -720p, -1080p and -4K. Build the key from a template, mind the 4K case, total 10 s from $0.375 to $3.75.
Written by Sume