Reordering & Discard in LTE 4G
In-order delivery, the reordering behaviour at handover, and the discard timer.
You want the bytes handed to your app in the exact order they were sent, with no gaps and no duplicates — even while you sprint between cells at 120 km/h, and even when your data is being split across two base stations at once. In steady state RLC AM already delivers in order, so PDCP mostly sits back. The hard cases are handover, where the pipe breaks and reforms on a new eNB, and dual connectivity, where two pipes feed one bearer out of order. Bridging both is PDCP's job, grounded in TS 36.323.
Introduction
PDCP (Packet Data Convergence Protocol) is the top of the Layer-2 stack on the radio side, sitting just below RRC and above RLC. For every radio bearer it makes one promise to the layers above: SDUs come out the top in the same order they went in at the transmitter, exactly once. To keep that promise it numbers PDUs, maintains a reordering window, deciphers, checks integrity, decompresses ROHC headers, and โ where the traffic demands it โ retransmits and reports what it holds.
The contract is exercised on every LTE bearer, but it only becomes visible at the moments that deliberately stress it. On a single stationary cell, RLC AM already delivers in order and PDCP is nearly idle. It earns its keep at handover, when RLC and MAC reset on the target eNB and the ordered stream would break at the seam, and in dual connectivity, when two RLC legs feed one bearer and no single RLC can see the whole stream. This page follows PDCP through both.
Because PDCP behaviour splits sharply by bearer type โ AM DRB, UM DRB, SRB โ most PDCP debugging reduces to one question: which mechanism should fire for this bearer, and did it? Keep that mapping straight and a "packets out of order after handover" or "voice bearer glitching" ticket resolves quickly.
On this page
Why PDCP reordering is needed
In plain words: imagine two couriers carrying pages of the same document from two different depots to your desk. Each depot sends its pages in order, but one route has more traffic, so page 2 turns up after page 3. You do not staple them the instant they land โ you hold the later pages for a moment, waiting for the straggler, and only bind the chapter once the run is contiguous. PDCP is that desk: it waits a bounded time for the missing page, then hands the ordered run upward.
Concretely, three things force PDCP to reorder rather than pass PDUs straight up. First, TCP hates reordering and gaps โ even in-order-but-late delivery of one segment triggers duplicate ACKs and needless congestion back-off in the flow above. Second, ciphering breaks if the receiver's COUNT drifts from the sender's, so PDCP must track a single, unambiguous per-SDU counter across sequence-number wrap-around. Third, the two events that stress the pipe โ handover and dual connectivity โ deliberately deliver data out of order or across a discontinuity that no single RLC entity can repair.
PDCP guarantees in-order, duplicate-free SDU delivery per bearer, keyed on the PDCP SN and the full COUNT (HFN + SN). Header compression, ciphering and integrity all key off that same COUNT.
TCP hates reordering and gaps; ciphering breaks if the receiver's COUNT drifts from the sender's. The contract must survive the two events that deliberately stress it: handover, which tears the connection down and rebuilds it, and dual connectivity, which delivers one bearer over two RLC legs.
Each PDCP PDU carries a PDCP SN. The receiver tracks a reordering window over the SN space, buffers out-of-order PDUs, drops duplicates by COUNT, and — at handover — re-establishes state and issues a PDCP Status Report so nothing is needlessly re-sent or lost.
PDCP's Delivery Contract
Sitting just below RRC and above RLC, PDCP promises the upper layers something specific: for a given radio bearer, SDUs come out the top in the same order they went in at the transmitter, once and only once. For a Data Radio Bearer (DRB) mapped to RLC AM, the RLC layer normally already does the heavy lifting — its ARQ retransmits lost segments and reassembles them in sequence, so PDCP mostly just deciphers, decompresses headers (ROHC), and passes SDUs up. That is why, on a single stationary cell, PDCP's reordering machinery is almost invisible: RLC hands it a clean, ordered stream and there is nothing to reorder.
The delivery contract is not free, and PDCP only pays for it where it is promised. Lossless, in-order handover applies to AM DRBs; a UM DRB gets a lighter treatment because it never promised losslessness in the first place, and an SRB is handled differently again. Keeping straight which mechanism fires for which bearer type is most of what it takes to reason about PDCP correctly.
SN, COUNT and the Reordering Window
Every PDCP PDU on a mapped bearer carries a PDCP SN — a sequence number of 5, 7, 12, 15 or 18 bits depending on configuration (pdcp-SN-Size). SRBs use the short 5-bit SN; DRBs use 7, 12, 15 or 18 bits, with the 18-bit size added later to feed the very high throughputs of carrier aggregation and dual connectivity without wrapping too often. The SN is small and wraps around, so on its own it cannot tell "packet 3" of this wrap from "packet 3" of the next. PDCP therefore maintains a Hyper Frame Number (HFN) that increments each time the SN rolls over, and the pair forms the COUNT:
The COUNT is the true monotonically increasing identity of an SDU. It is what ciphering and integrity protection actually consume, and it is what the receiver uses to place a PDU in order and to recognise a duplicate. Because the SN wraps, the receiver keeps a reordering window — a range of SN values, of size roughly half the SN space, that it currently considers "in play." A PDU whose SN falls inside the window relative to the last delivered COUNT is buffered or delivered; one that falls outside is treated as a duplicate or a very old straggler and discarded. A handful of state variables track where that window sits and what has already gone up to RRC or the application:
| State variable | Role |
|---|---|
Next_PDCP_RX_SN | The next SN the receiver expects; advances as in-order PDUs arrive. |
RX_HFN | The HFN for the receive side, incremented on each SN wrap to keep COUNT unambiguous. |
Last_Submitted_PDCP_RX_SN | SN of the last SDU already delivered upward — the low edge of what may still be reordered. |
Reordering_PDCP_RX_COUNT | Marks the COUNT that t-Reordering is waiting on before it flushes buffered SDUs (used for UM and split bearers). |
Why not just use the SN? The SN wraps every few thousand packets. The COUNT never wraps within a bearer's lifetime, so it — not the raw SN — is the unambiguous key for ordering, duplicate detection and security.
Handover: Where PDCP Earns Its Keep
In an intra-LTE handover the UE moves from a source eNB to a target eNB. RLC and MAC are reset on the new cell — their sequence numbers and buffers do not carry over — so the in-order guarantee would break at the seam if PDCP did nothing. Instead, PDCP performs a re-establishment on both sides and stitches the two halves of the stream together.
The mechanics for an AM DRB are these. The source eNB forwards to the target, over the X2 interface, any downlink PDCP SDUs it has not yet had acknowledged by the UE — carrying their PDCP SN so ordering is preserved — starting from the first SDU whose delivery RLC had not confirmed. On the uplink side, the UE retransmits from its PDCP buffer every uplink PDCP SDU that RLC had not confirmed as delivered before the handover, again starting from the first unconfirmed SDU. To avoid re-sending everything blindly, the receiver can issue a PDCP Status Report: a control PDU that tells the peer exactly which SDUs it already has, using a First Missing SDU (FMS) pointer plus a bitmap of subsequently received SNs. The sender then re-sends only the genuine gaps and skips the rest.
The net effect: a packet that was in flight when the cell changed is not lost (the source forwarded it) and not delivered twice (the receiver's COUNT-based duplicate check plus the status report suppress the extra copy). The application above never sees the seam. The price is buffering and a burst of X2 forwarding traffic during the switch, which is why the network only pays it for bearers that actually demand lossless service.
Re-establishment and the Status Report
PDCP re-establishment is triggered by RRC as part of the handover, via RRCConnectionReconfiguration carrying mobilityControlInfo. It resets the ROHC header-compression protocol, applies the new security keys derived for the target cell, and — crucially — defines exactly what gets retransmitted and how the SN/COUNT state is carried across. Behaviour splits by bearer type. For an AM DRB, re-establishment preserves the COUNT so ciphering stays consistent under the new keys, and it drives the retransmission of un-acknowledged SDUs described above. For a UM DRB the SN and COUNT are reset and buffered SDUs may be delivered or discarded without retransmission, because UM never guaranteed losslessness. For an SRB, PDCP simply discards all stored PDUs — signalling is short and RRC will retransmit at its own layer if needed.
The PDCP Status Report is optional and configured per bearer via statusReportRequired. When enabled, after re-establishment the receiver builds one control PDU: a First-Missing-SDU (FMS) field that says "I have everything below this SN," followed by a bitmap where each bit flags whether a later SN was received. The peer reads it and retransmits only the SDUs marked missing — saving air-interface capacity that blind retransmission would waste. On a congested cell edge, that saving is the difference between a clean handover and a self-inflicted burst of redundant traffic at the worst possible moment.
Only for AM DRBs. The status report and un-acked-SDU retransmission machinery apply to bearers on RLC AM, where lossless handover is promised. SRBs and UM DRBs do not carry this baggage.
The discardTimer — Bounding Latency
An SDU that sits in the PDCP transmit buffer waiting for a grant that never comes is worse than useless — for real-time media, a voice frame that arrives 500 ms late is just noise the decoder has to conceal. So PDCP arms a discardTimer when it receives each SDU from above. If the timer expires before that SDU (and its PDCP PDU) has been delivered and acknowledged, PDCP discards the SDU and signals the discard down to RLC so the corresponding RLC SDU is dropped too, provided its transmission has not already started. Configurable values run from tens of milliseconds up through ms1500 and an infinity setting for bearers that must never drop data.
The following table gathers every mechanism on this page against the question that matters in an interview or a design review: when does it fire, and why does it exist?
| Mechanism | When it acts | Why it exists |
|---|---|---|
PDCP SN + COUNT | On every received PDU | Order PDUs and detect duplicates unambiguously across SN wrap-around. |
| Reordering window | Continuously at the receiver | Buffer out-of-order PDUs; reject stragglers and duplicates outside the window. |
| PDCP re-establishment | At handover (RRC-triggered) | Reset ROHC, apply new keys, define what is retransmitted across the cell change. |
| SDU forwarding (X2) | At handover, downlink | Source hands un-acked SDUs to target so in-flight data is not lost. |
PDCP Status Report | After re-establishment (if configured) | Tell the peer what is already held so only true gaps are re-sent. |
discardTimer | Per SDU, from arrival | Drop stale SDUs to bound end-to-end latency — critical for VoLTE. |
t-Reordering | While a gap is open (UM / split bearer) | Wait a bounded time for a missing SN, then flush — so one lost PDU cannot stall delivery forever. |
VoLTE angle: a short discardTimer keeps the voice bearer's latency tight — better to drop a late frame than deliver it and stall the jitter buffer. A bulk file-transfer bearer uses a longer timer, since throughput matters more than a few hundred milliseconds of latency.
Dual Connectivity and Split-Bearer Reordering
Handover is not the only place order breaks. In dual connectivity (DC), introduced in Rel-12, a single split bearer's PDCP entity is fed by two lower-layer legs at once: one RLC/MAC path through the Master eNB (MeNB) and another through the Secondary eNB (SeNB). Each leg delivers its own PDUs in order, but the two legs have different backhaul and radio delays, so PDUs arrive at the common PDCP entity interleaved and out of order across legs. Neither RLC can fix this, because neither sees the whole stream. For the first time in LTE, PDCP itself must reorder, not just tidy up the seam after a handover.
To do this, PDCP gains an explicit reordering function governed by a timer, t-Reordering. When PDCP receives a PDU that leaves a gap below the expected SN, it starts t-Reordering and buffers everything above the gap. If the missing PDU arrives before the timer expires — typically because it was simply travelling the slower leg — PDCP delivers the now-contiguous run upward in order. If the timer expires first, PDCP concludes the PDU is genuinely lost, flushes the buffered SDUs up to the receiver in order, and moves the window forward. The same t-Reordering mechanism also serves UM DRBs, giving them a bounded wait for out-of-order lower-layer delivery. Tuning it is a trade-off: too short and PDCP gives up on a slow-leg PDU that was about to arrive, causing an avoidable gap; too long and one lost PDU stalls the whole bearer while the timer runs down.
t-Reordering for the missing SN, then delivers in order.The upshot is that DC pushed reordering from an occasional handover chore into a continuous per-PDU responsibility of PDCP — the same conceptual machinery (SN, COUNT, a window, duplicate rejection) that NR would later inherit and generalise.
SRB vs DRB: Different Rules for Different Traffic
PDCP treats signalling and user data quite differently, and the split explains why so many mechanisms above are qualified with "for AM DRBs only." An SRB carries RRC and NAS signalling: it always runs over RLC AM, uses the short 5-bit PDCP SN, is both ciphered and integrity-protected, never uses ROHC, and has no discardTimer — signalling is short, precious, and must not be silently dropped. A DRB carries user plane traffic: it uses a longer SN (7/12/15/18 bits), is ciphered but usually not integrity-protected, may run ROHC to compress IP/UDP/RTP headers, and always arms a discardTimer to bound latency.
| Aspect | SRB (signalling) | DRB (user data) |
|---|---|---|
| RLC mode | Always RLC AM | RLC AM or RLC UM |
PDCP SN size | 5 bits | 7 / 12 / 15 / 18 bits |
| Security | Ciphered + integrity-protected | Ciphered (integrity optional/rare in LTE) |
| Header compression | None | ROHC (optional) |
discardTimer | Not used | Configured per bearer |
| Status report / lossless HO | No — discards stored PDUs at re-establishment | Yes, for AM DRBs (statusReportRequired) |
| Split-bearer / DC | Not split | Split bearer uses t-Reordering |
Read the table alongside the earlier one and the pattern is clear: the expensive lossless-handover and reordering machinery is reserved for the bearers that both need it and can tolerate its buffering cost — AM DRBs, especially split ones — while SRBs get a lean, security-first treatment and UM DRBs get a bounded-wait compromise. Every mechanism is switched on exactly where the traffic justifies it, and nowhere else.
Reading PDCP in the logs
PDCP problems are usually one of three shapes: a gap that never fills (delivery stalls), duplicates reaching the app (duplicate check failing), or a decipher/integrity failure after a key change (COUNT desync at re-establishment). Each shows up as a distinct pattern in the trace, and each maps to a specific mechanism above. Walk the log by COUNT, not by raw SN, and the failing step is usually obvious.
Representative PDCP trace (split-bearer DRB, then handover) โ illustrative, values vary by vendor/build:
| Field | Meaning | Example | Check |
|---|---|---|---|
pdcp-SN-Size | SN length configured for the bearer. | len12bits | Must match the peer; a mismatch corrupts COUNT and every decipher fails. |
COUNT | HFN+SN, the true per-SDU identity. | 0x00002B | Order and duplicate-check on this, not raw SN; a jump means an HFN desync. |
t-Reordering | Bounded wait for a gap (UM / split bearer). | ms50 | Too short = gaps on slow-leg PDUs; too long = one loss stalls the bearer. |
Reordering_COUNT | The COUNT the reordering timer is waiting on. | 0x00002C | If it never advances, the missing PDU never arrived โ check the slow leg. |
DUPLICATE | A PDU whose COUNT was already delivered. | SN 43 | Expected after retransmission/handover; must be dropped, not delivered up. |
StatusReport FMS + bitmap | First-Missing-SDU pointer + received-SN bitmap. | FMS=44 | Peer should retransmit only bits flagged missing; blind resend = statusReportRequired not honoured. |
discardTimer | Per-SDU latency bound in the Tx buffer. | ms100 | On expiry the SDU is dropped and RLC signalled; too long delays voice frames. |
decipher FAIL | Ciphering/integrity check failed. | after key change | Points at a COUNT/key desync at re-establishment โ verify HFN carried across for AM DRB. |
Where the config is signalled: the per-bearer PDCP parameters โ pdcp-SN-Size, discardTimer, statusReportRequired, ROHC profiles โ are carried in the PDCP-Config IE inside the RRCConnectionReconfiguration that sets up or modifies the bearer. Re-establishment and key change ride on the same message when it carries mobilityControlInfo.
✅ Debugging steps
- Confirm
pdcp-SN-Sizematches on both ends; a mismatch silently corruptsCOUNTand fails every decipher. - For a stalled bearer, find the open gap and check whether
t-Reorderingis running against aCOUNTthat never arrives (slow/dead leg) or expired without flushing. - For duplicates reaching the app, verify the receiver is duplicate-checking on
COUNT, not rawSN, and thatLast_Submitted_PDCP_RX_SNis advancing. - After a handover, confirm re-establishment carried
COUNT/keys correctly (AM DRB) and that thePDCP Status Reportcaused only genuine gaps to be re-sent. - For dropped-data complaints on a real-time bearer, check the
discardTimervalue against the actual scheduling delay.
⚠ Common causes of failure
pdcp-SN-Sizeor key/COUNTmismatch after re-establishment, so decipher/integrity fails on the target cell.t-Reorderingtoo short on a split bearer, giving up on slow-leg PDUs and creating avoidable gaps; too long, stalling the bearer on a genuine loss.- Missing or ignored
PDCP Status Report(statusReportRequirednot set), causing a burst of redundant retransmissions at handover. discardTimerset too long for a real-time bearer, delivering stale voice frames that stall the jitter buffer; too short, dropping data needlessly.- X2 SDU forwarding not performed or lost, so in-flight downlink SDUs are dropped at the seam despite AM DRB configuration.
Summary
PDCP's job is a single promise โ in-order, once-only SDU delivery per bearer โ kept by numbering every PDU with a PDCP SN, tracking the unambiguous COUNT, and buffering behind a reordering window. On a stationary cell over RLC AM the promise costs almost nothing. It gets expensive exactly at handover (re-establishment, X2 forwarding, un-acked-SDU retransmission, and the PDCP Status Report) and in dual connectivity (an explicit t-Reordering reassembling two out-of-order legs).
The fastest way to root-cause a PDCP issue is to name the bearer type, name the symptom, and map to the one mechanism responsible: a stall is t-Reordering/a dead leg; duplicates are a COUNT duplicate-check problem; decipher failures after a key change are a COUNT/key desync at re-establishment; dropped real-time frames are the discardTimer. Because each mechanism is switched on only where the traffic justifies it โ AM DRBs get the full lossless machinery, UM DRBs get a bounded wait, SRBs get lean security-first handling โ knowing the bearer already tells you which mechanisms should be in play.
Interview Corner
Q. If RLC AM already delivers in order, why does PDCP need any reordering or status logic?
A. In steady state on one cell, RLC AM does deliver in order and PDCP mostly passes SDUs up. The exceptions are handover — where RLC and MAC are reset on the target, breaking the guarantee at the seam — and dual connectivity, where two RLC legs feed one bearer out of order. PDCP bridges the first with re-establishment, un-acked-SDU retransmission, X2 forwarding and a PDCP Status Report, and the second with an explicit reordering function and t-Reordering.
Q. Why detect duplicates on COUNT rather than on the PDCP SN?
A. The SN is short and wraps around, so the same SN value recurs every wrap. The COUNT (HFN + SN) never wraps within a bearer's lifetime, making it the unambiguous identity for ordering, duplicate detection and ciphering.
Q. What does the PDCP Status Report contain and when is it sent?
A. After PDCP re-establishment at handover, if statusReportRequired is set on an AM DRB, the receiver sends a control PDU with a First Missing SDU (FMS) pointer plus a bitmap of received SNs above it. The peer then retransmits only the SDUs flagged missing, avoiding redundant re-sends.
Q. What does the discardTimer do and why does VoLTE care?
A. It bounds how long an SDU may wait in the PDCP transmit buffer. On expiry the SDU is discarded and the drop is signalled to RLC. For VoLTE a late voice frame is useless, so discarding it keeps latency tight instead of delivering stale audio that stalls the jitter buffer.
Q. Why was t-Reordering added for dual connectivity, and what happens when it expires?
A. A split bearer receives PDUs from two RLC legs with different delays, so they arrive out of order across legs and no single RLC can reorder them. PDCP starts t-Reordering when a gap opens and buffers the higher SNs. If the missing PDU arrives first, the run is delivered in order; if the timer expires, PDCP treats the PDU as lost, flushes the buffered SDUs upward, and advances the window.
LTE ↔ NR: NR PDCP (TS 38.323) inherits this exact machinery and makes reordering universal: every NR DRB uses a reordering window and t-Reordering, not just split/UM bearers, because NR's split-bearer and duplication features are first-class. NR uses only 12- or 18-bit PDCP SN, adds per-PDU PDCP duplication (the same PDU sent over two legs for reliability, with the receiver dropping the copy by COUNT), and mandates the SDAP layer above it for QoS-flow-to-DRB mapping. The discardTimer, COUNT, and status-report concepts carry over unchanged.
Where reordering & discard connect
PDCP's delivery contract only makes sense alongside the layer's overall structure, the mobility event that stresses it most, and the dual-connectivity architecture that made per-PDU reordering PDCP's job.