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-05T06:41:33Z
Platform linux/amd64, 8 CPUs
Go go1.26.4
Native ffmpeg version 6.1.1-3ubuntu5 Copyright © 2000-2023 the FFmpeg developers
LGPL module /home/matt/workspace/phpboyscout/ffmpeg-wasi/dist-wasmcheck/ffmpeg-wasi-lgpl.wasm
GPL module (not provided)
Native driver /home/matt/workspace/phpboyscout/ffmpeg-wasi/dist-native/driver

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.52 s 162 ms
reel 15.61 s 390 ms
  • transcode — decode → scale 160 → H.264/AAC mp4 (encode-dominated)
  • reel — two inputs → xfade + amix → H.264/AAC mp4 (filter + encode, keyrx-shaped)

Native backend (Backend B) — WASM vs native engine

Same openh264 encoder, same jobs; the native driver serves afero over IPC.

Workload WASM openh264 Native driver Speedup
transcode 2.52 s 52 ms 48.1×
reel 15.61 s 268 ms 58.2×

The native driver also runs through the identical RunJob API — only the backend (WithBackend) differs; results are byte-compatible.

Fleet throughput (instance-level parallelism)

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

Mode Wall clock Throughput
Serial (1 Runtime) 10.15 s 0.4 jobs/s
Fleet (8 Runtimes) 2.96 s 1.4 jobs/s

Speedup: 3.4× across 8 cores.

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

WASM Native Native multiple
single frame @2s → png 190 ms 75 ms 2.5×

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.