SRTO_LATENCY Is a Deadline, Not a Delay: Sizing the SRT Retransmission Window for Trans-Pacific Paths
A trans-Pacific SRT contribution can look healthy on every superficial check and still bleed frames. The encoder reports a steady bitrate. The receiver locks and plays. A quick ping to the ingest endpoint shows a round-trip time that fits comfortably inside the configured latency. Then a burst of loss hits, the NAKs go out, the retransmissions come back — and the receiver drops them anyway because they arrive after their presentation deadline. The stream does not collapse; it degrades in a way that is easy to blame on the encoder, the CDN, or the venue uplink. The first thing to inspect is the latency setting, and the first thing to understand is that it is not a delay knob. It is a deadline.
What SRTO_LATENCY actually controls
SRT’s own documentation is explicit about the scope of the term. Latency in SRT is “only the delay introduced by sending over the network,” measured between the srt_sendmsg2 call at the sender and the srt_recvmsg2 call at the receiver (libsrt latency documentation). It is not glass-to-glass latency, and it is not a fixed sleep inserted into the pipeline.
The mechanism is Timestamp-Based Packet Delivery (TSBPD). Each packet carries a sender timestamp. The receiver computes an expected arrival time from that timestamp and the connection’s start reference, then schedules delivery at:
PTS[x] = ETS[x] + LATENCY + DRIFT
where PTS is the presentation time, ETS the expected arrival time, and DRIFT a correction for clock-rate divergence between the two hosts. The same document explains why drift tracking exists: sender and receiver clocks are not identical, and over a long session the mismatch can imply a negative network delay or an absurdly large one.
Read that formula as a scheduling rule. A packet that arrives early waits in the receive buffer until PTS. A packet that arrives late — because the path spiked, or because it had to be retransmitted — is handed up late or, if it misses the deadline, dropped as too late. The latency value is the width of the window in which a retransmission can still be useful. Everything else follows from that.
Three option names, one negotiated value
The socket-options reference lists SRTO_LATENCY with a default of 120 ms and a settable range starting at 0 (SRT API socket options). That default is inherited from UDT-era assumptions and is a poor fit for any path that crosses an ocean.
The naming is a common source of confusion. SRTO_LATENCY is the legacy, symmetric option. In modern libsrt, the negotiated latency is derived from SRTO_RCVLATENCY on one agent and SRTO_PEERLATENCY on the peer. The documentation is careful to say these options “do not define the true time interval between the srt_sendmsg2 and srt_recvmsg2 calls for the same packet.” They add receiver-side delay to compensate for late arrival or retransmission. The negotiated value may differ from what either side individually configured; always read back the negotiated value on both ends after connection rather than trusting the configured value on one side.
The retransmission arithmetic
SRT recovers loss through selective retransmission (ARQ), optionally combined with forward error correction; the protocol draft describes both mechanisms and their combination as a design choice spanning “the lowest possible latency to the highest possible reliability” (draft-sharabayko-srt-01). The ARQ path is the one that matters for sizing.
When the receiver detects a gap, it sends a NAK. The sender retransmits. The retransmitted packet must arrive before its PTS. The minimum cost of that exchange is one round trip: NAK out, retransmission back. In practice it is more, because the NAK is generated after the receiver has observed the gap, the sender may be pacing other traffic, and the retransmission shares the path with the primary stream. A window that equals one RTT leaves no margin for any of that.
Haivision frames the sizing question with an RTT multiplier: “SRT Latency = RTT Multiplier * RTT,” where the multiplier reflects “the maximum number of times SRT will try to resend a packet before giving up” (Haivision RTT multiplier guidance). Their table gives a minimum multiplier of 3 at ≤1% loss and 4 at ≤3% loss, with corresponding minimum latencies of 60 ms and 80 ms for paths at or under 20 ms RTT. The same page is candid about the table’s provenance: the numbers are “intended as conservative guidance,” based on “a model using an earlier version of SRT,” and newer versions “may incorporate more efficient retransmission algorithms.”
That caveat matters. The widely repeated “4× RTT” rule is vendor guidance derived from a constant-loss model, not a protocol requirement. It does not appear in the SRT draft. It is a defensible starting point and a bad finishing point.
Why TCP’s retransmission timer is the wrong analogy
Engineers who tune TCP for long-haul paths tend to reach for the same instincts here, and the instincts mislead. TCP maintains a smoothed RTT and an RTT variance, computes a retransmission timeout from them, and backs off exponentially on repeated loss; RFC 6298 also requires that a computed RTO below one second be rounded up to one second (RFC 6298). That is an adaptive timer with a conservative floor.
SRT does not work that way. The latency is negotiated at connection setup and held for the session. There is no exponential backoff on the delivery deadline, and there is no one-second floor. Importing TCP’s numbers into an SRT configuration produces windows that are either far too large — adding avoidable delay — or sized against a mean RTT that the path exceeds routinely. The relevant statistic for a fixed deadline is not the mean. It is the tail.
Measure the tail, not the median
A path with a 150 ms median RTT and a 120 ms configured latency is already misconfigured: the median exceeds the window, so ordinary packets are arriving after their deadline before any loss occurs. But the more common failure is subtler. A path with a 90 ms median and a 120 ms window looks fine on average and drops retransmissions every time the path spikes to 160 ms. The mean hides the events that matter.
The sizing procedure is a measurement procedure:
- Capture the RTT distribution, not a single sample. Run a sustained probe — ICMP if the path permits it, otherwise timestamped UDP or an SRT session’s own statistics — for at least a full day, ideally across the production’s actual operating hours. Record median, p95, and p99. The p99 is the number the window has to survive.
- Measure burst length, not just loss rate. A 2% average loss distributed as isolated packets is a different problem from 2% concentrated in 100 ms outages. Haivision’s guidance notes that burst loss requires higher bandwidth overhead when the RTT multiplier is low, “otherwise SRT cannot recover the lost data within one RTT period.” The window must cover the recovery of the longest burst you intend to survive, not the average loss event.
- Read the receiver’s too-late-drop counters. SRT exposes statistics that distinguish packets lost on the wire from packets that arrived but missed their deadline. The second category is the one your latency setting controls. If it is non-zero during normal operation, the window is too small for the path as it actually behaves.
- Re-measure when the path changes. A window sized for a terrestrial route is not valid after a failover to satellite or a bonded cellular uplink. The negotiated latency does not adapt; you have to.
A worked example, clearly hypothetical
Consider a contribution path with a 150 ms median RTT, a p99 of 220 ms, 2% average loss, and occasional 100 ms outages during peak hours. These numbers are illustrative, not measured; substitute your own.
At the 120 ms default, the window is narrower than the median RTT. Every retransmission is guaranteed to miss its deadline, and even primary packets arriving on the slow side of the distribution are at risk. The receiver will show too-late drops continuously, and the operator will see intermittent macroblocking that correlates with nothing obvious.
At 450–600 ms, the window covers the p99 RTT plus a retransmission round trip plus margin for a burst. The cost is explicit: roughly 0.3–0.5 seconds of additional end-to-end delay relative to the default. Whether that is acceptable is a production decision — a remote commentary feed and a live auction have different budgets — but it is a decision that should be made deliberately, with the number written down, rather than inherited from a default that was never intended for this path.
The trade is not free in the other direction either. A window sized at 2 seconds “to be safe” buys recovery margin you will never use and pays for it in delay on every packet, including the ones that arrived on time. The window should be the smallest value that covers the tail and the burst, not the largest value you can tolerate.
A sizing checklist
- Read back the negotiated latency on both ends after connection; do not trust the configured value on one side.
- Size from p99 RTT, not median or mean.
- Add one RTT for the NAK-and-retransmit exchange, plus margin for the longest burst you intend to recover.
- Treat the vendor RTT-multiplier table as a starting point and validate against your own path’s burst profile.
- Confirm with receiver-side too-late-drop counters, not with subjective video quality.
- Re-measure after any path change: failover, new carrier, new route, new time of day.
- Do not import TCP RTO floors or backoff behavior into SRT tuning; the mechanisms are different.
FAQ
Does setting SRTO_LATENCY higher increase the actual network delay?
No. It increases the receiver-side deadline — how long a packet may wait in the receive buffer before being handed up or dropped. The packets still cross the network at whatever speed the path provides. The added time is buffer time, which is why it shows up as end-to-end latency but does not change the RTT.
Is the 4× RTT rule part of the SRT specification?
No. It appears in Haivision’s vendor documentation as guidance derived from a constant-loss model on an earlier SRT version. The SRT IETF draft describes the protocol mechanisms but does not prescribe a latency-to-RTT ratio.
Why does my stream drop frames when the ping test looks fine?
Because ping measures a sample, not a distribution, and because ping does not measure burst loss. A path can have a healthy median RTT and still spike above the configured window often enough to drop retransmissions. Capture the p95 and p99 over a full day and compare those against the negotiated latency.
Can I change the latency mid-session?
The socket-options reference marks SRTO_LATENCY as restricted before connection; the negotiated value is established at handshake. Plan to reconnect with the new value rather than expecting a live adjustment.
What about FEC — does it change the sizing?
FEC can reduce the number of retransmissions required, which reduces pressure on the window, but it does not eliminate the need for a window that covers the path’s tail RTT. The two mechanisms are complementary; the draft describes them as usable separately or combined.