How we rendered 350 motion-design previews on Remotion Lambda

The catalog needed real hover-preview video for every item, not static posters. Rendering 350 clips serially on one machine would have taken hours. Here is what we actually did.

Aravind2 min readengineeringremotion

The catalog has 350 motion components and blocks, and until recently every one of them showed a static poster image in the grid. A poster tells you almost nothing about a motion component — the entire value of the thing is the motion, and a still frame throws that away. We needed real video.

The constraint that decided the approach

350 items, each a few seconds long, rendered serially on one machine, would have taken hours and tied up that machine the whole time. The items are independent of each other — rendering item 40 has no dependency on item 39 — which makes this an embarrassingly parallel problem. That is exactly what Remotion Lambda is for: instead of one process working through a queue, each item renders as its own concurrent Lambda invocation.

The actual code change was small. @remotion/lambda takes a composition ID and renders it on AWS infrastructure instead of locally. The work was in the batch script wrapping it — firing all 350 renders, tracking which ones completed, and handling the ones that didn't.

Sizing the output

A hover preview in a grid tile does not need to be 1080p. We rendered at half scale, 960×540, which roughly quarters the output size against full resolution with no visible loss at the size these actually display. Alongside the video, each item also gets a static poster JPEG — the video is what plays on hover, the poster is what the browser shows before that, so the tile never shows a blank space while the clip loads.

Everything landed in a Cloudflare R2 bucket. The final tally for the sweep was 349 successful renders totaling just under 110MB — small enough that egress cost is a non-issue, which matters because these are decorative hover previews, not billable output.

The one item that didn't render on the first pass

One composition — a liquid-glass effect — is unusually expensive to render. It kept timing out at the same chunk size everything else used. The fix was mechanical rather than clever: split it into smaller frame chunks so each Lambda invocation had less work to finish before its own timeout. It rendered fine at a lower resolution once the chunking was right, and shipped at 480×270 rather than the standard 960×540 — a visible exception in the data, and worth knowing rather than quietly overriding.

Why this is the same pipeline as the real product

The render pipeline generating these previews is not a special demo mode — it is the same Remotion-based rendering that produces an actual customer video. Watching a preview autoplay on hover on the catalog page is watching the real output the product makes, at reduced resolution and without a specific brief attached. That was worth getting right: a preview that misrepresents what shipping actually looks like is worse than no preview.

349 successful renders, one exception that needed different chunking, and a batch pipeline that will run again the next time the catalog grows.

Make this in Animatiq

Briefed in a sentence, editable line by line afterward.

Open the composer