LiveKit LogoDocs

Server / Recording and Livestreaming / Egress


Record or livestream your LiveKit rooms

On this page

OverviewEgress TypesRoom Composite EgressTrack Composite EgressTrack EgressFilenamesSupported OutputS3Google Cloud StorageAzureService ArchitectureAPIStartRoomCompositeEgressStartTrackCompositeEgressStartTrackEgressStartWebEgressUpdateLayoutUpdateStreamListEgressStopEgressDeployment


LiveKit Egress gives you a powerful and consistent set of APIs to export any room or individual tracks from a LiveKit session.

It supports recording to a MP4 file or HLS segments, as well as exporting to livestreaming services like YouTube Live, Twitch, and Facebook via RTMP(s).

For LiveKit Cloud customers, Egress is ready to use with your project without additional configuration. When self-hosting LiveKit, Egress is a separate component that needs to be deployed.

Egress Types

Room Composite Egress

Export an entire room's video and/or audio using a web layout rendered by chrome.

Example use case: recording a meeting for team members to watch later.

Track Composite Egress

Sync and export up to one audio and one video track. Will transcode and mux.

Example use case: exporting audio+video from many cameras at once during a production, for use in additional post-production.

Track Egress

Export individual tracks directly. Video tracks are not transcoded.

Example use case: streaming an audio track to a captioning service via websocket.


The below templates can also be used in request filename/filepath parameters:

Egress Type{room_id}{room_name}{time}{publisher_identity}{track_id}{track_type}{track_source}
Room Composite
Track Composite
  • If no filename is provided with a request, one will be generated in the form of "{room_name}-{time}".
  • If your filename ends with a /, a file will be generated in that directory.
  • If your filename is missing an extension or includes the wrong extension, the correct one will be added.


Request filenameResulting filename

Supported Output

Egress TypeMP4 FileOGG FileWebM FileHLS (TS SEGMENTS)RTMP(s) StreamWebSocket Stream
Room Composite
Track Composite

Files can be uploaded to any S3 compatible storage, Azure, or GCP.


message S3Upload {
string access_key = 1;
string secret = 2;
string region = 3;
string endpoint = 4;
string bucket = 5;

Egress supports any S3-compatible storage provider, including DigitalOcean Spaces. When endpoint is left empty, it'll use AWS's regional endpoints. region is required when endpoint is not set.

const output = {
fileType: EncodedFileType.MP4,
filepath: 'livekit-demo/room-composite-test.mp4',
s3: {
accessKey: 'aws-access-key',
secret: 'aws-access-secret',
bucket: 'my-bucket',
endpoint: 'https://my.s3.endpoint',
await egressClient.startRoomCompositeEgress('my-room', output);

Google Cloud Storage

message GCPUpload {
bytes credentials = 1;
string bucket = 2;

For Egress to upload to Google Cloud Storage, you'll need to provide credentials in JSON.

This can be obtained by first creating a service account that has permissions to create storage objects (i.e. Storage Object Creator). Then create a key for that account and export as a JSON file. We'll refer to this file as credentials.json.

import * as fs from 'fs';
const content = fs.readFileSync('/path/to/credentials.json')
const output = {
fileType: EncodedFileType.MP4,
filepath: 'livekit-demo/room-composite-test.mp4',
gcp: {
// credentials needs to be a UInt8Array
credentials: content,
bucket: 'my-bucket',
await egressClient.startRoomCompositeEgress('my-room', output);


message AzureBlobUpload {
string account_name = 1;
string account_key = 2;
string container_name = 3;

In order to upload to Azure Blob Storage, you'll need the account's shared access key.

const output = {
fileType: EncodedFileType.MP4,
filepath: 'livekit-demo/room-composite-test.mp4',
azure: {
accountName: 'my-account',
accountKey: 'shared-access-key',
containerName: 'my-container',
await egressClient.startRoomCompositeEgress('my-room', output);

Service Architecture

Depending on your request type, the egress service will either launch a web template in Chrome and connect to the room (room composite requests), or it will use the sdk directly (track and track composite requests). It uses GStreamer to encode, and can output to a file or to one or more streams.

Egress instance


All RPC definitions and options can be found here.

The Egress API exists within our server SDKs and CLI

You can also use curl to interact with Egress APIs. To do so, you can POST to:


Requests to Egress service need roomRecord permission in the access token.

For example:

% curl -X POST https://<your-livekit-host>/twirp/livekit.Egress/StartRoomCompositeEgress \
-H "Authorization: Bearer <access-token>" \
-H 'Content-Type: application/json' \
-d '{"room_name": "your-room", "segments": {"filename_prefix": "your-hls-playlist.m3u8", "s3": {"access_key": "<key>", "secret": "<secret>", "bucket": "<bucket>", "region": "<bucket-region>"}}}'


See Composite Recording


See Track Composite


See Track Egress


See Web Egress


Used to change the web layout on an active RoomCompositeEgress.

const info = await egressClient.updateLayout(egressID, 'grid-light');


Used to add or remove stream urls from an active stream

Note: you can only add or remove outputs from a stream (RTMP output instead of filepath).

const output = {
protocol: StreamProtocol.RTMP,
urls: ['rtmp://<stream-key>']
var info = await egressClient.startRoomCompositeEgress('my-room', 'speaker-dark', output);
const streamEgressID = info.egressId;
info = await egressClient.updateStream(


Used to list active egress. Does not include completed egress.

const res = await egressClient.listEgress();


Stops an active egress.

const info = await egressClient.stopEgress(egressID);


See the deployment docs for more info on deployment, config, and autoscaling.


Chevron IconServer: Webhooks
LiveKit logo