send_side_bwe_pacer: "leaky-bucket" is defined but not wired — how to enable rate-based pacing of SFU egress?
Context: we run livekit-server as an SFU between browser publishers and server-side (libwebrtc) subscribers across inter-cloud paths (AWS↔GCP). We consistently measure direction-asymmetric micro-loss: legs where a libwebrtc endpoint sends (its pacer smooths frames) are clean, while SFU-forwarded legs show recurring NACK-recovered loss. In an isolated A/B on the same path (identical packets, line-rate frame bursts vs the same frames spread over ~8ms), a transient loss event hit the bursty shape ~90x harder (0.44% vs 0.007% cumulative), with endpoint sockets, qdiscs, and ENA counters all clean — i.e. the forwarder's line-rate write bursts appear to be what shallow queues on the path punish.
Code: a rate-based pacer exists but doesn't appear to be reachable:
pkg/sfu/pacer/pacer.godefinesPacerBehaviorLeakybucket = "leaky-bucket"alongsidepass-through/no-queue.pkg/sfu/pacer/leaky_bucket.goimplements it (NewLeakyBucket(logger, bwe, interval, bitrate)).- But the selection switch in
pkg/rtc/transport.go(createPeerConnection/IsSendSideblock, ~L573) only handlesPacerBehaviorPassThroughandPacerBehaviorNoQueue;leaky-bucketfalls intodefault:→NewNoQueue. Socongestion_control.send_side_bwe_pacer: leaky-bucketsilently degrades to no-queue (and withuse_send_side_bwe: falsethe pacer is unconditionally pass-through).
Questions:
- Is there a supported way to get rate-based pacing of downstream forwarding in current releases (we run v1.11.0, checked master too)?
- Is
LeakyBucketconsidered production-ready, and is wiring it into thesend_side_bwe_pacerswitch planned / would a PR adding the missing case be welcome? - Any known caveats that led to it being left unwired (latency under congestion, interaction with the stream allocator, etc.)?
Happy to share the measurement setup/data if useful.
Source: livekit/livekit