ffmpegvp9libvpx-vp9video-encodingwebmcrfbucket-doc

How to Encode VP9 Video with FFmpeg: libvpx-vp9 CRF, Bitrate, and Quality Guide

·Javid Jamae·7 min read
How to Encode VP9 Video with FFmpeg: libvpx-vp9 CRF, Bitrate, and Quality Guide

VP9 is Google's open, royalty-free video codec. It powers most of YouTube's streaming library, and every modern browser supports it through the WebM container. If you need high-quality web video without licensing headaches, VP9 with FFmpeg's libvpx-vp9 encoder is the standard choice.

This guide covers the practical settings: CRF mode, 2-pass encoding, speed tuning, and multithreading. Everything here applies to FFmpeg's libvpx-vp9 encoder directly.

TL;DR: The Default VP9 Command

ffmpeg -i input.mp4 -c:v libvpx-vp9 -crf 31 -b:v 0 -c:a libopus -b:a 128k output.webm

CRF 31 with -b:v 0 gives you true constant-quality mode. Opus audio at 128k is the natural pairing for WebM.

What CRF Does in VP9

CRF stands for Constant Rate Factor. It tells the encoder to target a consistent visual quality across the whole file, letting the bitrate float up or down as needed. Flat talking-head footage gets a low bitrate. Complex action scenes get more.

VP9's CRF scale runs from 0 to 63. Lower means better quality and bigger files. This is different from H.264's libx264, which uses a 0-51 range.

You must set -b:v 0 for true CRF mode. If you leave out -b:v 0, FFmpeg treats the CRF value as a "constrained quality" floor and caps the bitrate at a default target. That usually produces worse results than either pure CRF or proper 2-pass encoding. This is the single most common VP9 encoding mistake.

Basic VP9 Encoding Command

ffmpeg -i input.mp4 \
  -c:v libvpx-vp9 \
  -crf 31 \
  -b:v 0 \
  -deadline good \
  -cpu-used 2 \
  -row-mt 1 \
  -c:a libopus -b:a 128k \
  output.webm

This hits a solid balance between quality, file size, and encoding speed for most web video.

VP9 CRF Values by Use Case

CRFUse CaseNotes
15-20Archival / master copiesNear-lossless. Large files.
24-28High-quality streamingVisually transparent for most content
30-33General web videoGood quality at reasonable file sizes
36-42Low-bandwidth deliveryNoticeable softness, but watchable
45+Previews / thumbnailsSignificant quality loss

CRF 31 is a reasonable default. It sits in the same perceptual territory as CRF 23 in libx264 or CRF 28 in libx265, roughly speaking.

Speed Settings: -cpu-used and -deadline

VP9 doesn't use named presets like x264's "slow" or "fast." Instead, speed is controlled by two flags.

-deadline sets the encoding mode:

  • best is painfully slow and mostly useful for benchmarks.
  • good is what you want for production encodes.
  • realtime is for live streaming only. Quality suffers.

-cpu-used is a number from 0 to 8. Zero is the slowest and highest quality. Eight is the fastest with the worst quality.

For most encodes, -deadline good -cpu-used 2 is the sweet spot. Bumping to -cpu-used 4 roughly halves encode time with a small quality drop. Values above 5 start showing visible artifacts on complex footage.

-cpu-usedRelative SpeedQuality Impact
01x (baseline)Best possible
1~1.5xNegligible loss
2~2.5xMinimal loss, good default
4~5xSlight softness
6~10xNoticeable on complex scenes
8~20xFast but rough

2-Pass Encoding for VP9

VP9 benefits more from 2-pass encoding than most codecs. The first pass analyzes the entire video so the second pass can distribute bits more intelligently. For anything targeting a specific bitrate, 2-pass is strongly recommended.

# Pass 1: analysis only (no audio, output discarded)
ffmpeg -i input.mp4 -c:v libvpx-vp9 -b:v 2M \
  -deadline good -cpu-used 2 -row-mt 1 \
  -pass 1 -an -f null /dev/null

# Pass 2: actual encode
ffmpeg -i input.mp4 -c:v libvpx-vp9 -b:v 2M \
  -deadline good -cpu-used 2 -row-mt 1 \
  -pass 2 -c:a libopus -b:a 128k output.webm

The first pass creates a log file that the second pass reads. Both passes need matching settings for -b:v, -cpu-used, and -deadline.

You can also combine 2-pass with CRF by replacing -b:v 2M with -crf 31 -b:v 0 in both passes. This gives CRF-quality encoding with better bit distribution across scenes.

