> ## Documentation Index
> Fetch the complete documentation index at: https://flux-docs.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Bridge

> The internal batching and flush layer.

<Info>
  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`](/api/server)
  and [`Flux.Client`](/api/client).
</Info>

```luau theme={null}
local Bridge = require(ReplicatedStorage.Flux.Bridge)
```

<Warning>
  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](/guides/shared-modules).
</Warning>

`Bridge` owns two responsibilities: handing out the `Writer` a send should append to, and
flushing accumulated writers once per frame.

## Bridge.Initialize()

```luau theme={null}
function Bridge.Initialize(): ()
```

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

<Steps>
  <Step title="Resolve remotes">
    `Remotes.Create()` on the server, `Remotes.Get()` on the client.
  </Step>

  <Step title="Start the flush loop">
    Connects to `RunService.Heartbeat` with a `1/60` accumulator.
  </Step>

  <Step title="Install player cleanup, server only">
    On `Players.PlayerRemoving`, frees that player's reliable and unreliable writers and drops
    the map entries.
  </Step>
</Steps>

***

## Bridge.Writer()

```luau theme={null}
function Bridge.Writer(reliable: boolean, player: Player?): Buffers.Writer
```

Returns the writer a send should append to, creating one from the pool if that group has no
writer for the current frame.

<ParamField path="reliable" type="boolean" required>
  Selects the reliable or unreliable writer group.
</ParamField>

<ParamField path="player" type="Player">
  Server only. The recipient, or `nil` for a broadcast. Ignored on the client.
</ParamField>

<ResponseField name="returns" type="Buffers.Writer">
  A pooled writer, positioned wherever the frame's accumulated bytes end.
</ResponseField>

### Writer groups

<Tabs>
  <Tab title="Server">
    | `reliable` | `player`   | Group                   |
    | ---------- | ---------- | ----------------------- |
    | `true`     | a `Player` | `ReliableMap[player]`   |
    | `false`    | a `Player` | `UnreliableMap[player]` |
    | `true`     | `nil`      | `BroadcastReliable`     |
    | `false`    | `nil`      | `BroadcastUnreliable`   |
  </Tab>

  <Tab title="Client">
    The `player` argument is ignored, and writers are keyed under the constant `"SERVER"`.

    | `reliable` | Group                     |
    | ---------- | ------------------------- |
    | `true`     | `ReliableMap["SERVER"]`   |
    | `false`    | `UnreliableMap["SERVER"]` |
  </Tab>
</Tabs>

<Info>
  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.
</Info>

***

## Bridge.FlushAll()

```luau theme={null}
function 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`.

```luau theme={null}
RunService.Heartbeat:Connect(function(dt)
	accumulator += dt
	if accumulator >= FRAME_TIME then
		local flushed = false
		while accumulator >= FRAME_TIME do
			accumulator -= FRAME_TIME
			flushed = true
		end
		if flushed then Bridge.FlushAll() end
	end
end)
```

<Note>
  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.
</Note>

### 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`

<Warning>
  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](/concepts/batching#ordering-rules-summarised).
</Warning>

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

<ResponseField name="ReliableMap / UnreliableMap" type="{[Player | string]: Buffers.Writer}">
  Pending per-recipient writers, keyed by `Player` on the server and by the string `"SERVER"`
  on the client.
</ResponseField>

<ResponseField name="BroadcastReliable / BroadcastUnreliable" type="Buffers.Writer?">
  Pending broadcast writers. Server only, and `nil` when nothing is queued.
</ResponseField>

<ResponseField name="accumulator" type="number">
  Elapsed time since the last flush step.
</ResponseField>

<ResponseField name="initialized" type="boolean">
  Guards `Initialize` and short-circuits `FlushAll`.
</ResponseField>

## Constants

| Constant     | Value      | Meaning                          |
| ------------ | ---------- | -------------------------------- |
| `FRAME_TIME` | `1 / 60`   | Minimum interval between flushes |
| `SERVER_KEY` | `"SERVER"` | Client-side writer map key       |

## Why there is no public flush

<Warning>
  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.
</Warning>

## Next steps

<CardGroup cols={2}>
  <Card title="Buffers" icon="binary" href="/api/internals/buffers">
    The writers this module hands out.
  </Card>

  <Card title="Batching" icon="layer-group" href="/concepts/batching">
    The same mechanism, explained in prose.
  </Card>
</CardGroup>
