Skip to content

Spec 0008 — performance measurement report

Generated by cmd/afmpeg-bench — WASM (afmpeg) vs native ffmpeg on the same host, same jobs. Source fixture: testsrc2 320×240 @25fps 3s + sine (H.264/AAC). All WASM I/O is in-memory (afero); native writes temp files. Median of 3 runs.

Host

When 2026-07-04T18:30:30Z
Platform linux/amd64, 8 CPUs
Go go1.26.4
Native ffmpeg version 6.1.1-3ubuntu5 Copyright © 2000-2023 the FFmpeg developers
LGPL module ../ffmpeg-wasi/dist/ffmpeg-wasi-intermediate-lgpl.wasm
GPL module ../ffmpeg-wasi/dist/ffmpeg-wasi-intermediate-gpl.wasm

Workloads — WASM vs native

The native multiple is WASM-libx264 ÷ native-libx264 (same encoder — the honest wasm overhead).

Workload WASM openh264 WASM libx264 Native libx264 Native multiple
transcode 2.35 s 9.75 s 153 ms 63.5×
reel 14.53 s 64.75 s 432 ms 149.9×
  • transcode — decode → scale 160 → H.264/AAC mp4 (encode-dominated)
  • reel — two inputs → xfade + amix → H.264/AAC mp4 (filter + encode, keyrx-shaped)

x264 preset sweep — transcode

Preset WASM libx264 Native libx264 Native multiple
ultrafast 3.11 s 237 ms 13.1×
veryfast 5.51 s 143 ms 38.4×
medium 10.81 s 196 ms 54.9×

Fleet throughput (instance-level parallelism)

8 transcode jobs (x264 ultrafast), one Runtime (serial) vs a pool of 8 Runtimes:

Mode Wall clock Throughput
Serial (1 Runtime) 22.80 s 0.4 jobs/s
Fleet (8 Runtimes) 4.57 s 1.8 jobs/s

Speedup: 5.0× across 8 cores.

Thumbnail (frames op — decode + scale, minimal encode)

WASM Native Native multiple
single frame @2s → png 216 ms 89 ms 2.4×

Caveats

  • Not apples-to-apples beyond the encoder. WASM is single-threaded and --disable-asm; native ffmpeg uses all cores + SIMD. The multiple is an upper bound on the gap, not a like-for-like.
  • I/O differs by design — WASM keeps everything in afero (RAM); native uses temp files.
  • openh264 ≠ libx264 in speed and quality/size; the openh264 column is informational.
  • The -Oz vs -O2/-O3 module-build axis (spec 0008 §3.2) needs a rebuilt module and is not measured here.