FFmpeg CRF explained and measured

Compare FFmpeg CRF from 18 to 32 on one file. Every 3 points of CRF removed about a fifth of the bytes, and the encode time barely moved at all.

Share

CRF is the dial almost everyone turns and almost nobody measures. The advice is always a range, usually “18 to 28, lower is better”, which tells you nothing about what a step actually buys.

Short version. On this clip the relationship is close to a clean 20% reduction per 3 points of CRF, and encode time does not meaningfully track it. Choosing a higher CRF is one of the few pure wins available: smaller files at no extra compute cost.

x264 CRF
What does each step of CRF actually cost in bytes?
Held constant: libx264, preset medium, 5 seconds of the same source
Bar chart. x264 CRF. Encode time and output size for each variant, each metric scaled to its own maximum.
VariantEncodeSizeCost
CRF 182216 ms665.8 KB$0.0038
CRF 201938 ms551.9 KB$0.0036
CRF 23982 ms433.0 KB$0.0025
CRF 262384 ms338.1 KB$0.0038
CRF 28967 ms282.5 KB$0.0025
CRF 301200 ms233.8 KB$0.0026
CRF 32854 ms fastest186.8 KB$0.0023
Measured 2026-08-20 on the Rendobar API. Encode time is the FFmpeg step alone, separated from download and upload. 7 of 7 runs succeeded. Sizes are exact and repeatable. Timings are a single sample and vary up to 2x run to run, so treat small differences as noise. Why.

The size curve is remarkably regular

Reading the sizes:

CRFSizeChange
18665.8 KB
20551.9 KB−17%
23433.0 KB−22%
26338.1 KB−22%
28282.5 KB−16%
30233.8 KB−17%
32186.8 KB−20%

Across the whole usable range, CRF 18 to CRF 32 is a 3.6x difference in file size. Each 3-point step removes roughly a fifth of what is left, which is the compounding behaviour you would expect from a quantiser and is a useful mental model to carry: +3 CRF is about −20%.

Encode time does not follow

This is the part worth internalising. The fastest run was CRF 32 at 854 ms and the slowest was CRF 18 at 2,216 ms, but the values in between did not form a slope. CRF 26 took 2,384 ms while CRF 28 took 967 ms, on the same preset and the same source.

Do not read a trend into that. What it says is that at a fixed preset, encode time is dominated by the preset’s search behaviour and by ordinary run-to-run variance on a short clip, not by the quantiser setting. There is no meaningful compute penalty for choosing a lower CRF, and no compute saving from choosing a higher one.

So the decision is unusually clean: CRF trades file size against visual quality, and essentially nothing else.

Where the free lunch is

If you are on CRF 23, which is x264’s default and the most common setting in the wild, moving to CRF 26 removes 22% of your bytes for a quality difference that most viewers will not spot on typical content at typical viewing distances.

That is the single cheapest decision in the range. Below CRF 20 you are spending a lot of bytes on detail that survives neither a phone screen nor a second transcode downstream. Above CRF 30 the artefacts start being visible on flat areas and gradients, which is where banding shows up first.

The caveat that actually matters

CRF is a quality target, not a size target, and that is the whole reason it works. The encoder spends whatever bytes it needs to hold the quality you asked for. Feed it a grainy, high-motion source and the same CRF will produce a far larger file, because holding quality on grain is expensive.

This is why “use CRF 23 and expect 400 KB” is not a thing anyone can promise you. The 20%-per-3-points relationship should travel to your content. The absolute byte counts will not.

If your requirement is a size, CRF is the wrong tool and you want a target-size search instead, which is a different job entirely.

Method

Seven encodes, libx264, preset medium, audio stripped, five seconds of the same 1280x720 source, run through the Rendobar API. Encode time is the FFmpeg step alone, separated from the download and the upload. Total cost $0.0211.

Every command is in the table above, and each is a single API call.

CRF is one of seven settings measured on this same source. The rest are in FFmpeg encoding settings compared.

Frequently asked questions

What CRF should I use for H.264?

23 is x264's default and 26 is usually the better trade for web delivery. We measured CRF 26 as 22% fewer bytes than CRF 23, a difference most viewers will not notice on typical content.

How much does each CRF step save?

Roughly 20% of the remaining bytes per 3 points of CRF, measured across CRF 18 to 32. The full range was a 3.6x difference in file size.

Does a higher CRF encode faster?

No, not meaningfully. Encode time is dominated by the preset's search behaviour, not by the quantiser, so choosing a higher CRF is close to a pure size saving with no compute cost.

Can CRF hit a target file size?

No. CRF is a quality target, so the bytes fall where the content demands. If you need a specific size you want a target-size search or two-pass ABR instead.

Sources

Tags #ffmpeg#crf#x264#encoding#benchmarks
All posts
Share
  1. Opus vs AAC vs MP3 vs FLAC Engineering blog
  2. AV1 vs H.264 VMAF compared Engineering blog
  3. AV1 vs VP9 vs HEVC vs H.264 Engineering blog