Ahosting Logo
Knowledge Base

FFmpeg Performance Optimization Tips

FFmpeg encoding speed is governed by a small number of decisions, and the largest one is a trade you cannot avoid: encoding faster produces larger files at the same quality, and encoding slower produces smaller ones. Everything below is either that trade, or a way to sidestep it entirely by not re-encoding at all.

Start by knowing which resource you are actually short of. If the machine's cores are saturated during a transcode, you are CPU-bound and the preset and codec choices matter most. If the cores are idle and the job is still slow, you are waiting on disk or network, and no encoder setting will help.

The preset is the largest lever, and it is a straight tradeFaster presetsSlower presetsEncoding timeshortlongFile size at the samequalitylargersmallerQuality at the samesizelowerhigherUse whenthroughput matters, or the file iswatched oncethe file is stored and served many timesThe preset changes how hard the encoder looks for savings. Nothing is lost by choosing a fast one except size.

1. Choose the preset deliberately

The preset sets how much effort the encoder spends looking for savings. It does not change quality directly. It changes how large the file has to be to reach that quality.

# Faster encoding (larger files)
ffmpeg -i input.mp4 -c:v libx264 -preset ultrafast output.mp4

# Balanced (default)
ffmpeg -i input.mp4 -c:v libx264 -preset medium output.mp4

# Slower encoding (smaller files)
ffmpeg -i input.mp4 -c:v libx264 -preset slow output.mp4

Available presets, fastest to slowest: ultrafast, superfast, veryfast, faster, fast, medium, slow, slower, veryslow.

Choose by what is scarce. A file encoded once and downloaded ten thousand times deserves a slow preset, because you pay the CPU cost once and the bandwidth saving repeats forever. A file transcoded on upload and watched twice does not: there, veryfast is usually the right answer and the storage difference is irrelevant.

The steps between neighbouring presets are small. The step from ultrafast to medium is large. If you are unsure, move one or two steps rather than jumping to an extreme.

2. Use CRF for quality control

CRF, Constant Rate Factor, asks the encoder for a consistent visual quality and lets the bitrate vary to achieve it. This is what you want for anything that is downloaded or watched on demand.

  • 18: Visually lossless
  • 23: Default, good balance
  • 28: Smaller files, acceptable quality
ffmpeg -i input.mp4 -c:v libx264 -crf 23 output.mp4

The scale is logarithmic and inverted: lower is better quality and larger. A change of about 6 roughly doubles or halves the file size, so moving from 23 to 28 is a large reduction, not a small one.

CRF and preset are independent, and the pairing is the point. CRF decides how good it looks; preset decides how long the encoder works to get there efficiently. Set the CRF you can accept, then choose the slowest preset your time budget allows.

3. Use multiple threads

# Use all CPU cores
ffmpeg -i input.mp4 -threads 0 -c:v libx264 output.mp4

# Specify thread count
ffmpeg -i input.mp4 -threads 4 -c:v libx264 output.mp4

-threads 0 lets FFmpeg decide, which is usually right. Specifying a number is for when you deliberately want to leave cores free, on a server also serving a website, an encode consuming every core makes the site slow while it runs.

Threading has diminishing returns. Doubling cores does not halve encode time, and beyond a point extra threads cost a little compression efficiency. Running two encodes on four cores each is often better throughput than one encode on eight.

4. Hardware acceleration

Hardware encoders are dramatically faster than software encoding because dedicated silicon does the work. They are also less efficient: at the same file size, hardware output generally looks worse than a good software encode.

# NVIDIA NVENC (much faster)
ffmpeg -i input.mp4 -c:v h264_nvenc -preset fast output.mp4

# Intel Quick Sync
ffmpeg -i input.mp4 -c:v h264_qsv output.mp4

These require the corresponding hardware to be present and exposed to your server. Check what your plan actually provides before building a pipeline around them: the command fails with an encoder-not-found error rather than falling back silently.

The right use is real-time or near-real-time work, where finishing on schedule matters more than the last few percent of efficiency. For a library encoded once and served many times, software encoding at a slow preset produces a better result.

5. Avoid re-encoding when possible

This is the largest saving available and it is frequently overlooked, because people reach for a transcode by habit.

# Just copy streams (instant)
ffmpeg -i input.mkv -c copy output.mp4

Stream copying moves the existing audio and video into a different container without touching them. There is no quality loss because nothing is decoded, and it runs at disk speed rather than encode speed, seconds instead of hours.

It works whenever the codecs inside the file are already what you need and only the container is wrong. Changing MKV to MP4 for browser playback is the classic case.

You can also copy one stream while encoding the other, which is useful when only the audio needs changing:

ffmpeg -i input.mp4 -c:v copy -c:a aac -b:a 128k output.mp4

Before writing any transcode, ask whether the codecs already match. ffprobe answers it in a second, and the answer is yes more often than people expect.

6. Use two-pass for a target bitrate

When the output must hit a specific size or bitrate. A delivery requirement, or a strict bandwidth budget, two-pass gives a noticeably better result than one pass at the same bitrate, because the first pass measures the material and the second spends the budget where it matters.

ffmpeg -y -i input.mp4 -c:v libx264 -b:v 2000k -pass 1 -an -f null /dev/null
ffmpeg -i input.mp4 -c:v libx264 -b:v 2000k -pass 2 -c:a aac output.mp4

It takes roughly twice as long, since the file is analysed twice. Only use it when the bitrate is genuinely fixed. If you simply want good quality at a reasonable size, CRF is better and half the work.

7. Scale down before encoding, not after

If the output is going to be smaller than the source, resize as part of the same command rather than encoding at full size first.

ffmpeg -i input.mp4 -vf scale=1280:-2 -c:v libx264 -crf 23 output.mp4

The -2 keeps the aspect ratio and rounds to an even number, which H.264 requires. Using -1 instead is a common cause of an encoder error about odd dimensions.

Encoding fewer pixels is faster in direct proportion, so this is often a larger speed gain than any preset change.

8. Cut before you encode

When you only need part of a file, place -ss before -i. FFmpeg then seeks to that point rather than decoding everything up to it.

# Fast: seek first, then decode
ffmpeg -ss 00:05:00 -i input.mp4 -t 60 -c copy clip.mp4

# Slow: decodes from the start
ffmpeg -i input.mp4 -ss 00:05:00 -t 60 -c copy clip.mp4

On a long file the difference is minutes against seconds. Combined with -c copy, extracting a clip becomes nearly instant.

What to do when nothing helps

If cores are idle during an encode, you are not CPU-bound and encoder settings will not change anything. Look at disk throughput, particularly when reading from and writing to the same volume, or when the source is on network storage.

If encodes are fast alone and slow when several run together, you are competing for the same cores. Queue them rather than running them in parallel; total throughput is usually higher and the machine stays responsive.

And if the workload has simply outgrown a shared environment, dedicated resources are the fix rather than further tuning. Ahosting's FFmpeg hosting runs on a VPS with FFmpeg and FFprobe pre-installed, SSH access and dedicated CPU, from $16.79/month.

When a command fails outright rather than running slowly, troubleshooting common FFmpeg errors goes over what the messages mean.

The largest performance decision is made before any of these settings, in the choice of codec itself. There is more on the trade between encoding time and file size in How to Choose a Video Codec: H.264, H.265, VP9 or AV1.

The largest single speed-up available is not a setting at all but a different encoder, when the machine has one. How to Use Hardware Acceleration with FFmpeg explains what you give up in exchange.

Running several jobs at once is the obvious next step and usually the wrong one. How to Run FFmpeg Jobs in Parallel Without Overloading covers why, and when it does help.