Skip to main content
This module is internal. It is documented so you can reason about how Flux behaves and performs, but it is not re-exported from the root Flux module and its surface may change without notice. For everyday use, reach for Flux.Server and Flux.Client.
Despite the name, Bridge is not a unified server and client accessor. It has nothing to do with ReferenceBridge-style APIs from other libraries; it is the buffer batching layer. Flux has no unified constructor, so see Shared Modules.
Bridge owns two responsibilities: handing out the Writer a send should append to, and flushing accumulated writers once per frame.

Bridge.Initialize()

Idempotent. Called automatically by Server.new and Client.new on first construction.
1

Resolve remotes

Remotes.Create() on the server, Remotes.Get() on the client.
2

Start the flush loop

Connects to RunService.Heartbeat with a 1/60 accumulator.
3

Install player cleanup, server only

On Players.PlayerRemoving, frees that player’s reliable and unreliable writers and drops the map entries.

Bridge.Writer()

Returns the writer a send should append to, creating one from the pool if that group has no writer for the current frame.
boolean
required
Selects the reliable or unreliable writer group.
Player
Server only. The recipient, or nil for a broadcast. Ignored on the client.
Buffers.Writer
A pooled writer, positioned wherever the frame’s accumulated bytes end.

Writer groups

Because every event on a side shares these groups, sends from unrelated events coalesce into one buffer and one remote call. This is the core of Flux’s throughput advantage over per-message remotes.

Bridge.FlushAll()

Finalises every pending writer, fires the corresponding remote, and returns the writer to the pool. Called from the Heartbeat handler, and a no-op before Initialize.
The accumulator drains in 1/60 steps but FlushAll runs at most once per Heartbeat. A 50 ms hitch drains three steps and still performs one flush, so a frame spike never turns into a burst of sends.

Flush order

On the server:
  1. BroadcastReliable to FireAllClients
  2. BroadcastUnreliable to FireAllClients
  3. Each ReliableMap entry to FireClient
  4. Each UnreliableMap entry to FireClient
Broadcasts flush before per-player buffers, so a FireAll issued after a Fire(player, ...) in the same frame reaches that player first. Ordering is only guaranteed within a single writer group. See Batching.
Each entry is cleared from its map before Finalize and the remote call, so a send that happens during a flush starts a fresh writer rather than mutating one mid-send.

Internal state

{[Player | string]: Buffers.Writer}
Pending per-recipient writers, keyed by Player on the server and by the string "SERVER" on the client.
Buffers.Writer?
Pending broadcast writers. Server only, and nil when nothing is queued.
number
Elapsed time since the last flush step.
boolean
Guards Initialize and short-circuits FlushAll.

Constants

Why there is no public flush

Calling Bridge.FlushAll() yourself to force an immediate send is unsupported. It does not reset the accumulator, so the next Heartbeat flushes again, usually into an empty set of writers. It fights the timing model and gains you at most one frame.If sub-frame latency genuinely matters for a specific message, a raw RemoteEvent alongside Flux is the honest answer.

Next steps

Buffers

The writers this module hands out.

Batching

The same mechanism, explained in prose.