remotion lambda aws cloud-rendering tutorial

Remotion Lambda: Cloud Rendering Guide for Developers

Remotion Lambda: Cloud Rendering Guide for Developers

Local rendering works fine when you are prototyping. Once you need to generate videos programmatically at scale — personalised marketing clips, automated weekly reports, on-demand social content — a developer’s MacBook becomes the bottleneck immediately. Remotion Lambda is the official answer to that problem: distribute rendering across AWS Lambda functions, pay only for what you use, and render in parallel rather than sequentially.

This guide walks through the entire setup from scratch: installing the package, configuring AWS IAM, deploying your Lambda function and site bundle, triggering renders via the renderMediaOnLambda API, and keeping costs under control.


Why Cloud Rendering? Local vs. Lambda

Before diving into setup, it is worth understanding what you actually get from cloud rendering.

Local rendering runs frames sequentially on a single CPU. A 60-second video at 30 fps means 1,800 frames processed one after another. On a fast development machine you might hit 4–8 frames per second, meaning a one-minute video takes three to seven minutes to render. That is manageable for occasional work but untenable for pipelines generating dozens or hundreds of videos.

Remotion Lambda splits the composition into chunks and assigns each chunk to a separate Lambda invocation. All chunks render simultaneously. A video that takes five minutes locally might finish in under thirty seconds when distributed across 50 or 100 concurrent Lambda functions. The trade-off is setup complexity and per-render cost — but at any meaningful scale, both are justified.

FactorLocalLambda
Speed (60-second video)3–7 min20–60 sec
CostYour electricity~$0.001–$0.05 per render (estimate)
ParallelismSingle machineHundreds of concurrent functions
ScalabilityManualAutomatic
Setup effortZero~30 minutes

Prerequisites

You need the following before starting:

  • A Remotion project already working locally (see npx create-video@latest if you need a scaffold)
  • Node.js 18 or later
  • An AWS account with billing enabled
  • AWS CLI installed and configured (aws configure) with an IAM user that has programmatic access
  • Basic familiarity with AWS IAM concepts (users, roles, policies)

Step 1 — Install @remotion/lambda

Add the Lambda package to your existing Remotion project. The version must match your core remotion package exactly:

npm install @remotion/lambda

Verify that @remotion/lambda and remotion share the same version number in package.json. Version mismatches are the most common cause of deployment failures.


Step 2 — Configure AWS IAM

Remotion Lambda needs two IAM entities: a user (for your local machine and CI pipeline to call AWS) and a role (for the Lambda function itself to access S3 and spawn child invocations).

Create the user policy

Generate the required policy JSON with the Remotion CLI:

npx remotion lambda policies user

Copy the JSON output. In the AWS Console, navigate to IAM → Policies → Create policy, select the JSON tab, paste the output, and save the policy with any name you like.

Next, attach this policy to your IAM user (the one whose credentials are in your local ~/.aws/credentials).

Create the Lambda execution role

npx remotion lambda policies role

Copy the output. In AWS Console, go to IAM → Roles → Create role, choose Lambda as the trusted entity, create a new policy with the copied JSON, and name the policy exactly:

remotion-lambda-policy

This exact name is required — the Remotion CLI looks for it when deploying functions.

Set your AWS region

All Remotion Lambda resources (functions, S3 buckets, and render jobs) must live in the same region. Set it as an environment variable:

export AWS_DEFAULT_REGION=us-east-1

Remotion supports multiple regions including us-east-1, eu-west-1, ap-northeast-1, and several others. The default is us-east-1. Pick the region closest to where your render requests originate to reduce latency and egress costs.


Step 3 — Deploy the Lambda Function

The Lambda function is the worker: it receives a chunk of frames, renders them using a headless Chromium binary, and uploads the output to S3.

Deploy via CLI

npx remotion lambda functions deploy

This command creates the Lambda function in your AWS account with the default configuration: 2048 MB of memory and a 120-second timeout. You should see output confirming the function name (something like remotion-render-3-3-xx-mem2048mb-disk2048mb-120sec).

Deploy via Node.js API

For programmatic deployments — useful in CI pipelines or deployment scripts — use deployFunction():

import { deployFunction } from "@remotion/lambda";

const { functionName } = await deployFunction({
  region: "us-east-1",
  timeoutInSeconds: 120,
  memorySizeInMb: 2048,
  createCloudWatchLogGroup: true,
});

