RLC Timers & Windows in 5G NR
t-Reassembly, t-PollRetransmit, t-StatusProhibit and the TX/RX windows.
RLC cannot wait forever, and it cannot talk forever. A segment may never arrive, a poll or its status report may vanish, and status reports left unchecked would flood the uplink. A small set of timers — and the sliding windows that bound sequence numbers — keep RLC making forward progress without stalling, without flooding, and without confusing a wrapped-around new PDU for a stale old one. Everything on this page is defined in TS 38.322, and the whole trick is knowing exactly which event arms each timer and what happens the instant it expires.
Introduction
This page covers the three RLC timers — t-Reassembly, t-PollRetransmit, t-StatusProhibit — together with the sliding windows and the retransmission ceiling maxRetxThreshold that bound the ARQ machinery. All of it is defined in TS 38.322 and configured per RLC entity by RRC in RLC-Config.
These mechanisms exist to keep RLC live. Reassembly must not hang forever on a segment that will never arrive; a lost poll or lost status report must not deadlock the feedback loop; unbounded status reporting must not swamp the uplink; and a finite, wrapping sequence number must never let an old PDU masquerade as a new one. Each timer solves one of those problems with a precise arm/expiry rule.
Because each timer maps to one failure mode and one recovery action, RLC timer problems localise cleanly: spurious NACKs point at t-Reassembly, slow recovery of a lost poll points at t-PollRetransmit, suppressed feedback points at t-StatusProhibit, and a bearer that keeps declaring failure points at maxRetxThreshold.
On this page
Why RLC Needs Timers and Windows
In plain words: imagine assembling a numbered book from pages arriving by post. If page 5 is missing you wait — but not indefinitely, so you set an egg-timer (t-Reassembly); when it dings you stop waiting and formally request page 5. You also don't pester the sender with a status note every five minutes (t-StatusProhibit), and the sender won't re-ask you forever if a request goes unanswered (t-PollRetransmit). The timers are just the common-sense "how long do I wait / how often do I speak" rules written into the protocol.
RLC sits between PDCP above and MAC below, and it has two jobs that both depend on ordering: it reassembles SDUs that were segmented to fit MAC grants, and (in Acknowledged Mode) it retransmits whatever the peer reports missing. Both jobs stall the moment a piece of the sequence goes missing — so RLC needs a way to decide when a gap is temporary (wait a little longer) versus hopeless (give up and move on). That decision is a timer.
Three timers — t-Reassembly, t-PollRetransmit, t-StatusProhibit — plus the AM/UM sliding windows and the retransmission limit maxRetxThreshold. All are configured per RLC entity by RRC inside RLC-Config.
Reassembly can hang on a permanently lost segment; polls and their status reports can be lost; unlimited status reporting wastes uplink; and a finite SN field wraps, so without a window an old PDU could be mistaken for a new one.
Each timer is armed on one specific event and, on expiry, forces one defined recovery action — advance the receiver, re-poll, or lift the status prohibition. The windows bound which SNs may be in flight so every sequence number stays unambiguous across the wrap.
Orientation: t-Reassembly lives on the receiver in every mode that reassembles (UM and AM); t-PollRetransmit is on the AM transmitter; t-StatusProhibit is on the AM receiver. Transparent Mode (TM) has no SN, no window and none of these timers — it is a passthrough. See ARQ & Status for the polling and status machinery these timers pace.
t-Reassembly — Detecting a Lost Segment
When an SDU is delivered in segments and one segment is missing, the receiver cannot complete that SDU, and because RLC must deliver in order it cannot pass on anything queued behind it either. It must not block indefinitely on a piece that may never come. So the receiver arms t-Reassembly — a single timer per RLC receive entity that answers the question "have I waited long enough to declare this gap lost?"
The mechanics are precise. The receiver starts t-Reassembly the moment it detects a reassembly gap: it is holding bytes of an SDU (or a later PDU) but is missing an earlier byte or an earlier SN in sequence. Exactly one instance of the timer runs at a time. While it runs, arriving data may fill the gap; if the missing piece completes and the receiver can advance past it, t-Reassembly is stopped — and if a gap still remains further along, the timer is immediately restarted for that new gap. If the timer expires, the receiver concludes the missing data is not coming: it advances its state variables past the hole and behaves according to mode. In UM it simply discards the partial SDU and reassembles from the next fully received SDU onward. In AM it does not discard blindly — instead it flags the outstanding SNs so the next STATUS PDU reports them as NACKs, handing the completeness problem to ARQ.
The point of the timer: on expiry in AM, RLC does not give up on the data — it gives up on waiting passively and switches to actively asking. Expiry triggers a STATUS report (subject to t-StatusProhibit) so the transmitter retransmits the gap. In UM, with no ARQ, expiry really does discard the incomplete SDU because there is no way to recover it.
Set it too short and you get spurious NACKs: data still in flight (delayed by HARQ reordering or a slow grant) is declared lost, the receiver NACKs it, and the transmitter wastes the air retransmitting bytes that were about to arrive anyway. Set it too long and every real loss adds that full timer duration to latency before recovery even begins. The value must comfortably exceed the worst-case HARQ round trip and reordering delay of the underlying MAC, and no more.
How it interacts with the state variables
To see exactly when the timer starts and stops, you have to look at the AM receiver's state variables, all defined in TS 38.322. Three of them drive t-Reassembly:
RX_Next— the lower edge of the receive window; theSNof the next AMD PDU expected in order. Everything below it has been fully received and delivered.RX_Next_Highest— one above the highestSNreceived so far. The span betweenRX_NextandRX_Next_Highestis the region that may contain gaps.RX_Highest_Status— the highestSNup to which all bytes are contiguously received; equivalently, theSNthat the next STATUS PDU will report as itsACK_SNlower bound.RX_Next_Status_Trigger— theSNthat, when reached or passed, tells the receiver the timer-armed gap is the one that just expired.
The rule the receiver follows: after processing a received PDU or segment, if t-Reassembly is not running, start it whenever RX_Next_Highest > RX_Next + 1 (there is a byte-hole below the highest received SN), or when there is a partially received SDU exactly at RX_Next. When it is armed, the receiver sets RX_Next_Status_Trigger = RX_Next_Highest — it remembers where the frontier was. The timer is stopped when reception advances such that all SNs below RX_Next_Status_Trigger are now complete (the gap filled). If instead the timer expires, the receiver updates RX_Highest_Status to the first still-missing SN at or above RX_Next_Status_Trigger, then — if there are still PDUs beyond that point — sets RX_Next_Status_Trigger = RX_Next_Highest and restarts the timer for the next gap. This is how one timer walks a chain of gaps one expiry at a time.
In one line: RX_Next_Highest tells the timer where the newest data is, RX_Highest_Status tells the STATUS report how far the contiguous run reaches, and t-Reassembly is the clock that decides when the space between them is declared a loss.
Reading t-Reassembly in the logs
Representative RLC log — illustrative, values vary by vendor/build:
| Field | Meaning | Example | Check |
|---|---|---|---|
RX_Next | Lower window edge / next in-order SN expected. | 5 | A stuck RX_Next means a gap is not being filled or advanced. |
RX_Next_Highest | One above the highest received SN; the gap frontier. | 7 | RX_Next_Highest > RX_Next + 1 is exactly the arm condition. |
t-Reassembly | Started on gap detection, stopped on fill, or expires. | EXPIRED | Frequent expiries with data arriving late = timer too short (spurious NACKs). |
RX_Highest_Status | Advanced past the hole on expiry; the STATUS reference point. | 5 | Must move to the first still-missing SN at/above the trigger. |
NACK_SN | The SN flagged for the next status report on expiry (AM only). | 5 | In UM there is no NACK — the SDU is discarded instead. |
✅ Debugging steps
- Confirm the arm condition: the timer should start only when
RX_Next_Highest > RX_Next + 1or a partial SDU sits atRX_Next. - Check that the timer stops when the gap fills before expiry — a gap that fills but still NACKs points at a stop-condition bug.
- Compare the configured value against the worst-case HARQ + reordering delay of the numerology in use.
- On expiry, verify AM flags a NACK (not a discard) and UM discards the incomplete SDU.
⚠ Common causes of failure
- Value too short → spurious NACKs: in-flight data declared lost and needlessly retransmitted.
- Value too long → every real loss adds the full timer duration to recovery latency.
- Timer not restarted for a subsequent gap, so a later hole is never reported.
- In UM, expiry discarding an SDU whose missing segment was only momentarily delayed.
A t-Reassembly Timeline
Read this left to right. PDUs arrive in order until SN 5 goes missing; later PDUs keep coming, which is exactly what proves there is a gap. The receiver arms t-Reassembly the moment the out-of-order PDU exposes the hole. The missing PDU never arrives, the timer expires, and on expiry the receiver builds a STATUS PDU that NACKs SN 5 and ACKs the rest — prompting the transmitter to retransmit.
t-PollRetransmit and t-StatusProhibit — the AM Pair
These two timers exist only in Acknowledged Mode, and they pull in opposite directions to keep the poll/status feedback loop both robust and economical. One guarantees feedback eventually arrives; the other stops feedback arriving too often.
t-PollRetransmit is a transmitter-side timer. A poll is the transmitter setting the P (poll) bit in an AMD PDU to explicitly ask "tell me what you have." t-PollRetransmit starts when a PDU with P=1 is submitted, and is stopped when a STATUS PDU arrives that acknowledges the polled data (specifically, when the poll's highest SN, tracked in POLL_SN, is covered by the report's ACK_SN). If it expires — no status came back — the transmitter assumes the poll or the report was lost and re-polls: it retransmits the PDU with the highest SN among those not yet acknowledged (or the one just submitted) with P=1. Without this timer, a single lost poll could wedge the ARQ loop forever, because the receiver only sends a status when asked or when its own t-Reassembly fires.
t-StatusProhibit is a receiver-side timer. It starts the moment the receiver sends a STATUS PDU, and while it runs the receiver is prohibited from sending another. This rate-limits status reporting: back-to-back polls, or repeated gap detection, could otherwise make the receiver spray STATUS PDUs and burn uplink. When the timer expires, any status report that became pending in the meantime may finally be sent. It trades a little feedback latency for a lot less uplink overhead — a knob the network tunes against how chatty it wants the feedback channel to be.
The interplay: t-PollRetransmit pushes feedback up (re-poll until a report comes); t-StatusProhibit holds feedback down (no more than one report per interval). Tuned together they keep the loop live without flooding it. Note the subtlety: even when t-Reassembly fires and wants to send a STATUS, t-StatusProhibit can delay it — the two timers negotiate the actual send moment.
✅ Debugging steps
- Confirm
t-PollRetransmitstarts on everyP=1and stops when aSTATUS PDUwithACK_SN>POLL_SNarrives. - If
t-PollRetransmitkeeps expiring, check whether the returnSTATUS PDUis being suppressed by an over-larget-StatusProhibitat the peer. - Confirm
t-StatusProhibitstarts when a STATUS is sent and that pending reports are released on expiry. - Trace a
t-Reassembly-triggered NACK throught-StatusProhibitto see the actual send moment.
⚠ Common causes of failure
t-PollRetransmittoo short → redundant re-polls before a valid status can return.t-PollRetransmittoo long → slow recovery when a poll or its report is lost.t-StatusProhibittoo large → NACKs suppressed, recovery shifted onto the poll timer and stalled.- The two mis-tuned relative to each other, so neither timer reliably drives recovery.
Windows — Bounding the Sequence Numbers
Because the SN field is finite and wraps around, both AM and UM use a sliding window so a wrapped new PDU is never confused with a stale old one. The window is anchored by a lower-edge state variable and spans a fixed size that is exactly half the sequence-number space:
Half the space is the magic number: it guarantees that the newest PDU the transmitter can send and the oldest it might still be holding can never alias to the same position when the counter wraps. So a 12-bit AM SN gives a window of 2048; an 18-bit AM SN gives 131072. UM with a 6-bit SN gives a reordering window of 32, and a 12-bit UM SN gives 2048. The SN size therefore directly caps how much data can be in flight before the window fills.
On the AM transmitter, the window's lower edge is TX_Next_Ack (the oldest unacknowledged SN) and its upper reach is TX_Next (the next SN to assign). The window advances as ACK_SN in incoming STATUS PDUs climbs; if the window fills before acknowledgements arrive, the transmitter stalls — it cannot assign a new SN until TX_Next_Ack moves. On the AM receiver, RX_Next is the lower edge and only SNs inside [RX_Next, RX_Next + AM_Window_Size) are accepted for reassembly; anything outside is discarded as a duplicate or out-of-window. UM has no ARQ, so its window serves only reordering and duplicate detection during reassembly, paced entirely by t-Reassembly; UM uses RX_Next_Highest, RX_Next_Reassembly and RX_Timer_Trigger to track the reordering frontier.
| Window variable | Mode & side | Meaning / role |
|---|---|---|
AM_Window_Size / UM_Window_Size | AM & UM, both sides | 2(SN−1); half the SN space, so wrapped SNs stay unambiguous. |
TX_Next_Ack | AM, transmitter | Lower window edge — oldest unacknowledged SN; advances with ACK_SN. |
TX_Next | AM, transmitter | Next SN to assign; window full when it reaches TX_Next_Ack + AM_Window_Size → TX stalls. |
RX_Next | AM, receiver | Lower edge of the receive window; next in-order SN expected. |
RX_Next_Highest | AM & UM, receiver | One above the highest SN received; upper bound of the possibly-gapped region. |
RX_Highest_Status | AM, receiver | Highest SN up to which all bytes are contiguous; the STATUS report's reference point. |
RX_Next_Reassembly | UM, receiver | Earliest SN still awaiting reassembly in the reordering window. |
maxRetxThreshold, Typical Values and Tradeoffs
Retransmission cannot go on forever. Each AM PDU carries a counter RETX_COUNT, incremented every time that PDU is retransmitted after a NACK. When RETX_COUNT reaches maxRetxThreshold, RLC concludes the link is broken and indicates the maximum retransmission to RRC, which may declare Radio Link Failure (RLF) and trigger re-establishment. The threshold counts retransmissions of a single PDU — reaching it for any one PDU is enough; RLC does not wait for every PDU to fail.
The RRC-configured values live in RLC-Config and are drawn from enumerated sets in TS 38.331. Rough guidance:
| Parameter | Typical configured value | Tradeoff / tuning intuition |
|---|---|---|
t-Reassembly | ms10 – ms50 (low-latency) up to ms200 | Too short → spurious NACKs on in-flight data; too long → every loss adds this delay before recovery. Must exceed worst-case HARQ + reordering delay. |
t-PollRetransmit | ms10 – ms80 (scaled to RTT) | Too short → redundant re-polls before a valid status can return; too long → slow recovery of a lost poll. Set just above the poll→status round trip. |
t-StatusProhibit | ms10 – ms50 (0 = disabled) | Larger → fewer STATUS PDUs, less uplink overhead, but slower NACK delivery; smaller → snappier feedback, more overhead. |
maxRetxThreshold | t8, t16, t32 (typ. 16 or 32) | Higher → more resilience on a flaky link before declaring RLF; lower → faster failure detection but risk of premature re-establishment. |
sn-FieldLength (AM) | size12 or size18 | 18-bit gives a huge window (131072) for high throughput / long RTT; 12-bit saves header bytes when in-flight data is modest. |
Design coupling: these values are not independent. A short t-Reassembly paired with a large t-StatusProhibit can defeat itself — the timer fires wanting to NACK, but the prohibit timer holds the STATUS back, so the transmitter's t-PollRetransmit ends up doing the recovery instead. Networks tune the trio together against the numerology's slot length and the expected HARQ RTT.
LTE ↔ NR: LTE RLC (TS 36.322) used the same three timer ideas but different names and structure — t-Reordering (LTE) is the direct ancestor of NR's t-Reassembly, while t-PollRetransmit, t-StatusProhibit and maxRetxThreshold keep their names. The big structural change: NR moved reordering / in-order delivery up into PDCP, so NR RLC's timer only governs segment reassembly, not cross-bearer reordering. NR also widened the AM SN from LTE's fixed 10 bits to a configurable 12/18, so NR windows (up to 131072) dwarf LTE's 512.
Timer Reference: Trigger and On-Expiry Action
Every timer on the page, with the side it runs on, what arms it, and the single action its expiry forces.
| Timer | Mode & side | Trigger (armed on) | Action on expiry |
|---|---|---|---|
t-Reassembly | UM & AM, receiver | A reassembly gap is detected (RX_Next_Highest > RX_Next + 1 or a partial SDU at RX_Next). | Advance RX_Highest_Status past the gap; in AM flag the missing SNs so the next STATUS PDU NACKs them; in UM discard the incomplete SDU. Restart for the next gap if one remains. |
t-PollRetransmit | AM, transmitter | An AMD PDU with P=1 (poll) is submitted; POLL_SN records the highest polled SN. | No status returned → re-poll: retransmit the highest-SN unacknowledged PDU with P=1. |
t-StatusProhibit | AM, receiver | A STATUS PDU is sent. | Prohibition lifts → a pending status report may now be sent. |
Stopping conditions matter as much as expiry: t-Reassembly stops when the gap fills; t-PollRetransmit stops when a covering STATUS PDU arrives; t-StatusProhibit simply runs to completion. A timer that is correctly stopped never fires its recovery — that is the normal, no-loss path.
Summary
Three timers keep AM RLC live and economical. t-Reassembly (receiver, UM & AM) decides when a reassembly gap is a real loss — on expiry it NACKs in AM or discards in UM. t-PollRetransmit (AM transmitter) chases feedback that never came back by re-polling. t-StatusProhibit (AM receiver) caps how often status reports go out. Around them, the sliding window — exactly 2(SN−1) — keeps every wrapping SN unambiguous, and maxRetxThreshold stops a dead link retransmitting forever by escalating to RRC.
When debugging, remember each timer maps to one symptom: spurious NACKs → t-Reassembly too short; slow recovery of a lost poll → t-PollRetransmit; suppressed or late NACKs → t-StatusProhibit too large; a bearer that keeps re-establishing → maxRetxThreshold reached on a persistently bad link. And a correctly stopped timer never fires its recovery — that is the normal, no-loss path.
Q&A
Q. Exactly when does the receiver start and stop t-Reassembly?
A. It starts when a reassembly gap is detected — when RX_Next_Highest > RX_Next + 1 or a partial SDU sits at RX_Next — and only one instance runs at a time. It stops when reception advances so all SNs below RX_Next_Status_Trigger are complete (gap filled). If it expires, the receiver advances RX_Highest_Status and restarts for the next gap if one remains.
Q. What does t-Reassembly expiry do differently in AM versus UM?
A. In AM it does not discard — it flags the missing SNs so the next STATUS PDU NACKs them, and ARQ retransmits. In UM there is no ARQ, so expiry discards the incomplete SDU and reassembly resumes from the next fully received SDU.
Q. Why do t-PollRetransmit and t-StatusProhibit both exist?
A. They oppose each other to balance the AM feedback loop. t-PollRetransmit re-polls if no status returns, guaranteeing feedback eventually arrives; t-StatusProhibit caps how often the receiver may send status, protecting the uplink. Both are AM-only.
Q. Why is the window exactly 2(SN−1), and how does SN size bound it?
A. Being exactly half the SN space keeps every in-flight SN unambiguous across the wrap, so old and new PDUs are never confused. SN size sets the ceiling: 12-bit → 2048, 18-bit → 131072 for AM; larger SN allows more data in flight before the window stalls the transmitter.
Q. What goes wrong if t-Reassembly is set too short or too long?
A. Too short causes spurious NACKs — data still in flight is declared lost and needlessly retransmitted. Too long adds the full timer duration to latency before recovery of any real loss even begins. It should just exceed the worst-case HARQ and reordering delay.
Q. What happens when RETX_COUNT reaches maxRetxThreshold?
A. RLC indicates maximum retransmission to RRC, which may declare Radio Link Failure and trigger re-establishment. The counter is per PDU and counts retransmissions only; hitting it for any one PDU is enough.
Where this fits
These timers and windows pace the ARQ loop below and surface unrecoverable failures to the control layer above.