n8ngoogle-drivevideo-compression

Google Drive Video Automation Fails in n8n. Pass a URL Instead.

·Javid Jamae·10 min read
Google Drive Video Automation Fails in n8n. Pass a URL Instead.

Someone drops a 1.4 GB screen recording into the team's Drive folder, and the n8n workflow that's supposed to compress it either times out, runs out of memory, or fails on a node that doesn't exist on your plan. The recipe everyone copies (Google Drive Trigger, Download File, Execute Command with FFmpeg, Upload File) was written for a self-hosted box in 2023 and quietly stopped working since.

Quick answer: Google Drive video automation breaks because the standard n8n recipe moves the bytes through n8n: the Download node loads the whole file into memory, and the Execute Command node that runs FFmpeg isn't available on n8n Cloud at all. The version that holds up never downloads the video. Share the Drive file by link, pass that URL to a video processing API, and write the compressed output back to a Processed folder when the webhook comes in. FFmpeg Micro runs that compress step as one API call with no encoder to install and no long-running node to babysit, on a free tier.

Why the standard Drive plus FFmpeg recipe breaks

The Drive trigger, download, shell out to FFmpeg, upload chain fails in three separate places, and each one has a different fix.

Execute Command isn't on n8n Cloud, and self-hosting it got harder

The Execute Command node is excluded from n8n Cloud entirely, and since n8n v2.0 it's disabled by default on self-hosted instances too, because arbitrary shell execution is a bad idea in a shared environment. So "just install FFmpeg in your n8n container" requires self-hosting and flipping a security default.

Installing FFmpeg got worse in 2026. The official docker.n8n.io/n8nio/n8n image is now distroless, so there's no apk or apt inside it. Every tutorial that tells you to run USER root and apk add --no-cache ffmpeg fails on the current image. The forum workaround is a multi-stage build that copies Alpine's apk binary and libapk.so* into the distroless base, which you re-verify on every n8n release.

The download node puts the entire file in memory

n8n's default binary data mode keeps file contents in memory. A 1 GB video downloaded from Drive sits in RAM as a buffer, and when it crosses a node boundary as base64 it grows by roughly a third.

Self-hosted, you can set N8N_DEFAULT_BINARY_DATA_MODE=filesystem and move that off the heap. On Cloud you can't set it. We wrote up the full diagnosis in How to Fix n8n Running Out of Memory on Large Video Files: the fix isn't a bigger instance, it's not routing the bytes through n8n.

Re-encoding runs longer than anything in the chain will wait

H.264 encoding of a 12-minute 1080p clip at preset veryfast takes a couple of minutes on a modest vCPU, and slower presets take much longer. n8n Cloud enforces an execution timeout, nginx defaults proxy_read_timeout to 60 seconds, and Cloudflare cuts the connection at 100 seconds with a 524. A synchronous encode inside a workflow run is a bet that the file is small. Asynchronous is the only shape that survives, which is the same argument we made for Zapier's video timeouts.

The workflow that holds up: URL in, webhook out

The working version of Drive video automation has four nodes and never touches the video file itself. n8n passes a URL out and receives a URL back, so the largest thing crossing a node boundary is a few hundred bytes of JSON.

1. Trigger on the watch folder, not the whole drive

Use the Google Drive Trigger node with "File Created" scoped to a specific folder, for example /Incoming. The trigger polls, so it can fire while a large upload is still in progress. Add a Wait node of 30 to 60 seconds, then fetch the file's size and compare it to the trigger payload before you proceed. If the size grew, wait again.

Scope is the other trap. If your Google credential only requests drive.file, the workflow sees files your app created and nothing else, so a video a teammate dragged in is invisible. You need drive.readonly plus drive.file, or full drive scope.

2. Give the API a URL it can actually fetch

Google Drive has no signed URLs, so an external service can't read a private file. Use the Drive node's Share operation to add a type: anyone, role: reader permission on that one file, then delete the permission after the job finishes. It's a two-minute window on a single file, not a public folder.

Then build the download URL. Don't use https://drive.google.com/uc?export=download&id=FILE_ID for large files: above roughly 100 MB, Google returns an HTML virus-scan interstitial instead of the video, and your API gets a web page where it expected an MP4. Use the API endpoint instead, which returns bytes directly:

https://www.googleapis.com/drive/v3/files/FILE_ID?alt=media&key=YOUR_API_KEY&supportsAllDrives=true

3. Send one compress job with a webhook target

An HTTP Request node posts the source URL, the compression settings, and a callback URL. The job runs on someone else's encoder, the node returns in under a second, and the execution ends there.

curl -X POST https://api.ffmpeg-micro.com/v1/jobs \
  -H "Authorization: Bearer $FFMPEG_MICRO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "input": "https://www.googleapis.com/drive/v3/files/FILE_ID?alt=media&key=...",
    "operation": "compress",
    "crf": 26,
    "preset": "veryfast",
    "webhook": "https://your-n8n.app/webhook/drive-compress-done"
  }'

Exact field names and the full option list are in the docs. The shape is the same for every job: submit, then poll or take a webhook, then download the output. There's no encoder to host, no FFmpeg build to keep current, and nothing in the workflow that can run long enough to hit a timeout. If you're running content ops at volume, the same call slots into the rest of a social media automation pipeline without changing shape.

