One FFmpeg command can make a video small enough to email or quick to upload.

In the test below, H.264 at CRF 23 took the test clip from 29.3 MB to 7.12 MB (-75.7%, VMAF 93.29). VMAF is a quality score that compares the result with the source; higher is better.

Command Examples

1. CRF Mode with H.264 (Most Versatile)

ffmpeg -i input.mp4 -c:v libx264 -crf 23 -preset medium -c:a aac -b:a 128k output.mp4
  • -c:v libx264: encode the video as H.264
  • -crf 23: the quality setting, from 0 to 51. Lower means better quality and a bigger file. The default is 23.
  • -preset medium: a balance between encoding speed and compression
  • -c:a aac -b:a 128k: re-encode the audio to AAC at 128 kbps

2. Higher Compression with H.265 (HEVC)

On the test clip, H.265 files were 26–35% smaller than H.264 files with the same VMAF score, and took about twice as long to encode (how this was measured).

ffmpeg -i input.mp4 -c:v libx265 -crf 28 -preset medium -c:a aac -b:a 128k output.mp4

3. Small-Size Priority (Social Media / Email Attachment)

ffmpeg -i input.mp4 -c:v libx264 -crf 32 -preset fast -vf scale=1280:-2 -c:a aac -b:a 96k output.mp4
  • -crf 32: lower quality for a smaller file
  • -vf scale=1280:-2: shrink to 1280px wide, with the height set automatically to an even number
  • -b:a 96k: a lower audio bitrate as well

4. High-Quality Archive (Time Not a Constraint)

ffmpeg -i input.mp4 -c:v libx265 -crf 22 -preset slow -c:a aac -b:a 192k output.mp4

5. Bitrate-Controlled Compression (Strict Size Target)

Use this when you need a predictable file size. The bitrate is the amount of data per second, so the file size is roughly bitrate × duration. -b:v sets the average bitrate, so some scenes can go above it. If a platform sets a maximum bitrate, also add -maxrate and -bufsize (for example -maxrate 2000k -bufsize 4000k).

# Video 2 Mbps + audio 128 kbps ≈ 2.1 Mbps total
ffmpeg -i input.mp4 -c:v libx264 -b:v 2000k -c:a aac -b:a 128k output.mp4

6. 2-Pass Encoding (Most Accurate Size Control)

# Pass 1: analyze video (no output generated)
ffmpeg -i input.mp4 -c:v libx264 -b:v 2000k -pass 1 -an -f null /dev/null

# Pass 2: generate the actual output
ffmpeg -i input.mp4 -c:v libx264 -b:v 2000k -pass 2 -c:a aac -b:a 128k output.mp4

Pass 1 creates ffmpeg2pass-0.log. You can delete it once pass 2 has finished.

Measured Results

These figures come from encoding one test clip; the table below lists the clip and the machine. VMAF predicts how good the video looks to viewers. It does not test for identical pixels, and no single score is a pass mark for every use. Compare scores only when the VMAF model and comparison settings are the same, and look at the frames too. The official VMAF FAQ notes that a video compared with itself need not score 100.

Measured chart of output file size against VMAF quality for H.264 and H.265; at the same VMAF the H.265 files are 26–35% smaller

File size runs along the bottom and VMAF up the side. Points nearer the top left are smaller and look better. The number next to each point is its CRF value, and the tables below give the exact figures.

CPU / GPU Intel Core i9-14900KF / NVIDIA RTX 4090
FFmpeg 8.1 (gyan.dev full build)
Source Big Buck Bunny 1920x1080 / 30 fps / 10.0 s / H.264 24.6 Mbps / 29.3 MB (no audio track)
Source licence © Blender Foundation, CC BY 3.0
Measured 2026-08-28
Size unit 1 MB = 1,048,576 bytes

H.264 by CRF (-preset medium)

CRF Size vs source VMAF Time
20 11.38 MB -61.1% 95.11 2.23 s
23 7.12 MB -75.7% 93.29 2.05 s
26 4.52 MB -84.6% 90.51 1.89 s
28 3.38 MB -88.4% 87.83 1.82 s
30 2.55 MB -91.3% 84.28 1.77 s
32 1.96 MB -93.3% 79.70 1.76 s

H.265 by CRF (-preset medium)

CRF Size vs source VMAF Time
22 7.96 MB -72.8% 94.86 4.68 s
25 4.94 MB -83.1% 92.94 4.07 s
28 3.04 MB -89.6% 90.03 3.52 s
30 2.20 MB -92.5% 87.27 3.41 s
32 1.60 MB -94.5% 83.53 3.28 s
34 1.14 MB -96.1% 78.49 3.33 s

The test clip is animation. Other footage gives different sizes at the same CRF; noise and fast motion make files bigger. Use the tables to see the trend, not to predict the sizes you will get.

To estimate the size for your own video before you encode it, enter its resolution, duration and CRF in the file size estimator.

CRF Value Reference

