Skip to content
38 changes: 29 additions & 9 deletions docs/deploy/aws-lambda.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,22 @@ Most often a Lambda cold-start chain on a many-chunk render. The Map state's res

If progress doesn't advance for >10 minutes, check the Step Functions execution in the AWS console — failed Lambda invocations include the typed error name (`FONT_FETCH_FAILED`, `FFMPEG_VERSION_MISMATCH`, etc.) which short-circuits the state machine.

### Long-video planning times out

Check the failed invocation's CloudWatch logs to distinguish Plan from RenderChunk. In current versions, `VIDEO_EXTRACTION_FAILED` with `ffmpeg_timeout` means extraction stopped producing new frames for the configured interval, which defaults to 300,000 ms. Frame progress resets that timer, so an extraction can run for longer than five minutes while it keeps producing frames. Normal frame extraction splits long ranges into segments of up to two minutes, including variable-frame-rate sources.

Plan v2 leaves eligible constant-frame-rate SDR extraction to chunk workers after a short timing probe. Variable-frame-rate sources and required HDR color conversions still extract during Plan; the deprecated v1 path also extracts videos during Plan. Smaller chunks or a higher `maxParallelChunks` can reduce each chunk's work, but do not divide extraction that still happens during Plan.

If the logs show that a slow extraction needs a longer gap between frames, and the work fits within the Lambda invocation budget, increase `FFMPEG_PROCESS_TIMEOUT_MS` on the deployed function that runs the failing phase. The default arm64 deployment uses the video function for Plan and RenderChunk. Setting the variable only in the terminal running `lambda render` does not configure the remote function. CDK users can configure the construct's render function before deploying. Here, `render` is the `HyperframesRenderStack` instance created in the CDK example above:

```ts
render.renderFunction.addEnvironment("FFMPEG_PROCESS_TIMEOUT_MS", "600000");
```

This allows extraction to wait ten minutes without a new frame. Each Plan, RenderChunk, and Assemble invocation must still finish within its own configured Lambda timeout, at most 15 minutes, including downloads, processing, and uploads, and fit its `/tmp` storage. Measure the failing phase's elapsed time and storage use in CloudWatch.

If planning cannot fit, split the composition into shorter, frame-aligned projects, render each as a separate job, and combine the results. Choose part lengths from measured planning times. There is no fixed maximum video length: resolution, frame rate, codec, and Lambda resources affect extraction time.

### Tearing down doesn't reclaim S3 storage

The render bucket is created with CloudFormation `Retain` on delete — `hyperframes lambda destroy` (or `sam delete`) tears the function + state machine down but the bucket survives. This is intentional: it protects final-rendered MP4s from being lost when you re-deploy. To fully reclaim storage, empty + delete the bucket via the AWS console / `aws s3 rb`.
Expand All @@ -254,15 +270,19 @@ The stack was deployed by an earlier version that cannot read this version's sit
- Each `--region` is an independent stack. Cross-region failover is not built
in.
- The distributed AWS path is SDR-only.
- Each render chunk extracts only the video frames it shows, so the plan step
no longer grows with video length. On a 10,240 MB function, a 26-minute
576×1024 24 fps H.264 clip plans in about 20 seconds. Each chunk reads
only the byte ranges of each video it shows, straight from the bucket. Variable-frame-rate and HDR
sources are the exception: the plan step still extracts every frame of those,
inside Lambda's 15-minute limit, in 2-minute segments, so
`FFMPEG_PROCESS_TIMEOUT_MS` applies to each segment, not to the whole clip.
- A chunk must also finish inside 15 minutes. For long renders, raise
`--max-parallel-chunks` (`maxParallelChunks` in the SDK) so each chunk covers
- Plan v2 leaves eligible constant-frame-rate SDR video extraction to each
render chunk after a short timing probe. Each chunk extracts only the frames
it shows. On a 10,240 MB function, a 26-minute 576×1024 24 fps H.264 clip
plans in about 20 seconds. Each chunk reads only the byte ranges of each
video it shows, straight from the bucket. Variable-frame-rate sources and
required HDR color conversions still need extraction during Plan. Normal
frame extraction uses segments of up to two minutes, including variable-frame-rate
sources; `FFMPEG_PROCESS_TIMEOUT_MS` limits how long extraction can go without
producing a new frame. See [long-video planning timeouts](#long-video-planning-times-out)
for timeout configuration and splitting jobs that cannot fit.
- Plan, each RenderChunk, and Assemble must finish within their own configured
Lambda timeout, at most 15 minutes, and fit the function's `/tmp` storage.
For long renders, raise `--max-parallel-chunks` (`maxParallelChunks` in the SDK) so each chunk covers
fewer frames.

## Related topics
Expand Down
6 changes: 4 additions & 2 deletions docs/packages/aws-lambda.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -44,16 +44,18 @@ The Lambda adapter wraps the distributed producer primitives behind one dispatch

<Steps>
<Step title="Plan">
Downloads the project archive from S3, runs the producer planner, and uploads the plan directory.
Fetches the project inputs from S3, probes the composition, prepares audio, and publishes the plan artifacts. Plan v2 defers eligible constant-frame-rate SDR video extraction to the chunk workers; variable-frame-rate sources and required HDR color conversions still run during planning.
</Step>
<Step title="Render chunks">
Step Functions fans out chunk jobs. Each Lambda invocation downloads the plan assets, renders one chunk, and uploads the result.
Step Functions fans out chunk jobs. Each Lambda invocation downloads the assets it needs, extracts its deferred video frames, renders one chunk, and uploads the result.
</Step>
<Step title="Assemble">
Downloads all rendered chunks plus audio assets, assembles the final output, and writes the finished file to S3.
</Step>
</Steps>

All three phases must fit the configured per-invocation Lambda timeout, at most 15 minutes, and the function's temporary storage. Smaller chunks can reduce each worker's extraction and rendering work, but do not divide video extraction that still happens in Plan. See [long-video planning limits](/deploy/aws-lambda#long-video-planning-times-out) for FFmpeg frame-stall timeouts and how to split jobs that cannot fit.

The handler uses `@sparticuz/chromium` by default, with a build-time fallback for bundling `chrome-headless-shell` directly when needed.

## Using the SDK
Expand Down
Loading