Skip to content

Data streams v2#1985

Merged
1egoman merged 68 commits into
mainfrom
data-streams-v2
Jul 23, 2026
Merged

Data streams v2#1985
1egoman merged 68 commits into
mainfrom
data-streams-v2

Conversation

@1egoman

@1egoman 1egoman commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

Warning

This change relies on some new SFU updates to be able to function. Checkout main (really, livekit/livekit@86a79f8 or later), build + run the SFU locally, and point any test app at this local SFU for testing.

Overview

Data streams v2 consists of some updates to data streams to add three things:

  1. Single packet data streams for short (< 15kb), finite length payloads
  2. DEFLATE compression, when both the sender and all receivers support compression/decompression
  3. A maximum 15kb size for data stream attributes to close this as a DOS vector

This pull request contains the initial web implementation and initial data streams spec which will be used to propagate this across all other client sdks.

Performance

Both 1 and 2 together at least doubles ⚠️ data stream throughput across the spectrum of network conenctions and payload sizes.

Before:
image

After:
image

TODO

  • Remove benchmark and spec before merging
  • Maybe make the changeset a minor release, not a patch? This is a fairly substantial change to a core sdk feature.
  • Cleanup cdc741a, I think I might need to rebase this

@changeset-bot

changeset-bot Bot commented Jun 23, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: c3fd1ab

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
livekit-client Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

github-advanced-security[bot]

This comment was marked as resolved.

Comment thread examples/data-stream-benchmark/api.ts Outdated

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NOTE: The diff is quite large, and a big reason why it is is because I have both this example app AND the spec checked in. I'll remove these before an eventual merge which will make the diff a lot more reasonable.

Feel free to ignore this examples/data-stream-benchmark directory when reviewing.

Image

Comment on lines +12 to +20
/** The data-streams-v2 wire signals carried directly on the header: the compression flag and the
* inline single-packet payload. Both used to live in reserved header attributes; they are now
* first-class protobuf fields on `DataStream.Header`. */
export interface StreamHeaderV2Fields {
/** Compression applied to the inline/chunked payload. Defaults to `NONE` when omitted. */
compression?: DataStream_CompressionType;
/** The full payload smuggled into the header for single-packet (inline) sends. */
inlineContent?: Uint8Array;
}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note to self: get rid of this and inline these two fields directly into the relevant function calls. Or name this something more generic if I decide to keep it.

Comment thread src/room/data-stream/outgoing/OutgoingDataStreamManager.ts
Comment on lines +161 to +162
// set text part of progress to 1
handleProgress(1, 0);

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note to self: add some tests for the onProgress stuff. I'm not sure I've fully exercised it to make sure I didn't break anything here. Though worth noting I did find some bugs where in some paths onProgress wasn't being called before so I'm actually not convinced it was working properly before either.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed this (sort of) in 4a6e2bb. It definitely works better than how it did before but I think there's still some work that could be done to improve it. Right now it measures bytes before the compression stage, which means that if the compressor were to take a long time it could potentially skew the progress.

Comment thread src/room/data-stream/outgoing/OutgoingDataStreamManager.ts
Comment on lines +333 to 335
// FIXME: make this a global event to ensure "max listener" warning won't get logged for lots of
// in flight data streams.
engine.once(EngineEvent.Closing, onEngineClose);

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note to self: fix this pre-existing bug as part of this larger change, I think right now there will me a "max listener" warning if you try to send too many data streams concurrently.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

alternatively if the pattern is expected we can also bump the maxListener count.

@1egoman 1egoman Jun 29, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not a fan of just bumping the maxListener count, since you're just increasing the high water mark threshold. So IMO it either should be disabled (I forget if that's possible in the node EventEmitter implementation) or will address using a similar pattern as I did in waitForBufferStatusLow here.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, the latter option sounds nice!