CRF Perceived Quality Use Case Estimated Size vs. Original
15–17 Transparent (near visually lossless) Production masters 60–80%
18–20 Excellent YouTube upload, archival 40–60%
21–23 High (default) General sharing, web 25–40%
24–26 Good Social media, preview 15–25%
27–30 Visible degradation Email attachments 8–15%
31–35 Noticeable artifacts Minimum file size 4–8%

These sizes vary a lot with the content (action, animation, talking heads and so on). On the test clip above, CRF 20 gave 39% and CRF 23 gave 24%. Check the result on your own video.

How much the source content changes the size

Each version below started from the same clip and was encoded with the same -crf 23 -preset medium. Only the source itself was changed.

Measured output size at a fixed H.264 CRF 23 for differently prepared source material; only the grain-added version exceeds the 29.3MB source, at 55.89MB

Source condition Output size VMAF vs source
As-is 7.12 MB 93.29 24%
With film grain added 55.89 MB 88.41 191%
Slightly blurred 4.40 MB 73.57 15%
Downscaled to 720p 3.40 MB 82.23 12%

The CRF never changed, yet the output ranged from 3.40MB to 55.89MB, a 16.4x difference. This shows three things:

  • Noise can make a compressed file bigger than the original. Adding grain alone pushed the file to 191% of the source. Film grain, high-ISO footage shot in low light and digitised videotape behave the same way. You can also try removing the noise first (for example with -vf hqdn3d) before raising the CRF.
  • Blurring shrinks the file but lowers quality. The file fell to 4.40MB, but VMAF dropped to 73.57. VMAF measures the difference from the original, so it counts the blur as damage.
  • Downscaling is the better trade. 720p gave 3.40MB at VMAF 82.23, which is both smaller and higher-scoring than the blurred version. If you need to reach a certain size, scale down instead of blurring.

The noise level and resolution of your source matter more than the CRF value you pick.

Preset Comparison

Here the CRF stays the same and only the preset changes. Presets are often said to change only speed and file size, not quality. In this test, quality changed too.

Measured H.264 CRF 23 presets. Top panel VMAF, bottom panel output size; ultrafast alone produces 37.4MB from a 29.3MB source

ultrafast is the fastest (0.88s), but its output is larger than the source file. If you pick a preset for speed alone, the “compressed” file can end up bigger than the original.

Preset Speed File Size Recommended For
ultrafast Fastest Largest Real-time streaming
veryfast Very fast Smaller (measured -31.6%), lower quality Live transcoding, quick tests
fast Fast Slightly smaller (measured -2.9%) Quick turnaround needed
medium Default Balanced General use
slow Slow Same as medium (measured +0.3%) When you want slightly higher quality
slower Very slow Same as medium (measured +1.9%) Long-term storage
veryslow Slowest Slightly smaller (measured -7.0%) Maximum efficiency required

Measured presets (H.264, CRF 23 fixed, same machine as above)

Preset Size VMAF Time
ultrafast 37.40 MB 91.70 0.88 s
veryfast 4.87 MB 88.09 1.10 s
fast 6.91 MB 92.44 1.77 s
medium 7.12 MB 93.29 2.03 s
slow 7.14 MB 93.49 3.26 s
slower 7.26 MB 93.84 5.34 s
veryslow 6.62 MB 94.26 8.65 s

Three results go against the usual advice:

  • medium to slow did not make the file smaller. It went from 7.12 MB to 7.14 MB (+0.3%), and encoding took 1.61x as long. Here the slower preset gave slightly better quality at about the same size (VMAF 93.29 to 93.49), not a smaller file. On this clip, choosing slow to save space did not pay off.
  • ultrafast made a file larger than the source: 37.40 MB from a 29.3 MB input. It gives up so much compression efficiency that the file can grow, even at CRF 23.
  • Quality did not stay the same. At one fixed CRF, VMAF ranged from 88.09 to 94.26, a spread of more than six points. CRF does not keep quality constant across presets.

For general use, choose medium. Pick a slower preset when you want a little more quality. Only veryslow made the file smaller here (-7.0%), and it took over four times as long as medium.

H.264 vs H.265: Which to Choose?

Aspect H.264 (libx264) H.265 (libx265)
Compatibility Nearly universal (phones, TVs, browsers) Moderate (older Android; browser support depends on the OS and device)
Compression Standard 26–35% smaller at equal VMAF (measured, see below)
Encoding speed Fast ~1.9× slower at the same preset (measured)
Software playback Universally supported Widely supported; some players need additional codec
Recommended CRF 18–28 20–30 (in the test above, a value about 2 higher than H.264’s gave a similar VMAF)
Best for Web delivery, social media, broad audiences Personal storage, space-saving, controlled environments

Is H.265 really 40–50% smaller?

The figure you often see is 40–50%. On the test clip, the difference was 26–35%. Comparing the two codecs at the same CRF number tells you little, because their CRF scales differ. So both were encoded at a range of CRF values and compared where their VMAF scores match. The H.264 column is linearly interpolated from the measured H.264 results.

VMAF H.265 Equivalent H.264 H.265 smaller by
83.53 1.60 MB 2.46 MB 34.9%
87.27 2.20 MB 3.25 MB 32.4%
90.03 3.04 MB 4.32 MB 29.5%
92.94 4.94 MB 6.79 MB 27.2%
94.86 7.96 MB 10.80 MB 26.3%

H.265’s advantage shrinks as quality rises: 34.9% at VMAF 83, down to 26.3% at VMAF 95. So archiving at high quality is where H.265 saves the least. It saves the most at low bitrates.

Combining Resolution Downscaling

Lowering the resolution multiplies the savings you get from compression.

# 4K → 1080p + H.265
ffmpeg -i input_4k.mp4 -c:v libx265 -crf 26 -preset medium \
  -vf scale=1920:-2 -c:a aac -b:a 128k output_1080p.mp4

# 1080p → 720p + H.264 (social media)
ffmpeg -i input_1080p.mp4 -c:v libx264 -crf 26 -preset fast \
  -vf scale=1280:-2 -c:a aac -b:a 96k output_720p.mp4

In -vf scale=1280:-2, the -2 keeps the aspect ratio and rounds the height to the nearest even number. Use -2 instead of -1 to avoid codec errors.

Audio Optimization

Audio can be a noticeable part of the file size.

# Drop audio entirely (video only)
ffmpeg -i input.mp4 -c:v libx264 -crf 23 -an output.mp4

# Convert to mono (effective for voice-only content)
ffmpeg -i input.mp4 -c:v libx264 -crf 23 -c:a aac -ac 1 -b:a 64k output.mp4

Audio size reference: 128k stereo ≈ 0.9 MB/min | 96k ≈ 0.7 MB/min | 64k mono ≈ 0.5 MB/min

Option Reference

Option Meaning Recommended Value
-c:v libx264 H.264 encoder Best compatibility
-c:v libx265 H.265 encoder When size matters more than speed
-crf N Quality factor (0–51) H.264: 18–28 / H.265: 20–30
-preset NAME Speed vs. compression medium default; slower ones for a little more quality
-b:v Nk Video bitrate target 720p: 1500k / 1080p: 4000k / 4K: 15000k
-b:a Nk Audio bitrate Stereo: 128k–192k / Voice: 64k–96k
-vf scale=W:-2 Resize video scale=1280:-2 (width=1280, even height)
-movflags +faststart Moves the file’s index (moov atom) to the start Playback on the web starts sooner (recommended)

Troubleshooting

Problem 1: Unknown encoder 'libx265'

Cause: Your FFmpeg build was made without libx265.
Fix: Run ffmpeg -h encoder=libx265. If it prints Codec 'libx265' is not recognized by FFmpeg., install a build that includes libx265:

brew install ffmpeg          # macOS
sudo apt install ffmpeg      # Ubuntu/Debian

Problem 2: Encoding Is Extremely Slow

Cause: -preset veryslow/slow on high-resolution video, or H.265 on older hardware.
Fix: Switch to medium or fast. H.265 is slower by nature, so use H.264 if time matters.

Problem 3: Output File Is Larger Than Expected

Cause: The CRF is too low, or the preset is ultrafast, which compresses poorly.
Fix: Raise the CRF by 2–4, and use medium rather than ultrafast. In the test above, presets slower than medium did not make the file much smaller:

ffmpeg -i input.mp4 -c:v libx264 -crf 26 -preset medium -c:a aac -b:a 128k output.mp4

Problem 4: width not divisible by 2 or height not divisible by 2

Cause: The scale filter produced an odd width or height. For example, scale=1280:-1 can give 1280x719.
Fix: Use -2 for the side FFmpeg calculates: -vf scale=1280:-2 or -vf scale=-2:720. The -2 rounds that side to an even number.

Problem 5: Pass 1 Finished But No Output File

Cause: This is normal. Pass 1 uses -f null /dev/null on purpose: it only writes the stats log file, not a video.
Fix: Run the pass 2 command to make the actual output.

FAQ

Q1. Should I use CRF mode or bitrate mode?
A. Use CRF for almost everything. It keeps the quality consistent across simple and complex scenes. Use bitrate mode only when you need strict control of the file size, for example to stay under a platform’s bitrate cap.

Q2. Is CRF 23 the best setting for any video?
A. No. CRF 23 is only the encoder’s default. Fast action may need CRF 20, and animation with flat colors can go down to CRF 18–22. Always check the actual output.

Q3. Should I copy or re-encode the audio?
A. Use -c:a copy to keep the audio exactly as it is. Use -c:a aac -b:a 128k if you also want a smaller audio track. Re-encoding always loses a little quality.

Q4. Can I use GPU encoding on macOS?
A. Yes. VideoToolbox, Apple’s hardware video encoding framework, is available on Apple Silicon and Intel Macs:

ffmpeg -i input.mp4 -c:v h264_videotoolbox -b:v 4000k -c:a aac output.mp4

There is no -crf option. Set the bitrate with -b:v, or on Apple Silicon Macs set a quality level with -q:v (1–100, higher is better).

Q5. How do I compress all videos in a folder at once?
A. Use a loop in a bash or zsh terminal:

for f in *.mp4; do
  ffmpeg -i "$f" -c:v libx264 -crf 23 -preset medium -c:a aac -b:a 128k "compressed_${f}" -y
done