console.log("Deployed function:", functionName);

The timeout must be less than 900 seconds. The Remotion team recommends 120 seconds or lower: if a chunk is taking longer than that, increasing concurrency is more efficient than raising the timeout.


Step 4 — Deploy Your Remotion Site

Your React components need to be bundled and uploaded to S3 so the Lambda function can load them. This is what deploySite() does.

Deploy via CLI

npx remotion lambda sites create src/index.ts --site-name=my-video

The command bundles your project, creates an S3 bucket in the configured region (or reuses an existing one), and uploads the bundle. It prints a serve URL — save it, you will need it for every render call.

Deploy via Node.js API

import { deploySite, getOrCreateBucket } from "@remotion/lambda";

const { bucketName } = await getOrCreateBucket({ region: "us-east-1" });

const { serveUrl } = await deploySite({
  bucketName,
  entryPoint: "./src/index.ts",
  region: "us-east-1",
  siteName: "my-video",
});

console.log("Serve URL:", serveUrl);

You only need to redeploy the site when your compositions change. The Lambda function and the site are independent — update one without touching the other.


Step 5 — Trigger a Render with renderMediaOnLambda

This is the core API call. renderMediaOnLambda() kicks off a distributed render and returns a renderId that you use to track progress.

import { renderMediaOnLambda } from "@remotion/lambda";

const { renderId, bucketName } = await renderMediaOnLambda({
  region: "us-east-1",
  functionName: "remotion-render-3-3-xx-mem2048mb-disk2048mb-120sec",
  serveUrl: "https://remotionlambda-xxxx.s3.us-east-1.amazonaws.com/sites/my-video/index.html",
  compositionId: "MyComposition",
  inputProps: {
    title: "Q2 Sales Report",
    highlightColor: "#3b82f6",
  },
  codec: "h264",
  imageFormat: "jpeg",
  maxRetries: 1,
  privacy: "public",
  outName: "output.mp4",
});

console.log("Render started, ID:", renderId);

Key parameters to understand:

  • compositionId — the id you gave the composition in <Composition id="MyComposition" ...>
  • inputProps — any serialisable object; your composition receives it via useCurrentFrame() context or getInputProps()
  • codec — typically "h264" for broad compatibility; "h265" for smaller files at equivalent quality
  • privacy"public" makes the output S3 object publicly accessible; "private" requires signed URLs for download
  • maxRetries — how many times a failed chunk retries before the render errors

Step 6 — Check Progress and Download the Output

renderMediaOnLambda() is non-blocking. You poll for progress using getRenderProgress():

import { getRenderProgress } from "@remotion/lambda";

const progress = await getRenderProgress({
  renderId,
  bucketName,
  functionName: "remotion-render-3-3-xx-mem2048mb-disk2048mb-120sec",
  region: "us-east-1",
});

if (progress.done) {
  console.log("Render complete:", progress.outputFile);
  console.log("File size:", progress.outputSizeInBytes, "bytes");
} else if (progress.fatalErrorEncountered) {
  console.error("Render failed:", progress.errors);
} else {
  console.log("Progress:", Math.round(progress.overallProgress * 100), "%");
}

A typical polling loop waits one second between checks. For webhook-style integrations, AWS SQS is a good pattern — the Remotion docs include an SQS integration guide if you want push notifications instead of polling.

When progress.done is true, progress.outputFile contains the public URL (if privacy: "public") or the S3 key. Download the file using the AWS SDK or redirect your users to the URL directly.


Step 7 — Cost Breakdown

Remotion Lambda costs break down into three components:

1. Lambda compute AWS bills per GB-second. A typical render uses a 2 GB Lambda function running for a few seconds per chunk. As a rough estimate:

  • A simple 30-second composition with 50 concurrent Lambdas: roughly $0.001–$0.005 per render
  • A complex 3-minute video with heavy graphics: roughly $0.01–$0.05 per render

These are estimates. Remotion’s documentation includes an estimatePrice() function that calculates expected cost before a render runs. Use it in development to catch unexpectedly expensive compositions early.

2. S3 storage and egress The site bundle and output files sit in S3. Storage is cheap (fractions of a cent per GB per month) but egress adds up if you serve many large files. Consider using CloudFront in front of S3 for rendered output at scale.

