Monitor FFmpeg Speed and CPU Usage in Real-Time

Monitoring the real-time encoding speed and CPU consumption of an FFmpeg task is critical for benchmarking hardware, optimizing transcoding pipelines, and diagnosing system bottlenecks. This guide covers how to extract FFmpeg’s built-in real-time speed metric, track CPU utilization via system monitoring utilities on Linux, macOS, and Windows, and combine these outputs into a single pipeline.


1. Reading FFmpeg’s Native Encoding Speed

FFmpeg prints dynamic progress information to stderr during execution. Among these metrics is the real-time speed multiplier:

frame= 1240 fps= 62 q=28.0 size=   15872kB time=00:00:51.60 bitrate=2518.2kbits/s speed=2.58x
  • speed=: Indicates how fast FFmpeg processes the file relative to real-time playback. A speed of 1.0x means 1 second of video is encoded every second. A speed of 2.58x means the encoder is running 2.58 times faster than real-time playback.
  • fps=: Indicates the number of frames processed per second.

Capturing Progress via Machine-Readable Output

If you are automating the monitoring process, pass the -progress flag to send metrics directly to stdout or a Unix socket:

ffmpeg -i input.mp4 -c:v libx264 -progress pipe:1 -nostats output.mp4

This streams key-value pairs line-by-line, including:

  • fps=
  • total_size=
  • out_time_us=
  • speed=

2. Measuring CPU Usage in Real-Time

FFmpeg does not monitor system-level CPU resource consumption natively. You must measure this using operating-system tools alongside the process.

Linux and macOS

Option A: Using pidstat (Most Accurate for Linux)

pidstat (part of the sysstat package) outputs real-time CPU percentages per core and aggregated across threads at regular intervals:

# Run FFmpeg in the background or another terminal, then monitor by process name:
pidstat -C "ffmpeg" 1
  • The 1 sets the polling interval to 1 second.
  • %CPU shows total CPU utilization across all cores (e.g., 800% means 8 cores fully saturated).

Option B: Using top in Batch Mode

To monitor CPU usage non-interactively:

top -b -d 1 -p $(pgrep -d',' ffmpeg) | grep --line-buffered ffmpeg

Option C: Interactive Monitoring with htop

Run htop in a separate terminal and press F4 to filter for ffmpeg. This displays per-thread CPU consumption, total memory allocation, and processor affinity dynamically.


Windows

Option A: PowerShell

To continuously poll the CPU utilization of an active FFmpeg process every second:

while ($true) {
    Get-Process ffmpeg -ErrorAction SilentlyContinue | 
    Select-Object ProcessName, Id, CPU, @{Name="CPU%"; Expression={
        $prev = $_.CPU; 
        Start-Sleep -Seconds 1; 
        $curr = (Get-Process -Id $_.Id).CPU; 
        [math]::Round(($curr - $prev) / [System.Environment]::ProcessorCount, 2)
    }} | Format-Table -AutoSize
}

Option B: Performance Monitor (GUI)

  1. Press Win + R, type perfmon.exe, and press Enter.
  2. Add the counter: Process -> % Processor Time -> Select ffmpeg.

3. Combining Speed and CPU Tracking in a Single Script

To observe both metrics concurrently in a terminal, run FFmpeg alongside a polling loop in a POSIX-compliant shell:

#!/usr/bin/env bash

# Start FFmpeg in the background with progress piped
ffmpeg -y -i input.mp4 -c:v libx264 -preset slow output.mp4 -progress pipe:1 2> ffmpeg.log | while read -r line; do
    case "$line" in
        speed=*)
            SPEED="${line#speed=}"
            ;;
        fps=*)
            FPS="${line#fps=}"
            ;;
        progress=continue)
            # Fetch current CPU usage for the ffmpeg process
            CPU_USAGE=$(ps -C ffmpeg -o %cpu= | awk '{s+=$1} END {print s}')
            printf "\r[FFmpeg] Speed: %s | FPS: %s | Total CPU: %s%%" "$SPEED" "$FPS" "$CPU_USAGE"
            ;;
        progress=end)
            echo -e "\nEncoding Complete."
            ;;
    esac
done

This method reads FFmpeg's internal throughput and matches it to current processor workload at each reporting cycle.