ffmpeg.wasm vs a Hosted FFmpeg API: Where Browser-Side Breaks

ffmpeg.wasm looks like magic the first time you see it. Run FFmpeg right in the browser. No server, no install, no infrastructure. Your user picks a file, you process it client-side, and nobody's video ever leaves their machine.
Then someone uploads a 200MB file and the tab crashes.
This post breaks down exactly where ffmpeg.wasm works, where it falls apart, and when you should move the heavy lifting to a server-side API instead.
What ffmpeg.wasm actually is
ffmpeg.wasm is a WebAssembly port of FFmpeg that runs entirely in the browser. It compiles the FFmpeg C codebase to Wasm, loads it into a web worker, and executes FFmpeg commands against files stored in an in-memory virtual filesystem.
That means your JavaScript can do this:
import { FFmpeg } from '@ffmpeg/ffmpeg';
const ffmpeg = new FFmpeg();
await ffmpeg.load();
await ffmpeg.writeFile('input.mp4', videoData);
await ffmpeg.exec(['-i', 'input.mp4', '-vf', 'scale=640:360', 'output.mp4']);
const data = await ffmpeg.readFile('output.mp4');
No server call. No API key. The entire operation happens in the user's browser tab.
Where ffmpeg.wasm works well
For small, quick operations on small files, ffmpeg.wasm is genuinely useful:
- Thumbnail extraction from short clips (under 50MB)
- Format detection and metadata inspection
- Quick trims of short videos (cut first 10 seconds)
- Privacy-sensitive workflows where video can't leave the device
- Prototyping when you want to test FFmpeg commands without a backend
If your use case fits in that box, ffmpeg.wasm is a reasonable choice. No server costs, no latency from uploads, and you get to keep things simple.
The five walls you'll hit
1. Memory ceiling
ffmpeg.wasm loads the entire input file into browser memory (via the virtual filesystem). A 500MB video needs at least 500MB of RAM just for the input, plus working memory for the decode/encode pipeline, plus memory for the output file. On a mobile device with 2-4GB total, that is a guaranteed crash.
The practical limit is roughly 100-200MB per file on desktop, less on mobile. Anything larger and you are fighting the browser's memory allocator.
2. Single-threaded performance
Wasm execution in the browser is single-threaded. A transcode that takes 30 seconds on a server with 8 cores can take 5-10 minutes in the browser. Your user is staring at a progress bar while their laptop fan screams.
Multi-threaded ffmpeg.wasm builds exist (@ffmpeg/core-mt) but require SharedArrayBuffer, which needs specific CORS headers (Cross-Origin-Opener-Policy and Cross-Origin-Embedder-Policy). Many CDNs and hosting platforms don't set these by default, and enabling them breaks third-party embeds (analytics, ads, chat widgets).
3. Codec limitations
The Wasm build doesn't include every codec FFmpeg supports. Licensing (x264, x265, AAC) and binary size constraints mean you get a subset. If you need HEVC encoding, hardware-accelerated decode, or niche codecs, they likely aren't compiled in.
4. Mobile is unreliable
Mobile browsers have tighter memory limits, more aggressive tab killing, and weaker CPUs. A transcode that works fine on your MacBook will crash Safari on an iPhone 12. If your product has mobile users (and it probably does), client-side processing is a liability.
5. No batch processing
Processing one file at a time is manageable. Processing 50 files in a queue? The user has to keep the tab open, can't navigate away, and any browser crash kills the entire batch. There is no retry, no persistence, no background processing.
When to move server-side
The decision point is straightforward. If any of these are true, you need a server-side solution:
- Files regularly exceed 100MB
- You need to process more than one file at a time
- Mobile users are part of your audience
- Transcode speed matters (seconds, not minutes)
- You need reliable batch processing or webhooks
- You want to use codecs not available in the Wasm build
You don't have to build a server for this. FFmpeg Micro runs FFmpeg in the cloud and exposes it as a REST API. The same operation from the ffmpeg.wasm example above looks like this:
curl -X POST https://api.ffmpeg-micro.com/v1/transcodes \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"inputs": [{"url": "https://your-bucket.s3.amazonaws.com/input.mp4"}],
"outputFormat": "mp4",
"options": [
{"option": "-vf", "argument": "scale=640:360"}
]
}'
The user uploads to your storage, you fire an API call, and FFmpeg Micro handles the processing on dedicated infrastructure. No memory limits, no single-threaded bottleneck, no mobile crashes.
The hybrid approach
You don't have to choose one or the other. A smart pattern is to use ffmpeg.wasm for lightweight client-side operations (thumbnails, previews, quick trims under 50MB) and route heavier work to an API.
const FILE_SIZE_THRESHOLD = 50 * 1024 * 1024; // 50MB
async function processVideo(file) {
if (file.size < FILE_SIZE_THRESHOLD) {
return processClientSide(file); // ffmpeg.wasm
}
return processServerSide(file); // FFmpeg Micro API
}
This gives you the best of both worlds: instant client-side processing for small files, and reliable server-side processing for everything else.
Comparison table
| Factor | ffmpeg.wasm | Hosted FFmpeg API |
|---|---|---|
| Max file size | ~100-200MB (browser RAM) | No practical limit |
| Processing speed | 5-10x slower (single thread) | Server-grade (multi-core) |
| Mobile support | Unreliable | Works everywhere |
| Batch processing | Manual, fragile | Built-in queuing |
| Privacy | Video stays on device | Video uploaded to server |
| Cost | Free (client CPU) | Pay per minute processed |
| Setup | npm install + CORS config | API key |
| Codec support | Subset (Wasm build) | Full FFmpeg |
Common pitfalls
"It works on my machine." Desktop Chrome with 16GB RAM is not representative of your users. Test on a mid-range Android phone with a 300MB file before committing to client-side processing.
"SharedArrayBuffer will fix the speed." Multi-threaded Wasm helps, but the CORS requirements break other parts of your stack. Check what third-party scripts you load before enabling COEP/COOP headers.
"I'll just chunk the file." FFmpeg needs random access to the full file for most operations. You can't stream-process a transcode the way you stream-process a text file. The entire input has to be in memory.
FAQ
Is ffmpeg.wasm free to use?
Yes, ffmpeg.wasm is open source (MIT + LGPL for the FFmpeg core). There are no licensing fees. The cost is your user's CPU and RAM.
Can ffmpeg.wasm handle 4K video?
Technically yes, but practically no. A 4K video file is typically 500MB-2GB. Loading that into browser memory will crash most devices. Use a server-side solution for 4K content.
Does ffmpeg.wasm work in all browsers?
It works in Chrome, Firefox, Edge, and Safari (recent versions). The multi-threaded build (@ffmpeg/core-mt) requires SharedArrayBuffer support, which Safari only added recently and some mobile browsers still don't support.
How much does a hosted FFmpeg API cost?
FFmpeg Micro has a free tier for testing and small workloads. Paid plans start at $19/month with usage-based billing per minute of video processed. Get a free API key to test it.
Can I use both ffmpeg.wasm and an API in the same app?
Yes. Use ffmpeg.wasm for lightweight client-side operations (previews, thumbnails) and route heavier processing to an API. The hybrid approach section above shows a simple pattern for this.
Last verified: July 2026 against ffmpeg.wasm 0.12.x and FFmpeg Micro API v1.
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.
You might also like

fluent-ffmpeg vs FFmpeg Micro: Why Node.js Developers Switch to a Cloud API
Compare fluent-ffmpeg with FFmpeg Micro cloud API. See why Node.js developers migrate from local FFmpeg to a REST API for serverless video processing.

Self-Hosting FFmpeg vs. Using an API: What Developers Get Wrong
Self-hosting FFmpeg looks simple until Docker bloat, codec licensing, and scaling hit production. Compare self-hosted FFmpeg vs a cloud API.

FFmpeg as a Service: Process Video with One API Call
FFmpeg as a service: process video with a single API call instead of managing FFmpeg servers. Working curl examples, pitfalls, and cost comparison.
Ready to process videos at scale?
Start using FFmpeg Micro's simple API today. No infrastructure required.
Get Started Free