Skip to Content

Proxies

A proxy is a low-resolution copy of a clip that the viewport uses in place of the original, so that heavy footage scrubs at a usable rate. Output never sees it.

Why they exist

Random access is what makes 4K slow. To show frame n of a long-GOP clip the decoder has to go back to the previous keyframe and decode forward, and that work scales with the picture size and with how far back the keyframe is. Jumping around a 4K H.264 or HEVC clip therefore costs far more than the same jump in a 1080p copy, however fast the GPU that draws the result.

The engine decodes footage itself, with the GPU’s hardware decoder where there is one, and cached playback holds full rate once frames are cached. A proxy is for the case those do not cover: heavy footage you need to scrub freely before anything is cached. A proxy is smaller, and it is encoded with a short GOP (-g 12), so a seek never has far to go back.

Earlier versions of this page quoted a table of seek and upload timings. It was measured in Chromium’s video decoder, which no longer decodes your footage, so it has been removed rather than left to mislead. Whether a proxy helps on your machine is a question the viewport’s performance HUD answers in a few seconds.

The safety property

A proxy is substituted for the interactive viewport only. Never for output.

That is enforced by polarity rather than by vigilance. Substitution is something the interactive viewport asks for; the export, the Render Queue and the command line never ask for it, so they reach the original footage by doing nothing. There is no opt-out to forget.

Substitution is pixels only, at a single chokepoint. Size, duration, frame rate, pixel aspect, alpha interpretation, loop count, trim, slip, stretch and time remap all keep reading the original asset. There is no second record to keep in step, so a proxy cannot drift out of alignment with its source.

Using one

The proxy row lives on the asset, next to Interpret Footage ▸ Alpha — the same shape of thing, because the record belongs to the file. One proxy therefore speeds up every layer using that file, in every composition.

The row always states which state the file is in, because a proxy silently in use looks like a quality bug:

StateMeaning
Full resolutionNo proxy. The row still says what one would be — 1920 × 1080 for a 4K source — so the action is a known quantity before you click it
GeneratingAn ffmpeg job is running. The asset renders at full resolution meanwhile
ReadyA decodable stand-in exists
In useReady, and the global switch is on. Styled loudly rather than left to be inferred from how soft the picture looks
FailedGeneration ran and failed, or the file went missing. The error says why, and renders fall back to full resolution

The global switch — proxies on or off for the whole project — is repeated on the row rather than buried in a menu.

Generating, attaching, detaching

Generate runs ffmpeg as a child process, outside the interface, for the same reason the export encode does: the transcode must not compete with the UI, because the whole promise is that the asset stays usable at full resolution while it runs. The call returns as soon as the job is queued — import is never blocked. It uses the same ffmpeg as export, which every installer ships — see ffmpeg & codecs.

The target is a halved long edge, at or below 1920, rounded to even dimensions. Alpha sources become VP9 WebM; everything else becomes H.264 MP4.

Cancel is real, not cooperative: the child process is killed. Quitting kills any survivors, which is the other half of why a generating record is never persisted — there would be no process behind it after a reload.

Attach points the record at a file you supply yourself. It needs no ffmpeg, which is the route when ffmpeg is not available (a build from source with none on PATH, say). Detach removes the proxy record, and deliberately does not delete a file you attached.

Every failure path lands the asset back at full resolution rather than in an error state. A failed proxy is a missed optimisation; a broken asset is a lost shot. The enumerated cases: no ffmpeg, encode error, a throwing bridge, an unreadable original, empty output, cancellation, an asset deleted mid-encode, and an asset re-imported mid-encode — where the stale job re-reads the record after every await and stands down rather than overwriting the new one.

When it refuses, and why

Refusals are explained rather than attempted, and the check is pure — so the UI can disable the action and say why without starting anything.

ReasonMessage
No ffmpegProxies need ffmpeg, which this build cannot reach. You can still attach one
Not videoOnly video footage can have a proxy
Too smallThis footage is already small enough to scrub smoothly
Unknown sizeThis file’s dimensions are unknown, so no proxy size can be chosen
Already runningA proxy is already being generated for this file
Source unreadableThe original file could not be read

“Too small” means a long edge at or below 1280. Below that the source is already small enough to scrub smoothly, so halving it would buy little and cost the disk and the wait.

Last updated on