3. Remotion licence For commercial use, Remotion requires a company licence. Teams of four or more people require the company licence. Factor this into your cost model.

Cost optimisation tips

  • Reduce memory — the default 2048 MB is conservative; test at 1024 MB for lighter compositions and compare render time
  • Use JPEG frames — JPEG frame capture is significantly faster than PNG and reduces Lambda execution time
  • Increase concurrency — more concurrent functions means shorter wall-clock time, but similar or lower total cost because less time is spent idle
  • Cache the serve URL — only redeploy your site when compositions change
  • Use Graviton2 functions — if Remotion supports ARM-based Lambda in your region, it costs roughly 20% less per GB-second

FAQ

Q: Do I need to pay for AWS before trying Remotion Lambda? AWS has a Lambda free tier (1 million requests and 400,000 GB-seconds per month). Small-scale experimentation often falls within the free tier. However, you will need a billing-enabled account to increase Lambda concurrency limits above the default.

Q: Why does my Lambda deployment fail with a policy error? The most common cause is naming the Lambda execution role policy something other than remotion-lambda-policy. The Remotion CLI expects this exact string. Double-check the role and policy names in IAM.

Q: Can I use Remotion Lambda in any AWS region? Remotion supports a wide set of regions including us-east-1, us-east-2, us-west-2, eu-west-1, eu-central-1, ap-northeast-1, and more. Always deploy your function and S3 bucket in the same region. Splitting them across regions adds latency and cross-region data transfer costs.

Q: How long can a Lambda render take? Lambda has a maximum execution timeout of 15 minutes (900 seconds). Remotion recommends keeping individual Lambda invocations under 120 seconds by increasing concurrency rather than timeout. A highly concurrent render with many short-lived Lambdas is faster and cheaper than a few long-running ones.

Q: Can I pass dynamic data to each render? Yes. Use the inputProps parameter in renderMediaOnLambda(). Your composition receives the props via getInputProps() from remotion. This is the standard pattern for data-driven video — pass a customer name, a chart dataset, or a product SKU and generate a unique video for each.

Q: What happens if a Lambda chunk fails mid-render? Remotion retries failed chunks according to the maxRetries setting (default is typically 1). If retries are exhausted, the render is marked as failed and progress.fatalErrorEncountered becomes true. You can inspect progress.errors for stack traces.

Q: Does Remotion Lambda support rendering to formats other than MP4? Yes. The codec parameter accepts "h264", "h265", "vp8", "vp9", "gif", and "prores", among others. Use "gif" for short looping clips for web use, and "prores" for broadcast-quality masters.

Q: How do I keep the serve URL up to date in production? Store the serve URL returned by deploySite() in an environment variable or a configuration store. Only update it when you redeploy the site. A common pattern is to write the URL to a .env file or SSM Parameter Store as part of a CI/CD step that runs deploySite().


Summary

Remotion Lambda transforms programmatic video from a local curiosity into a production-scale infrastructure component. The setup investment is roughly 30 minutes: install the package, configure two IAM entities, deploy a function and a site bundle, and you have an API endpoint that can render any Remotion composition in the cloud in seconds.

The key steps are:

  1. npm install @remotion/lambda
  2. npx remotion lambda policies user and policies role → configure IAM
  3. npx remotion lambda functions deploy → deploy the Lambda worker
  4. npx remotion lambda sites create → bundle and upload your compositions
  5. renderMediaOnLambda() → trigger a render
  6. getRenderProgress() → poll for completion and retrieve the output URL

From here, the natural next step is wrapping these calls in a queue (SQS, BullMQ, or similar) to handle bursts of render requests without hammering Lambda’s concurrency limits.


Speed Up Renders with Optimised Templates

A Lambda setup only delivers maximum value when the compositions themselves are well-structured. Poorly optimised React components — unnecessary re-renders, uncompressed assets, excessively large bundles — increase Lambda execution time and cost even with perfect infrastructure configuration.

RenderComp offers a library of production-ready Remotion templates pre-optimised for Lambda rendering: lightweight bundles, JPEG-friendly frame designs, and clean prop interfaces that slot directly into inputProps. Browse the full library at rendercomp.com and accelerate your cloud rendering pipeline today.

Ready to ship

Get 1,400+ Remotion Templates

Lifetime license. TypeScript-first. Ship polished video in minutes, not days.

Get RenderComp →