Compress a video to fit a hard upload limit

Pick the limit, land under it

Drop a video anywhere on this page. The bitrate is solved backwards from the ceiling you have to hit — Discord, WhatsApp, Gmail or your own number — and shown before a single frame is encoded.

  • MP4
  • MOV
  • WebM
  • MKV
Or drop a file anywhere on this page
01Solved, not guessed
Target bytes, minus audio, minus container overhead, over duration. No slider, no second attempt.
02Honest resolution
When the bitrate cannot carry the pixels, the frame comes down and the page says why.
03No upload
Decoding and encoding happen in this tab with WebCodecs. Nothing leaves the device.
Compressing to a size, in depth

The arithmetic behind a file that fits

Compressing to a hard limit is arithmetic, not a slider

Every upload ceiling is a fixed number of bytes: Discord's free tier stops at 10 MB, WhatsApp at 16 MB, a Gmail attachment at 25 MB. None of them care how good your video looks, only whether the byte count is under the line. That makes "compress this video" solvable rather than a matter of taste — and it is solved backwards, from the target rather than the source.

The equation

A video file is, to a first approximation, a bitrate multiplied by a duration. Turn that around and the bitrate you are allowed becomes a subtraction:

video_bitrate = (target_bytes × 8 × (1 − overhead)) / duration − audio_bitrate

Every term earns its place. The × 8 converts bytes to bits, because limits are quoted in bytes and bitrates in bits; dropping that factor is how people end up eight times over the line. (1 − overhead) reserves room for the container — MP4 headers, the moov atom, sample tables and per-frame boxes are all real bytes that are not picture, and four per cent is a sane reserve. − audio_bitrate subtracts the soundtrack, which competes for the same budget and is the term almost everyone forgets.

A worked example: 42 seconds into 10 MiB

Take a 42-second clip that has to fit Discord's free tier. That limit is 10 MiB — 10,485,760 bytes — because that is how it is enforced.

  1. 10,485,760 bytes × 8 = 83,886,080 bits, the entire budget.
  2. × 0.96 to reserve container overhead = 80,530,637 bits of payload.
  3. ÷ 42 seconds = 1,917,396 bits per second for picture and sound together.
  4. − 96,000 bps of AAC audio = 1,821,396 bps, about 1.82 Mbps, for the video.

Run it back through the same arithmetic as a check — (1,821,396 + 96,000) × 42 ÷ 8 ÷ 0.96 — and you land on 10,485,759 bytes. One byte under 10 MiB. There is no guessing step anywhere in that, which is the point.

Why a quality slider cannot hit a hard cap

Most compressors hand you a slider marked Low to High, or a CRF number if they are being honest about the underlying knob. Constant Rate Factor tells the encoder how much distortion to tolerate and then spends whatever bitrate that costs. A static talking head at CRF 23 might cost 900 kbps; forty seconds of confetti and camera shake at the same CRF might cost 6 Mbps. Same setting, same perceived quality, seven times the file.

That is a feature when you want consistent quality across a library, and useless against a ceiling, because a ceiling is pass or fail: 10.2 MB against a 10 MB limit fails no matter how good the picture is. A slider can only be aimed by trial and error — compress, check, adjust, compress again. Solving for the bitrate first turns that into one pass with a predictable outcome.

Bits per pixel, and the resolution ladder that follows

Knowing the bitrate is only half of it. The same 1.82 Mbps is generous for a 480p clip and hopeless for 4K, because what the encoder actually experiences is bits spread over pixels over time. The useful unit is bits per pixel per frame:

bpp = bitrate / (width × height × frame_rate)

For H.264, roughly 0.09 bpp is where a frame looks like the source. Around 0.05 is the floor: below that the encoder runs out of bits for detail, gives up on high-frequency texture and starts emitting visible 16×16 blocking. Fix bpp at 0.09 and the arithmetic produces a resolution ladder — multiply the pixel count by the frame rate, then by 0.09:

ResolutionPixels × 30 fpsComfortable (0.09 bpp)Floor (0.05 bpp)
1920×108062,208,0005.60 Mbps3.11 Mbps
1280×72027,648,0002.49 Mbps1.38 Mbps
854×48012,297,6001.11 Mbps0.61 Mbps
640×3606,912,0000.62 Mbps0.35 Mbps

Double the frame rate and every figure doubles: 1080p60 wants about 11.2 Mbps to sit at 0.09 bpp. That one fact explains most disappointing compressions — a 60 fps phone recording asks for twice the budget of the same shot at 30.

Back to the worked example. 1.82 Mbps over a 1080p30 frame is 1,821,396 ÷ 62,208,000 = 0.029 bpp, less than a third of the target and well under the floor. Asking an encoder for 1080p at that rate does not produce a small 1080p file; it produces a smeared, blocky one. Since pixel count scales with the square of the linear scale factor, the fix is to scale by √(0.029 ÷ 0.09) = 0.57, landing on roughly 1096×616 — where the same 1.82 Mbps is back at 0.090 bpp. A clean 1096×616 file beats a broken 1920×1080 one at identical bytes. When this tool reduces your resolution it is telling you the bitrate cannot carry the pixels you have.