Row-Based Multithreading

By default, libvpx-vp9 doesn't parallelize well. Two flags fix this.

-row-mt 1 -tile-columns 2 -threads 8

-row-mt 1 enables row-based multithreading, which lets the encoder process multiple rows of macroblocks simultaneously. This alone can cut encode time by 50% or more on multi-core machines.

-tile-columns splits each frame into independent tile columns for parallel encoding. Set it based on resolution: 1 for 720p, 2 for 1080p, 3 for 4K. The value is a log2 count, so -tile-columns 2 means 4 tile columns.

Always enable -row-mt 1. There's no quality penalty and the speed improvement is substantial.

Running VP9 Encodes via the FFmpeg Micro API

If you don't want to install FFmpeg or manage encoding infrastructure, you can run the same VP9 encode through the FFmpeg Micro API.

{
  "inputs": [{ "url": "https://storage.example.com/video.mp4" }],
  "outputFormat": "webm",
  "options": [
    { "option": "-c:v", "argument": "libvpx-vp9" },
    { "option": "-crf", "argument": "31" },
    { "option": "-b:v", "argument": "0" },
    { "option": "-deadline", "argument": "good" },
    { "option": "-cpu-used", "argument": "2" },
    { "option": "-row-mt", "argument": "1" },
    { "option": "-c:a", "argument": "libopus" },
    { "option": "-b:a", "argument": "128k" }
  ]
}

Send that as a POST to https://api.ffmpeg-micro.com/v1/transcodes with your Bearer token. FFmpeg Micro runs the same FFmpeg binary in the cloud. You send an API call, it runs your VP9 encode, no server to manage. Grab a free API key at ffmpeg-micro.com.

Common Pitfalls

Forgetting -b:v 0 in CRF mode. Without it, libvpx-vp9 operates in constrained quality mode and caps bitrate at a low default. Your CRF value becomes a quality floor, not a target. Always pair -crf with -b:v 0.

Using -cpu-used 0 and wondering why it takes forever. CPU-used 0 is extremely slow. For a 10-minute 1080p video, it can take hours. Start with -cpu-used 2 and only go lower if you have time to burn and need every last bit of quality.

Skipping -row-mt 1. Without row-based multithreading, libvpx-vp9 barely uses multiple cores. This is free performance. There's no reason to leave it off.

Using .mp4 as the output container. VP9 belongs in WebM (or MKV). While some players handle VP9 in MP4, browser support and spec compliance are best with .webm.

FAQ

Is VP9 better than H.264 for web video?

VP9 typically achieves 30-50% better compression than H.264 at the same visual quality. The tradeoff is slower encoding. For web delivery where bandwidth costs matter, VP9 produces smaller files that look just as good.

Should I use VP9 or AV1?

AV1 is the newer codec and compresses roughly 20-30% better than VP9. But AV1 encoding is significantly slower, and hardware decoder support is still catching up. VP9 is the practical choice today when you need broad browser compatibility and reasonable encode times.

What's the difference between CRF mode and 2-pass in VP9?

CRF mode targets consistent quality and lets file size vary. 2-pass targets a specific bitrate and distributes bits optimally across the video. Use CRF when quality matters most. Use 2-pass when you need predictable file sizes, like hitting a CDN storage budget.

Why is my VP9 encode so slow?

Check your -cpu-used value. Zero is the slowest setting. Also make sure -row-mt 1 is enabled for multithreading. Encoding speed scales roughly linearly with -cpu-used from 0 to 4. A jump from -cpu-used 0 to -cpu-used 2 can cut encode time by 60% with minimal quality impact.

Can I use VP9 with MP4 containers?

Technically yes, but don't. The WebM container is the correct home for VP9 video. Browser <video> tags expect VP9 in .webm, and some players won't recognize VP9 inside .mp4. Stick with WebM for maximum compatibility.

*Last verified against FFmpeg 7.1 (libvpx-vp9) on June 23, 2026.*

About Javid Jamae

Founder & CEO at FFmpeg Micro

Javid is a software engineer, author, and entrepreneur with over 25 years of professional software development experience across enterprise, startup, and consulting environments. He founded FFmpeg Micro to make video processing accessible to developers through a simple, automation-first REST API.

Software EngineeringVideo ProcessingFFmpegCloud ArchitectureAPI DesignAutomation

Ready to process videos at scale?

Start using FFmpeg Micro's simple API today. No infrastructure required.

Get Started Free