Comment thread src/room/data-stream/outgoing/OutgoingDataStreamManager.ts
Comment thread src/room/data-stream/compression.ts Outdated
Comment thread DATA_STREAMS_SPEC.md Outdated
@1egoman
1egoman requested a review from ladvoc June 23, 2026 21:19
Comment thread DATA_STREAMS_SPEC.md Outdated
Comment thread DATA_STREAMS_SPEC.md Outdated
Comment thread DATA_STREAMS_SPEC.md Outdated
Comment thread DATA_STREAMS_SPEC.md Outdated
Comment thread DATA_STREAMS_SPEC.md Outdated
Comment thread DATA_STREAMS_SPEC.md Outdated
@github-actions

github-actions Bot commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

size-limit report 📦

Path Size
dist/livekit-client.esm.mjs 104.63 KB (+2.23% 🔺)
dist/livekit-client.umd.js 113.68 KB (+2.12% 🔺)

@lukasIO lukasIO left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is looking great already.

Really like that you consolidated a bunch of spread out things into helpers. Makes it a lot nicer to reason about.

Comment thread src/room/data-stream/incoming/IncomingDataStreamManager.ts Outdated
Comment thread src/room/data-stream/incoming/IncomingDataStreamManager.ts Outdated
Comment thread src/room/data-stream/incoming/IncomingDataStreamManager.ts Outdated
Comment thread src/room/data-stream/incoming/IncomingDataStreamManager.ts Outdated
Comment thread src/room/data-stream/incoming/IncomingDataStreamManager.ts Outdated
Comment thread src/room/data-stream/outgoing/OutgoingDataStreamManager.ts
Comment thread src/room/data-stream/outgoing/OutgoingDataStreamManager.ts Outdated
Comment thread src/room/data-stream/outgoing/OutgoingDataStreamManager.ts Outdated
Comment on lines +333 to 335
// FIXME: make this a global event to ensure "max listener" warning won't get logged for lots of
// in flight data streams.
engine.once(EngineEvent.Closing, onEngineClose);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

alternatively if the pattern is expected we can also bump the maxListener count.

Comment thread src/room/data-stream/incoming/IncomingDataStreamManager.ts Outdated
Comment thread src/room/data-stream/incoming/IncomingDataStreamManager.ts
Comment thread src/room/data-stream/incoming/IncomingDataStreamManager.ts Outdated
Comment thread src/room/data-stream/incoming/IncomingDataStreamManager.ts Outdated
Comment thread src/room/data-stream/incoming/IncomingDataStreamManager.ts Outdated
Comment thread src/room/data-stream/incoming/IncomingDataStreamManager.ts Outdated
Comment thread src/room/data-stream/incoming/IncomingDataStreamManager.ts Outdated
Comment thread src/room/data-stream/incoming/IncomingDataStreamManager.ts Outdated

@lukasIO lukasIO left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks for addressing all my comments!

@yeongkyuyoon

Copy link
Copy Markdown

Nice work!

devin-ai-integration[bot]

This comment was marked as resolved.

devin-ai-integration[bot]

This comment was marked as resolved.

1egoman added 20 commits July 20, 2026 15:30
…ial stream materialization"

This reverts commit 25af9bc.
…ntexts

It's still not perfect - the progress events are reported pre-compressor
right now so the compressor lag isn't taken into account directly (other
than the side effect of it on future data "pulls" through the stream).
But I think it's an improvement over the previous state of just 0 -> 1.
This is set fairly high and will prevent any malicious decompression
bomb style payloads

@lukasIO lukasIO left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

great work!

just some questions around the NonSharedUint8Array usage, there are some internal Uint8Arrays declared directly in some places

Comment thread src/room/data-stream/incoming/IncomingDataStreamManager.ts
Comment thread src/room/utils.ts Outdated
Comment thread src/room/utils.ts Outdated
Comment thread package.json Outdated
@1egoman
1egoman merged commit 2c45da1 into main Jul 23, 2026
6 checks passed
@1egoman
1egoman deleted the data-streams-v2 branch July 23, 2026 14:06
@github-actions github-actions Bot mentioned this pull request Jul 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants