field note — July 6, 2026 · 5 min read

n8n can't handle heavy video files — the FFmpeg microservice pattern

n8n · FFmpeg · video automation · Flask · Docker

If you have ever tried to push real video files through n8n nodes, you already know the ending: memory pressure, stalled executions, and a workflow that dies exactly when it matters. n8n is a brilliant orchestrator — and a terrible byte-mover.

The rule: n8n handles logic, a microservice handles bytes

My YouTube automation pipeline publishes 6 Shorts and 2 long-form videos every day. n8n never touches a video file. It passes file paths and job references to a small Flask service in Docker (running on a free-tier ARM64 box) that owns every FFmpeg operation.

# The contract is deliberately boring:
POST /render
{
  "job_id": "short-2026-07-06-04",
  "source": "/data/raw/ep-114.mp4",
  "ops": ["reframe-9x16", "karaoke-subs", "kenburns-intro", "audio-mix"]
}
# n8n polls /status/{job_id} — bytes never cross the webhook boundary.

What lives inside the microservice

  • Scripted FFmpeg filter graphs: Ken Burns pans, karaoke subtitles, audio ducking, 9:16 reframes — no editor ever opens.
  • A job queue with idempotent job IDs, so a retried webhook cannot double-render.
  • Disk hygiene: rendered artifacts are cleaned on a schedule, because the disk WILL fill (ask me how I know).

Why not just use bigger n8n instances?

Because the failure mode does not scale away — it just moves the cliff. Separating orchestration from rendering means each side fails independently and recovers independently. The pipeline has run daily since 2024 at $0/month infrastructure cost. That number is the entire business case.

from the system this note is based onYouTube Automation Pipeline — full case study →

next note

GoHighLevel A2P compliance: the checklist I use on every client build