---
image: /generated/articles-docs-lambda-setup.png
id: setup
title: Setup
slug: /lambda/setup
crumb: 'Lambda'
---

import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';

<YouTube minutes={18} href="https://www.youtube.com/watch?v=kFVd3KnfwYY" thumb="https://i.ytimg.com/vi/kFVd3KnfwYY/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLCJOz2mu_A24NvjFQGm6GjUVssnUQ" title="How to set up Remotion Lambda" />

## 1. Install `@remotion/lambda`

```bash
npx remotion add @remotion/lambda
```

## 2. Create role policy

- Go to [AWS account IAM Policies section](https://console.aws.amazon.com/iamv2/home?#/policies)
- Click on "Create policy"
- Click on JSON
- In your project, type `npx remotion lambda policies role` in the command line and copy it into the "JSON" field on AWS.
- Click next. Give the policy **exactly** the name `remotion-lambda-policy`. The other fields can be left as they are.
- On the tags page, you don't need to fill in anything. Click next again.

## 3. Create a role

- Go to [AWS account IAM Roles section](https://console.aws.amazon.com/iamv2/home#/roles)
- Click "Create role".
- Under "Use cases", select "Lambda". Click next.
- Under "Permissions policies", filter for `remotion-lambda-policy` and click the checkbox to assign this policy. Click next.
- In the final step, name the role `remotion-lambda-role` **exactly**. You can leave the other fields as is.
- Click "Create role" to confirm.

## 4. Create a user

- Go to [AWS account IAM Users section](https://console.aws.amazon.com/iamv2/home#/users)
- Click `Add users`
- Enter any username, such as `remotion-user`.
- **Don't check** the "Enable console access" option. You don't need it.
- Click "Next".
- Click "Next" again without changing any settings. You should now be on the "Review and Create" step.
- Click "Create user".

## 5. Create an access key for the user

- Go to [AWS account IAM Users section](https://console.aws.amazon.com/iamv2/home#/users)
- Click on the name of the user that was created in step 4.
- Navigate to the "Security Credentials" tab, and scroll down to the "Access Keys" section.
- Click the "Create access key" button.
- Select "Application running on an AWS compute service".
- Ignore warnings that might appear and check the "I understand the recommendations..." checkbox.
- Click "Next".
- Click "Create access key".
- Add a `.env` file to your project's root and add the credentials you just copied in the following format:

```txt title=".env"
REMOTION_AWS_ACCESS_KEY_ID=<Access key ID>
REMOTION_AWS_SECRET_ACCESS_KEY=<Secret access key>
```

## 6. Add permissions to your user

- Go to [AWS account IAM Users section](https://console.aws.amazon.com/iamv2/home#/users)
- Select the user you just created.
- Click "Add inline policy" under the "Add Permissions" dropdown in the "Permissions policies" panel.
- Click the tab "JSON".
- Enter in your terminal: `npx remotion lambda policies user` and copy into the AWS text field what gets printed.
- Click "Review policy".
- Give the policy a name. For example `remotion-user-policy`, but it can be anything.
- Click "Create policy" to confirm.

## 7. Optional: Validate the permission setup

Check all user permissions and validate them against the AWS Policy simulator by executing the following command:

```bash
npx remotion lambda policies validate
```

<hr />

For the following steps, you may execute them on the CLI, or programmatically using the Node.JS APIs.

## 8. Deploy a function

<Tabs
defaultValue="cli"
values={[
{ label: 'CLI', value: 'cli', },
{ label: 'Node.JS', value: 'node', },
]
}>
<TabItem value="cli">

Deploy a function that can render videos into your AWS account by executing the following command:

```bash
npx remotion lambda functions deploy
```

</TabItem>
<TabItem value="node">

You can deploy a function that can render videos into your AWS account using [`deployFunction()`](/docs/lambda/deployfunction).

```ts twoslash
import {deployFunction} from '@remotion/lambda';

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

The function name is returned which you'll need for rendering.

</TabItem>
</Tabs>

The function consists of necessary binaries and JavaScript code that can take a [serve URL](/docs/terminology/serve-url) and make renders from it. A function is bound to the Remotion version, if you upgrade Remotion, you [need to deploy a new function](/docs/lambda/upgrading). A function does not include your Remotion code, it will be deployed in the next step instead.

## 9. Deploy a site

<Tabs
defaultValue="cli"
values={[
{ label: 'CLI', value: 'cli', },
{ label: 'Node.JS', value: 'node', },
]
}>
<TabItem value="cli">

Run the following command to deploy your Remotion project to an S3 bucket. Pass as the last argument the [entry point](/docs/terminology/entry-point) of the project.

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

A [Serve URL](/docs/terminology/serve-url) will be printed pointing to the deployed project.

When you update your Remotion code in the future, redeploy your site. Pass the same [`--site-name`](/docs/lambda/cli/sites/create#--site-name) to overwrite the previous deploy. If you don't pass [`--site-name`](/docs/lambda/cli/sites/create#--site-name), a unique URL will be generated on every deploy.

</TabItem>
<TabItem value="node">

First, create an S3 bucket in your preferred region. If one already exists, it will be used instead:

```ts twoslash
import {getOrCreateBucket} from '@remotion/lambda';

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

Next, build your Remotion project and upload the resulting bundle to the bucket. The entry point is the file where [`registerRoot()`](/docs/register-root) is called.

```ts twoslash
import path from 'path';
import {bundle} from '@remotion/bundler';
import {deploySiteFromBundle, getOrCreateBucket} from '@remotion/lambda';

const {bucketName} = await getOrCreateBucket({
  region: 'us-east-1',
});
// ---cut---
const bundleDir = await bundle({
  entryPoint: path.resolve(process.cwd(), 'src/index.ts'),
});

const {serveUrl} = await deploySiteFromBundle({
  bucketName,
  bundleDir,
  region: 'us-east-1',
  siteName: 'my-video',
});
```

When you update your Remotion code, create and deploy a new bundle. Pass the same [`siteName`](/docs/lambda/deploysitefrombundle#sitename) to overwrite the previous deployment. If you don't pass [`siteName`](/docs/lambda/deploysitefrombundle#sitename), a unique URL will be generated on every deployment.

</TabItem>
</Tabs>

## 10. Check AWS concurrency limit

Check the concurrency limit that AWS has given to your account:

```
npx remotion lambda quotas
```

By default, it is `1000` concurrent invocations per region. However, new accounts might have a limit [as low as `10`](/docs/lambda/troubleshooting/rate-limit#new-accounts-using-aws-lambda). Each Remotion render may use as much as 200 functions per render concurrently, so if your assigned limit is very low, [you might want to request an increase right away](/docs/lambda/troubleshooting/rate-limit#request-an-increase).

## 11. Render a video

<Tabs
defaultValue="cli"
values={[
{ label: 'CLI', value: 'cli', },
{ label: 'Node.JS', value: 'node', },
]
}>
<TabItem value="cli">

Take the URL you received from the step 9 - your "serve URL" - and run the following command. Also pass in the [ID of the composition](/docs/composition) you'd like to render.

```bash
npx remotion lambda render <serve-url> <composition-id>
```

Progress will be printed until the video finished rendering. Congrats! You rendered your first video using Remotion Lambda 🚀

</TabItem>
<TabItem value="node">

You already have the function name from a previous step. But since you only need to deploy a function once, it's useful to retrieve the name of your deployed function programmatically before rendering a video in case your Node.JS program restarts. We can call [`getFunctions()`](/docs/lambda/getfunctions) with the `compatibleOnly` flag to get only functions with a matching version.

```ts twoslash
import {getFunctions, renderMediaOnLambda, getRenderProgress} from '@remotion/lambda/client';

const functions = await getFunctions({
  region: 'us-east-1',
  compatibleOnly: true,
});

const functionName = functions[0].functionName;
```

We can now trigger a render using the [`renderMediaOnLambda()`](/docs/lambda/rendermediaonlambda) function.

```ts twoslash
import {getFunctions, renderMediaOnLambda, getRenderProgress} from '@remotion/lambda/client';

const url = 'string';
const functions = await getFunctions({
  region: 'us-east-1',
  compatibleOnly: true,
});

const functionName = functions[0].functionName;
// ---cut---

const {renderId, bucketName} = await renderMediaOnLambda({
  region: 'us-east-1',
  functionName,
  serveUrl: url,
  composition: 'HelloWorld',
  inputProps: {},
  codec: 'h264',
  imageFormat: 'jpeg',
  maxRetries: 1,
  framesPerLambda: 20,
  privacy: 'public',
});
```

The render will now run and after a while the video will be available in your S3 bucket. You can at any time get the status of the video render by calling [`getRenderProgress()`](/docs/lambda/getrenderprogress).

```ts twoslash
import {getFunctions, renderMediaOnLambda, getRenderProgress} from '@remotion/lambda/client';

const url = 'string';
const functions = await getFunctions({
  region: 'us-east-1',
  compatibleOnly: true,
});

const functionName = functions[0].functionName;

const {renderId, bucketName} = await renderMediaOnLambda({
  region: 'us-east-1',
  functionName,
  serveUrl: url,
  composition: 'HelloWorld',
  inputProps: {},
  codec: 'h264',
  imageFormat: 'jpeg',
  maxRetries: 1,
  framesPerLambda: 20,
  privacy: 'public',
});
// ---cut---
while (true) {
  await new Promise((resolve) => setTimeout(resolve, 1000));
  const progress = await getRenderProgress({
    renderId,
    bucketName,
    functionName,
    region: 'us-east-1',
  });
  if (progress.done) {
    console.log('Render finished!', progress.outputFile);
    process.exit(0);
  }
  if (progress.fatalErrorEncountered) {
    console.error('Error enountered', progress.errors);
    process.exit(1);
  }
}
```

This code will poll every second to check the progress of the video and exit the script if the render is done. Congrats! [Check your S3 Bucket](https://s3.console.aws.amazon.com/s3/) - you just rendered your first video using Remotion Lambda 🚀

</TabItem>
</Tabs>

## Next steps

- Select [which region(s)](/docs/lambda/region-selection) you want to run Remotion Lambda in.
- Familiarize yourself with the CLI and the Node.JS APIs (list in sidebar).
- Learn how to [upgrade Remotion Lambda](/docs/lambda/upgrading).
- Before going live, go through the [Production checklist](/docs/lambda/checklist).
- If you have any questions, go through the [FAQ](/docs/lambda/faq) or ask in our [Discord channel](https://remotion.dev/discord)
