Blog 4 min read

Why film grain makes your Remotion renders slow (and your files huge)

Two 15-second Remotion videos, same machine: one renders in 19 seconds at 11 MB, the other takes 25 and weighs 33 MB. The difference is real video footage and film grain — here's what each one actually costs, and what to do about it.

I just finished a glitchy promo video for Inktrap in Remotion: real screen-recording footage, hard cuts, boiling film grain, dust, a VHS band along the bottom. Same length and resolution as the motion templates I ship, rendered on the same machine. The templates render a 540-frame video in about 19 seconds and produce files around 11 MB. The promo takes 25 seconds and comes out at 33 MB.

Nothing was wrong. The difference is exactly two things, and knowing them changes how you build.


A render is two jobs, not one

When you run npx remotion render, two very different programs do the work:

  1. Chrome draws every frame. Your React markup becomes pixels, one frame at a time.
  2. The encoder compresses the frames into a video. By default that’s x264 producing an H.264 MP4.

Each job has its own idea of what “expensive” means, and the two looks land on opposite ends of both.


Drawing: DOM is nearly free, footage is not

The motion templates are webp images moved around with CSS transforms. Chrome rasterizes that kind of thing all day; a 1920x1080 frame of images and type costs almost nothing, even with motion blur sampling the frame multiple times.

Embedding real footage is a different job. <OffthreadVideo> has to seek into the source file and decode the exact frame that belongs at the current timestamp — for my promo, a frame of a 2560x1680 H.264 screen recording, 450 times. Decoding is fast when it’s linear, because each frame builds on the previous one. But glitch edits are the opposite of linear: every stutter and jump-cut lands mid-stream, and the decoder has to walk from the nearest keyframe to the frame you asked for. The cuts are the point of the edit, and they’re also the cost.


Encoding: grain is the worst thing you can feed a codec

This one surprised me more. H.264 gets its magic from inter-frame compression: for each 16x16 block of pixels, the encoder tries to say “same as the last frame, moved a bit.” On the templates, most blocks qualify — flat backgrounds, smooth gradients, one moving card. Frames encode fast and small.

Film grain breaks that promise on every block of every frame. My grain layer re-seeds every three frames, the flicker changes the whole frame’s brightness every frame, and dust particles swap positions. No block ever matches its predecessor, so the encoder falls back to encoding everything from scratch, every frame. That’s where the extra render time goes, and it’s why the file tripled: 15 seconds of “nothing matches” simply contains more information than 15 seconds of “one thing moves.”

It’s the same reason your screen recordings of code editors are tiny and your camera footage is not. Codecs charge you for entropy.


What to do about it

None of this means avoid grain — the look was worth every megabyte. But a few things follow:

  • Know which layer is costing you. If renders got slower after you added footage, it’s decode. If the file ballooned, it’s noise. Different fixes.
  • Prefer generated noise over noisy sources. My grain is three tiled SVG turbulence images swapped per frame — cheap to draw. The cost lives entirely in encoding. If the grain came baked into 4K stock footage, I’d be paying on both sides.
  • --crf is your file-size lever. Grainy content at the default quality produces huge files for invisible gains. Bumping CRF to 26-28 on a grainy piece often halves the size before anyone can tell.
  • Cut footage linearly when you can. Every seek has a cost; a passage that plays straight through decodes faster than one that stutters. Spend seeks where the edit earns them.
  • Don’t optimize a 25-second render. I almost did. The templates render fast because images and transforms are the fast path — which is exactly why the Remotion templates are built that way. Promos with real footage will always pay the decode tax, and 6 extra seconds is a fine price for the look.

The quiet takeaway: when a render feels slow, the question isn’t “is Remotion slow,” it’s “which of the two jobs did my design just make harder?” Once you can answer that, the fix is usually obvious.

/Michael Andreuzza