What the platforms actually allow

DestinationCeilingNote
Discord, free account10 MBPer file, the single most searched limit on the internet
Discord Nitro Basic50 MBApplies per upload, not per message
Discord Nitro500 MBEnough that bitrate, not size, becomes the constraint
WhatsApp16 MBWhatsApp also re-encodes on its own, so arrive under the line
Gmail attachment25 MBAbove this Gmail substitutes a Drive link

Treat those as of the time of writing: platforms change ceilings, run regional variations and occasionally raise them without announcing it. If your number is not in the list, type it into the custom field — the arithmetic does not care where the figure came from.

Two-pass ABR versus CRF

Once you have a bitrate, there is still a choice about how the encoder spends it, and it is the choice that decides whether you hit the target.

  • CRF gives predictable quality and unpredictable size. Right for archiving, for uploads to a platform that will re-encode anyway, and for anything without a hard ceiling.
  • Two-pass average bitrate gives predictable size and lets quality land where it lands. The first pass analyses the clip and writes a statistics file; the second spends the fixed budget where the first pass found the complexity. Right for a hard cap.

Single-pass ABR is worse than both: the encoder must guess at complexity it has not seen yet, so it overshoots early and starves the end of the clip. The second pass is what you are paying for. In FFmpeg, with the numbers solved above:

ffmpeg -i input.mp4 -c:v libx264 -b:v 1821k -vf scale=1096:616 \
  -pass 1 -an -f null /dev/null && \
ffmpeg -i input.mp4 -c:v libx264 -b:v 1821k -vf scale=1096:616 \
  -pass 2 -c:a aac -b:a 96k output.mp4

On Windows, replace /dev/null with NUL. Pass one writes ffmpeg2pass-0.log into the working directory, which you can delete afterwards. The tool above prints this command with your own solved figures already substituted.

Dropping the audio is the highest-leverage switch you have

Audio is a fixed cost per second, and on a tight budget that cost is brutal. At 96 kbps a soundtrack consumes 96,000 × duration ÷ 8 bytes: 492 KiB over 42 seconds, 1.03 MiB over 90 seconds, 2.06 MiB over three minutes. Against a 10 MiB ceiling that last figure is a fifth of the entire budget spent on sound.

Hand it back to the picture and the video bitrate on that three-minute clip rises from about 370 kbps to 466 kbps — a 26 per cent increase, which in bpp terms is one whole rung of the resolution ladder. For a screen recording, a silent timelapse, or anything destined for a feed that autoplays muted, dropping the track is free quality, and it is the first thing to try when the plan panel says your target is out of reach.

Honest limits

There is no server here, which has consequences worth stating plainly. Decoding and encoding happen in your own browser through the WebCodecs API, so nothing is uploaded and nothing retained. But the output is assembled in memory before it is handed to you, so a very long source can exhaust the tab. A few minutes at 1080p is comfortable on an ordinary laptop; for a half-hour recording, trim it first or reach for FFmpeg on the command line.

Two more caveats. Encoding is variable-bitrate, so the finished file moves a percentage point or two either side of the prediction — which is exactly why four per cent of the budget is reserved rather than spent. And browser encoders differ: where no H.264 encoder is available the output is VP9 in WebM, a better codec at the same bitrate but not accepted everywhere an MP4 is. The output panel says which one you got.

And an impossible target is reported as impossible. Below roughly 50 kbps there is no resolution at which the result is worth shipping, so if your duration and ceiling cannot be reconciled the tool says so rather than producing mush and calling it success. Shorten the clip or raise the limit — those are the only two answers.

Questions

Why not just pick a quality setting?
Because a quality setting cannot promise a size. A hard upload cap is pass or fail: 10.2 MB against a 10 MB limit is a failure no matter how good it looks. Solving for the bitrate from the target and the duration is the only approach that reliably lands under the line.
Why did my 1080p video come back at 720p or 480p?
Because the bitrate your target allows could not carry 1080p. Below roughly 0.05 bits per pixel per frame, H.264 stops resolving detail and starts producing blocks. A clean 480p file at the same size looks better than a broken 1080p one, so the resolution is reduced to fit the bitrate.
What is Discord’s actual upload limit?
Ten megabytes on a free account, 50 MB on Nitro Basic and 500 MB on Nitro at the time of writing. These change, so there is also a free-text field — type whatever number you have been given.
How accurate is the predicted size?
Usually within a few per cent, and deliberately biased to land under the target: four per cent of the budget is reserved for container overhead and the audio is costed at 96 kbps. Variable-bitrate encoding means the exact figure moves a little run to run, which is why the headroom is there.
Can I drop the audio to save space?
Yes, and on a very tight ceiling it is the highest-value switch you have. On a 10 MB, three-minute clip the audio track is around 2 MB — roughly a fifth of the entire budget handed back to the picture.

Other local video tools

All tools

Start processing

Drop a clip in and pick the limit. The plan is on screen before anything is encoded.