DEV Community

Javid Jamae
Javid Jamae

Posted on • Originally published at ffmpeg-micro.com

FFmpeg CRF Explained: Quality vs File Size Guide

Originally published at ffmpeg-micro.com

Every video encoder faces the same tradeoff: quality vs. file size. CRF (Constant Rate Factor) is how FFmpeg lets you control that tradeoff with a single number.

Most guides say "just use CRF 23." That's fine for a quick transcode, but CRF 23 means completely different things depending on your codec, your content, and where you're delivering. This guide covers what CRF actually does, how the scale works across codecs, and how to pick the right value.

What Is CRF in FFmpeg?

CRF is a rate control mode that targets consistent perceptual quality across an entire video, letting the bitrate float as needed. Simple scenes (static shots, solid colors) get fewer bits. Complex scenes (fast motion, fine detail) get more bits. The result is a file where quality looks consistent to your eyes, even though the bitrate varies frame to frame.

ffmpeg -i input.mp4 -c:v libx264 -crf 23 output.mp4
Enter fullscreen mode Exit fullscreen mode

Lower CRF always means higher quality and larger files. CRF 0 is mathematically lossless (and produces enormous files). The default for libx264 is 23.

CRF Scale by Codec

CRF values are not universal. Each codec has its own scale, and the same number produces different quality levels.

Codec Encoder CRF Range Default Visually Lossless Good Balance Small File
H.264 libx264 0-51 23 17-18 20-23 28-30
H.265/HEVC libx265 0-51 28 20-22 24-28 32-35
VP9 libvpx-vp9 0-63 31 15-20 25-31 35-40
AV1 libaom-av1 0-63 32 20-25 28-32 38-45

CRF 23 in H.264 is not the same quality as CRF 23 in H.265. H.265 is a more efficient encoder, so its default is CRF 28 to produce roughly comparable quality.

A useful rule of thumb for H.264: every +6 CRF roughly halves the file size.

CRF Examples for Each Codec

H.264 (most common):

ffmpeg -i input.mp4 -c:v libx264 -crf 20 -preset medium -c:a aac -b:a 192k output.mp4
Enter fullscreen mode Exit fullscreen mode

H.265/HEVC (better compression, slower):

ffmpeg -i input.mp4 -c:v libx265 -crf 24 -preset medium -c:a aac -b:a 192k output_hevc.mp4
Enter fullscreen mode Exit fullscreen mode

VP9 (WebM, used by YouTube internally):

ffmpeg -i input.mp4 -c:v libvpx-vp9 -crf 30 -b:v 0 -c:a libopus output.webm
Enter fullscreen mode Exit fullscreen mode

VP9 requires -b:v 0 alongside CRF. Without it, the encoder applies a default bitrate cap that overrides your CRF setting.

AV1 (best compression, slowest encoding):

ffmpeg -i input.mp4 -c:v libaom-av1 -crf 30 -cpu-used 4 -c:a libopus output.mkv
Enter fullscreen mode Exit fullscreen mode

Common CRF Pitfalls

Forgetting -b:v 0 with VP9. VP9 ignores your CRF and uses a default bitrate cap instead. Always add -b:v 0 when using CRF with libvpx-vp9.

Comparing CRF across codecs. CRF 23 in H.264 produces different quality than CRF 23 in H.265. Use the table above when switching codecs.

Using CRF 0 for "best quality." CRF 0 is lossless and creates enormous files. CRF 17-18 is visually indistinguishable from lossless for H.264, at a fraction of the size.

FAQ

What CRF should I use for H.264? CRF 23 is the default and works for most cases. For archiving or YouTube uploads, drop to CRF 18-20. For web delivery or mobile, use CRF 26-28.

Does CRF 18 in H.265 equal CRF 18 in H.264? No. H.265 is more efficient, so CRF 18 in H.265 produces higher quality than CRF 18 in H.264.

Why is VP9 ignoring my CRF setting? Add -b:v 0. VP9 in FFmpeg applies a default bitrate cap even when CRF is set.

Read the full guide with API examples and more use cases at ffmpeg-micro.com/blog/ffmpeg-crf-explained.

Top comments (0)