4. Write the result back with a resumable upload

A second n8n workflow starts on a Webhook node, downloads the finished file from the URL in the callback payload, and uploads it to /Processed. This is the one point where bytes move through n8n, and now they're the compressed 110 MB instead of the original 1.4 GB.

If you're building the upload by hand with an HTTP Request node, Google's simple upload (uploadType=media) caps at 5 MB. Anything larger needs uploadType=resumable: POST to https://www.googleapis.com/upload/drive/v3/files?uploadType=resumable&supportsAllDrives=true, read the session URI out of the Location response header, then PUT the bytes to it in chunks that are multiples of 256 KB.

The FFmpeg command and the one-call equivalent

The compression itself is simple. This is the command that does the job on your laptop:

ffmpeg -i input.mov \
  -c:v libx264 -preset veryfast -crf 26 \
  -vf "scale=-2:1080" \
  -c:a aac -b:a 128k \
  -movflags +faststart \
  output.mp4

-crf 26 sets quality (lower is better and bigger), scale=-2:1080 caps height at 1080p while keeping width divisible by 2, and +faststart moves the moov atom to the front so the file starts playing before it's fully downloaded. On one 12-minute 1080p30 iPhone recording (1.02 GB, roughly 11 Mbps), here's what the CRF choice costs:

SettingsOutput sizeReduction
CRF 20, 1080p~380 MB63%
CRF 23, 1080p~230 MB77%
CRF 26, 1080p~130 MB87%
CRF 28, 1080p~95 MB91%
CRF 26, 720p~65 MB94%

High-motion footage lands well above these numbers and a static screen recording well below, so treat CRF 26 as a starting point and check one real file. Note that source .mov files from iPhones often carry HEVC, which not every downstream tool reads; the MOV to MP4 recipe covers that conversion in the same pattern.

Pitfalls that cost the most time

The failures here are rarely FFmpeg failures. They're Drive permission and trigger behavior, and they look like silent no-ops.

Watching a folder that contains your output folder gives you an infinite loop: the workflow writes the compressed file to /Incoming/Processed, the trigger sees a new file, and compresses that. Put /Processed outside the watched folder, or filter on a filename prefix and skip anything already named compressed_.

Shared drives need supportsAllDrives=true on every Drive API request and includeItemsFromAllDrives=true on any list or search call. Miss either one and the API returns an empty result set with a 200, not an error. Service accounts have their own trap: they get no personal storage quota, so uploading to a My Drive folder fails with storageQuotaExceeded even though the folder is shared with them. The same upload into a shared drive works, because the shared drive owns the file.

The virus-scan interstitial wastes an afternoon. Your workflow succeeds, the job comes back with an error about an invalid input, and the input was a 2 KB HTML page. Log the first bytes of what your API received when a job fails on a large file.

When this isn't the right shape

Passing URLs to an API is the wrong call for a couple of real cases. If the videos are confidential and you can't make even a link-shared, 60-second-window copy, keep the whole pipeline inside your own network with a self-hosted encoder and accept the operational cost. If your files are consistently under 20 MB and you're already self-hosting n8n with FFmpeg installed and working, the local encode is fine and there's no reason to add a network hop.

And if what you actually need is a templated video with layers, text, and a brand kit that a non-developer edits, a template-editor service is the better tool. This pattern is for a compression or transform step inside a pipeline, not a design surface. For chained transforms (clip, then caption, then reframe) the same async shape scales up, which we walked through in Clip, Caption, and Reformat Video in One n8n Workflow API Chain.

FAQ

Can I run FFmpeg on n8n Cloud?

You can't run FFmpeg on n8n Cloud. The Execute Command node is excluded from Cloud plans, and there's no container to install a binary into. The options are self-hosting n8n with a custom image, or calling a video processing API over HTTP, which works identically on Cloud and self-hosted.

How do I let a video API read a private Google Drive file?

Google Drive has no signed URL feature, so grant a temporary anyone with the link reader permission on the single file through the Drive node's Share operation, pass the files/FILE_ID?alt=media API URL to the processing service, and delete that permission as soon as the job's webhook fires. The exposure is one file for the length of one encode.

Why does my Drive-triggered workflow fire twice on the same video?

A Drive trigger firing twice usually means the polling interval caught the file mid-upload and again when it finished, or your output folder sits inside the folder you're watching. Compare the file's reported size across a short Wait node before processing, and keep the processed output in a sibling folder.

How large a video can this handle?

File size stops being the constraint once n8n isn't holding the bytes, because the workflow only passes a URL and receives a URL. The practical limits move to the processing service's own input ceiling and to Drive's download behavior, where files over roughly 100 MB need the alt=media API endpoint rather than the uc?export=download link.

Does the same pattern work in Make or Zapier?

The URL in, webhook out pattern works the same way in Make and Zapier. Both have a Google Drive watch-folder trigger, an HTTP module to submit the job, and a webhook trigger to catch the result, and neither can run FFmpeg locally, so offloading the encode is the only version that works.

Wire this up against the free tier and watch a real file compress before you commit to the architecture: sign up free and point one job at a Drive URL.

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.

Software EngineeringVideo ProcessingFFmpegCloud ArchitectureAPI DesignAutomation

Ready to process videos at scale?

Start using FFmpeg Micro's simple API today. No infrastructure required.

Get Started Free