A single broadcaster can produce one audio and video stream while hundreds or thousands of viewers consume it. That asymmetry is useful, but it does not make the server side free: each viewer still needs consumers, transports, packet retransmission, and keyframe handling.
Once a single MediaSoup router approaches its practical capacity, the audience has to be distributed. MediaSoup provides the media-plane primitive for doing this, PipeTransport, while leaving the application responsible for topology and signaling.
The basic forwarding topology
What PipeTransport gives you
On one host, router.pipeToRouter() coordinates the two pipe transports and mirrors a producer into another router. Across physical hosts, the same RTP path is possible, but the application has to exchange transport addresses and identifiers itself.
// Source SFU
const sender = await sourceRouter.createPipeTransport(options);
await sender.connect({ ip: receiverIp, port: receiverPort });
const pipeConsumer = await sender.consume({ producerId });
// Destination SFU
const receiver = await destinationRouter.createPipeTransport(options);
await receiver.connect({ ip: senderIp, port: senderPort });
const pipedProducer = await receiver.produce({
id: pipeConsumer.producerId,
kind: pipeConsumer.kind,
rtpParameters: pipeConsumer.rtpParameters,
});The snippet is only the transport handshake. A production design also needs authenticated signaling between SFUs, idempotent setup, retries, cleanup, and a way to decide where each forwarded producer should live.
Forwarding a player, not just packets
Making a destination SFU behave as if it owns the original producer requires forwarding application state alongside media:
- Create and connect a pipe transport between the two SFUs.
- Consume the source streams and reproduce them on the destination.
- Forward producer start, pause, resume, and close events.
- Forward authorization and “may consume” decisions.
- Mirror enough player metadata that existing consumer code does not need a separate path for remote producers.
Preserving the normal consuming path is the architectural payoff. The destination router can treat a piped producer like a local one, keeping most of the viewer-facing code unchanged.
From a fan-out to a tree
A source router can pipe directly to several downstream routers, but a very large audience eventually puts pressure on that source too. The forwarding topology can grow into a tree: a hot stream is replicated to a few SFUs, and those SFUs replicate it further as demand spreads.
In principle, the audience then scales with the available fleet rather than the capacity of one router. In practice, the control plane becomes the hard part: placement, loop prevention, topology convergence, and cleanup after partial failures.
The hidden keyframe problem
Packet retransmissions are handled per viewer transport and do not travel back to the broadcaster. Keyframe requests are different. A viewer connecting, changing spatial layers, or losing too many packets can emit an RTCP PLI or FIR that reaches the original encoder.
MediaSoup rate-limits these requests, but a sustained audience can still make the broadcaster generate large keyframes repeatedly. That can multiply sender bitrate and create bursts for every viewer receiving the stream. Increasing keyFrameRequestDelay reduces pressure at the cost of longer black-video periods.
At broadcast scale, a backend re-encoder can absorb viewer-driven keyframe requests and reproduce stable streams into the router tree. The re-encoder runs inside the backend network, where bandwidth and placement can be controlled.
Operational questions the API cannot answer
- How do we trace which SFU hops a packet or frame traveled through?
- Should network-latency measurements influence viewer and pipe placement?
- What does cross-region transit cost, and when is another replica cheaper than another hop?
- How do we rebuild a branch after a process or host disappears?
Graceful draining becomes a topology operation
In a flat fleet, draining means moving clients away from one SFU. In a cascading fleet, an SFU may also be an internal node carrying producers to downstream viewers. Retirement therefore has to rebuild or reroute those pipes before the process exits.
The application-level cordoned state described in graceful SFU draining without ending the call is a starting point. A future version should treat pipe dependencies as active work: stop assigning new branches, establish replacements, confirm downstream producers, then allow the old SFU to terminate.
PipeTransport makes cross-router media forwarding possible. Turning it into a dependable multi-host system requires treating signaling, keyframes, observability, and lifecycle management as first-class parts of the architecture.