DRX — Discontinuous Reception in 5G NR
Connected-mode DRX timers and cycles that let the UE sleep while staying connected.
A UE in RRC_CONNECTED has no way of knowing when the gNB will schedule it. The only safe default is to decode every PDCCH monitoring occasion the network has configured, on every serving cell, forever. That default is ruinous. Keeping an FR1 receiver chain, its LNA, its ADCs and the PDCCH blind-decoding engine powered and running costs on the order of a hundred times what a deep-sleep state costs, and for a phone with a chat app open the overwhelming majority of those decodes find nothing addressed to it.
Contents
- 01Why DRX Exists, and What It Costs
- 02The Basic Cycle: onDuration, Sleep, and the Inactivity Extension
- 03Active Time: the Definition That Decides Whether the Receiver Is On
- 04The Timer Set in Full
- 05Cycle Arithmetic: Exactly When onDuration Starts
- 06Short Cycle, Long Cycle, and the Transitions Between Them
- 07The DRX MAC Control Elements
- 08DRX and HARQ: Sleeping Through a Retransmission
- 09DRX Groups, Carrier Aggregation and Dual Connectivity
- 10C-DRX and I-DRX: Two Mechanisms, One Name
- 11Power, Latency and Duty Cycle: Worked Numbers
- 12Rel-16 Power Saving Beyond DRX
- 13Rel-17 and Rel-18: eDRX, PEI and PDCCH Skipping
- 14Configuration Reference (ASN.1 and Ranges)
- 15Failure Modes and What Each One Means
- 16Illustrative Message Traces
- 17Release Deltas: Rel-15 to Rel-18
- 18Reading DRX in Logs: A Checklist
- 19Glossary
- 20References
1. Why DRX Exists, and What It Costs
A UE in RRC_CONNECTED has no way of knowing when the gNB will schedule it. The only safe default is to decode every PDCCH monitoring occasion the network has configured, on every serving cell, forever. That default is ruinous. Keeping an FR1 receiver chain, its LNA, its ADCs and the PDCCH blind-decoding engine powered and running costs on the order of a hundred times what a deep-sleep state costs, and for a phone with a chat app open the overwhelming majority of those decodes find nothing addressed to it.
Discontinuous Reception is the negotiated escape. The network tells the UE, in advance and in exact frame arithmetic, which monitoring occasions it is actually required to decode. Everything else the UE may skip, and skipping means it may power down the receiver entirely. Nothing else about the protocol changes: the search spaces, the DCI formats, the HARQ processes and the RNTIs are the same as without DRX. DRX only removes obligations.
The cost is latency, and it is paid asymmetrically. Uplink data is barely affected — the UE knows it has something to send, so it can send a Scheduling Request immediately and an SR pending on PUCCH is itself part of Active Time (§3). Downlink data is the problem. A packet that arrives at the gNB one millisecond after the UE went to sleep waits for the next cycle occasion, and with a 160 ms cycle that is up to 152 ms of pure, unrecoverable delay before the first PDCCH can even be sent (§11).
| Trigger for the DRX state to change | Where it is decided | Effect | Diagnostic consequence |
|---|---|---|---|
drx-Config present in mac-CellGroupConfig | gNB RRC, per cell group | DRX starts operating from the first cycle occasion after the reconfiguration takes effect | The reconfiguration and the first missed grant can be tens of milliseconds apart; correlate by SFN, not by log line order. |
| Cycle occasion reached | UE MAC arithmetic (§5) | drx-onDurationTimer starts after drx-SlotOffset | If the UE and gNB disagree on the offset, the gNB schedules into a sleeping receiver and sees only HARQ DTX. |
| PDCCH indicating a new transmission to the C-RNTI | UE MAC, on decode | drx-InactivityTimer starts or restarts | A retransmission grant does not restart it — a common source of "the UE slept during my burst" reports. |
drx-InactivityTimer expiry | UE MAC | Use the Short cycle if configured (and start drx-ShortCycleTimer), else the Long cycle | The transition is silent. Only the wake-up pattern reveals which cycle is in use. |
| DRX Command MAC CE | gNB scheduler | Stop drx-onDurationTimer and drx-InactivityTimer immediately | The only network-side lever on Active Time. Its absence in a log means the scheduler is not using it, not that it does not exist. |
| Long DRX Command MAC CE | gNB scheduler | Stop drx-ShortCycleTimer, go straight to the Long cycle | Used when the gNB knows the session is over rather than merely quiet. |
drx-ShortCycleTimer expiry | UE MAC | Switch to the Long cycle | Wake-up spacing changes without any signalling; do not read it as a reconfiguration. |
| DCP (DCI format 2_6) received, wake-up bit clear | gNB, Rel-16 | The next drx-onDurationTimer is not started at all | An onDuration that simply does not appear is normal with DCP configured and alarming without it. |
drx-HARQ-RTT-TimerDL/UL expiry with the TB not decoded | UE MAC | Start the matching drx-RetransmissionTimer, re-entering Active Time | Explains PDCCH monitoring that appears outside any onDuration (§8). |
Table 1. Everything that can change the DRX state, who decides it, and what it looks like from outside. Only two rows are network-signalled; the rest happen silently inside the UE.
DRX is not a mode the UE enters. It is a set of permissions not to listen, evaluated afresh at every PDCCH monitoring occasion. There is no "DRX sleeping" state in the RRC state machine and no message that reports entering or leaving one. Everything you can observe about DRX is inferred from what the UE did or did not decode — which is exactly why misconfiguration here is so hard to see.
2. The Basic Cycle: onDuration, Sleep, and the Inactivity Extension
The skeleton is two numbers. drx-LongCycle sets the period; drx-onDurationTimer sets how much of each period the UE must spend monitoring. Once per cycle, at a moment both sides compute identically from the SFN (§5), the UE starts drx-onDurationTimer and monitors PDCCH until it expires. If nothing arrives, it stops monitoring and the receiver can go down until the next occasion.
That alone would be useless for real traffic, because a burst that starts in the last symbol of an onDuration would be truncated. drx-InactivityTimer fixes it: every PDCCH that indicates a new downlink or uplink transmission for this UE restarts it from zero TS 38.321 cl. 5.7. While it runs, the UE keeps monitoring. So a continuous stream of grants keeps the UE awake indefinitely, and Active Time collapses back to the onDuration floor only after the traffic actually stops for drx-InactivityTimer milliseconds.
drx-InactivityTimer is restarted, not extended: the grant at 96 ms discards the remaining 7 ms of the first run and starts a fresh 20 ms.Three consequences follow directly, and all three show up in logs:
- The duty cycle you configure is a floor, not a prediction. With any traffic at all the UE is awake far more than
onDuration / cycle. Vendor power figures quoted against the floor are best-case only. - A single grant can cost more than the whole onDuration. With
drx-onDurationTimer ms4anddrx-InactivityTimer ms100, one stray grant buys 100 ms of monitoring for one transport block. This is whydrx-InactivityTimeris the single most consequential DRX parameter for battery life, and why the DRX Command MAC CE exists (§7). - The UE is never obliged to sleep. Every DRX rule is permissive. A UE that keeps its receiver on through the sleep window is fully compliant and indistinguishable from one that sleeps, from the network's side. Real power savings depend on the UE implementation actually taking the permission.
drx-InactivityTimer is restarted only by a PDCCH indicating a new transmission — a DCI whose New Data Indicator has toggled for that HARQ process. Retransmission grants do not restart it, and neither do PDCCHs addressed to other RNTIs (SI-RNTI, P-RNTI, RA-RNTI) or DCI formats that carry no scheduling assignment. See the companion 05 HARQ document for the NDI semantics this depends on.
3. Active Time: the Definition That Decides Whether the Receiver Is On
Active Time is the term the spec actually uses, and it is the only thing that matters. onDuration and the inactivity extension are two of its contributors, not the whole of it. Active Time is defined as a union of conditions TS 38.321 cl. 5.7: if any one of them holds, the UE monitors PDCCH in that occasion. There is no priority and no ordering — a UE can be in Active Time with drx-onDurationTimer long expired.
| Contributor | Starts when | Ends when | Why it must be in Active Time |
|---|---|---|---|
drx-onDurationTimer running | Cycle occasion reached, after drx-SlotOffset | Timer expires, or a DRX Command MAC CE stops it | The scheduled, agreed opportunity for the gNB to reach a quiet UE. |
drx-InactivityTimer running | PDCCH indicating a new DL or UL transmission to the C-RNTI | Timer expires, or a DRX Command MAC CE stops it | Traffic tends to arrive in bursts; the next packet is far more likely than a random one. |
drx-RetransmissionTimerDL running (per HARQ process) | drx-HARQ-RTT-TimerDL expired and the TB was not decoded | Timer expires, or a PDCCH for that HARQ process arrives | A retransmission is owed to the UE and it must be listening for the grant (§8). |
drx-RetransmissionTimerUL running (per HARQ process) | drx-HARQ-RTT-TimerUL expired | Timer expires, or a PDCCH for that HARQ process arrives | An uplink retransmission grant can only be delivered on PDCCH. |
ra-ContentionResolutionTimer running | MSG3 transmitted in a contention-based Random Access | MSG4 received and the identity matches, or the timer expires | The UE has an unfinished RACH; sleeping through MSG4 would fail the procedure. See companion 03 Random Access. |
| A Scheduling Request sent on PUCCH and still pending | SR transmitted, no grant yet received | The gNB issues a grant that can accommodate the pending data, or the SR is cancelled | The UE asked for a grant; it must be awake for the answer. See companion 10 BSR, PHR, SR. |
| Contention-free RA: RAR received, no PDCCH to own C-RNTI yet | Successful RAR reception for a preamble the UE did not pick from the contention-based pool | A PDCCH indicating a new transmission to the C-RNTI arrives | Covers handover and beam-failure recovery, where the response is an ordinary PDCCH rather than a MAC CE. See companion 12 Beam Failure Recovery. |
Table 2. The Active Time union, TS 38.321 cl. 5.7. A UE monitoring PDCCH outside any onDuration is almost always one of the last four rows.
A Regular BSR does not appear in the list, and readers often expect it to. It enters indirectly: a Regular BSR with no usable grant triggers a Scheduling Request TS 38.321 cl. 5.4.5, and it is the pending SR that is an Active Time contributor. If no valid PUCCH SR resource is configured the SR instead initiates Random Access, and ra-ContentionResolutionTimer takes over the job. Either way the UE stays awake to hear the answer — but the mechanism you should look for in a log is the SR or the preamble, not the BSR.
3.1 What the UE still does outside Active Time
Not monitoring PDCCH is not the same as transmitting nothing. Outside Active Time the UE still transmits HARQ feedback for transport blocks it already received, and still sends aperiodic CSI on PUSCH and aperiodic SRS when they have been triggered — those obligations were incurred while it was awake and are not cancelled. What it may skip is periodic CSI reporting on PUCCH and periodic or semi-persistent SRS. This asymmetry is why a UE deep in a long cycle can still be seen transmitting: the transmissions are the tail of earlier scheduling, not evidence that it is listening.
A UE that transmits HARQ feedback but does not respond to the retransmission grant that follows is not broken. Check whether the grant landed outside Active Time. The feedback was mandatory; decoding the grant was not.
4. The Timer Set in Full
Ten fields inside DRX-Config describe the whole mechanism. Two of them are in symbols, two in slots, and the rest in milliseconds or fractions of a millisecond — mixing the units up is the most common arithmetic error when reading a configuration.
| ASN.1 field | Unit | Values | Typical | What it does and what going wrong looks like |
|---|---|---|---|---|
drx-onDurationTimer | 1/32 ms or ms | subMilliSeconds 1..31, or milliSeconds ms1..ms1600 | ms8 (FR1 smartphone) | The mandatory monitoring window each cycle. Too short and the gNB cannot reliably reach a quiet UE within one cycle; too long and it dominates the duty cycle. |
drx-InactivityTimer | ms | ms0, ms1..ms6, ms8, ms10, ms20..ms100, ms200, ms300, ms500, ms750, ms1280, ms1920, ms2560 | ms10 to ms100 | How long the UE keeps monitoring after a new-transmission PDCCH. The dominant battery parameter. ms0 disables the extension entirely, which is right for strictly periodic traffic and wrong for anything bursty. |
drx-LongCycleStartOffset | ms | CHOICE of ms10, ms20, ms32, ms40, ms60, ms64, ms70, ms80, ms128, ms160, ms256, ms320, ms512, ms640, ms1024, ms1280, ms2048, ms2560, ms5120, ms10240, each carrying its own offset INTEGER | ms80 or ms160, offset spread per UE | One field carries both the cycle and drx-StartOffset. Assigning the same offset to every UE in a cell synchronises their wake-ups and produces periodic PDCCH congestion. |
drx-SlotOffset | 1/32 ms | 0..31 | 0 | Delay from the subframe boundary to the actual onDuration start. Lets the network place onDuration on a slot boundary at higher SCS instead of a subframe boundary. |
drx-ShortCycle | ms | ms2..ms8, ms10, ms14, ms16, ms20, ms30, ms32, ms35, ms40, ms64, ms80, ms128, ms160, ms256, ms320, ms512, ms640 | ms20 or ms40 | The faster cycle used just after a burst. Must divide drx-LongCycle; a configuration that violates this is rejected, and some implementations reject the whole RRCReconfiguration. |
drx-ShortCycleTimer | multiples of drx-ShortCycle | 1..16 | 2 to 8 | How long to stay on the short cycle before falling back to the long one. Total short-cycle residency is the product of the two fields. |
drx-HARQ-RTT-TimerDL | symbols of the active DL BWP | 0..56 | up to 56 (SCS-dependent) | Minimum guaranteed gap before a DL retransmission can be granted. Not an Active Time contributor — it is a licence to sleep (§8). |
drx-HARQ-RTT-TimerUL | symbols of the active UL BWP | 0..56 | up to 56 | Same for uplink; runs from the end of the first repetition of the PUSCH transmission. |
drx-RetransmissionTimerDL | slots of the active DL BWP | sl0, sl1, sl2, sl4, sl6, sl8, sl16, sl24, sl33, sl40, sl64, sl80, sl96, sl112, sl128, sl160, sl320 | sl16 to sl40 | Maximum time the UE keeps listening for the DL retransmission grant after the RTT timer expires. Too short and a loaded scheduler misses the window, producing a stalled HARQ process. |
drx-RetransmissionTimerUL | slots of the active UL BWP | same list | sl16 to sl40 | Same for the uplink retransmission grant. |
Table 3. DRX-Config, TS 38.331. Enumerations abridged where the pattern is obvious; ... members and spares omitted. Slot- and symbol-based timers scale with the numerology of the active BWP, so the same configuration is a different wall-clock duration on a 30 kHz and a 120 kHz BWP.
The two HARQ RTT timers are in symbols; the two retransmission timers are in slots; everything else is in milliseconds or 1/32 ms. At 30 kHz SCS, drx-HARQ-RTT-TimerDL = 56 is 4 slots = 2.0 ms, while drx-RetransmissionTimerDL = sl16 is 16 slots = 8.0 ms. At 120 kHz the same two values are 0.5 ms and 2.0 ms. A DRX profile lifted from an FR1 cell and pasted into an FR2 cell silently becomes four times tighter.
5. Cycle Arithmetic: Exactly When onDuration Starts
Both sides must agree on the wake-up instant to the symbol, and they do it without signalling by evaluating the same congruence on the frame counter. The subframe index is used rather than the slot index precisely so the test is numerology-independent TS 38.321 cl. 5.7:
Long DRX cycle in use:
[(SFN x 10) + subframe] modulo (drx-LongCycle) == drx-StartOffset
Short DRX cycle in use:
[(SFN x 10) + subframe] modulo (drx-ShortCycle)
== drx-StartOffset modulo (drx-ShortCycle)
If the condition holds:
start drx-onDurationTimer drx-SlotOffset x (1/32) ms after the
beginning of that subframe
SFN 0 .. 1023, wraps every 10240 ms
subframe 0 .. 9, always 1 ms regardless of SCS
drx-LongCycle the CHOICE branch of drx-LongCycleStartOffset, in ms
drx-StartOffset the INTEGER inside that branch, 0 .. (cycle - 1)
drx-SlotOffset 0 .. 31, in units of 1/32 ms5.1 Worked example: a long cycle
drx-LongCycleStartOffset = ms80 : 27, so drx-LongCycle = 80 ms and drx-StartOffset = 27. drx-SlotOffset = 16. SCS is 30 kHz, so a subframe holds 2 slots of 0.5 ms.
Condition: [(SFN x 10) + subframe] mod 80 == 27
Solutions are 27, 107, 187, 267, ... i.e. every 80 ms:
27 -> SFN 2, subframe 7
107 -> SFN 10, subframe 7
187 -> SFN 18, subframe 7
... SFN = 2 mod 8, subframe 7, always
drx-SlotOffset = 16 -> 16/32 = 0.5 ms into subframe 7, which at 30 kHz is exactly the boundary of the second slot of that subframe: slot 15 of the frame (subframe 7 holds slots 14 and 15).
So the UE starts drx-onDurationTimer at SFN 2 / slot 15, then SFN 10 / slot 15, then SFN 18 / slot 15. With drx-onDurationTimer = ms8 it monitors slots 15 to 30 inclusive, i.e. 16 slots.
5.2 Worked example: the same offset on the short cycle
Same UE, now on the Short cycle: drx-ShortCycle = ms20, drx-StartOffset still 27.
Right-hand side: 27 mod 20 = 7
Condition: [(SFN x 10) + subframe] mod 20 == 7
Solutions: 7, 27, 47, 67, 87, 107, ... i.e. every 20 ms:
7 -> SFN 0, subframe 7
27 -> SFN 2, subframe 7 <- also a long-cycle occasion
47 -> SFN 4, subframe 7
67 -> SFN 6, subframe 7
87 -> SFN 8, subframe 7
107 -> SFN 10, subframe 7 <- also a long-cycle occasion
Every long-cycle occasion is also a short-cycle occasion. That is not a coincidence: it follows from both tests using the same drx-StartOffset and from drx-ShortCycle dividing drx-LongCycle. Switching between cycles therefore never moves a wake-up — it only adds or removes the intermediate ones.
The subframe index in the condition is deliberate. Slots per subframe vary with SCS (1, 2, 4, 8, 16), so a slot-based congruence would give different wake-up instants on different BWPs of the same cell. Working in subframes makes the cycle a wall-clock quantity, and drx-SlotOffset — in 1/32 ms — then provides sub-subframe placement that is still numerology-independent as a duration, even though which slot it lands on depends on the SCS. See the companion 02 Radio Frame Structure document for the SFN and slot numbering this rests on.
The SFN wraps at 1024, i.e. the counter [(SFN x 10) + subframe] jumps from 10239 back to 0. If drx-LongCycle divides 10240 the pattern is continuous across the wrap. Two enumerated values do not divide it: ms60 (10240 / 60 = 170.67) and ms70 (146.3). The same applies to the short cycle values ms3, ms6, ms7, ms14, ms30 and ms35. With those, one cycle every 10.24 s is short or long by up to a cycle, and any test that measures wake-up jitter over a long window will see a periodic outlier that is correct behaviour. Symptom: exactly one anomalous inter-wake-up interval per 10.24 s, always at the same SFN.
6. Short Cycle, Long Cycle, and the Transitions Between Them
One cycle length cannot serve both ends of a session. Immediately after a burst ends, more data is likely and a short cycle keeps latency low for a modest power cost. Ten seconds later, more data is unlikely and a long cycle is worth the latency. shortDRX gives the UE both, with an automatic one-way decay from short to long.
drx-ShortCycleTimer is expressed in multiples of drx-ShortCycle, so its wall-clock length changes if either field is retuned.| Event | Condition | Action | Cycle in use afterwards |
|---|---|---|---|
drx-InactivityTimer expires | shortDRX configured | Start or restart drx-ShortCycleTimer in the first symbol after expiry | Short |
drx-InactivityTimer expires | shortDRX not configured | Nothing beyond stopping the timer | Long |
| DRX Command MAC CE received | shortDRX configured | Stop drx-onDurationTimer and drx-InactivityTimer; start or restart drx-ShortCycleTimer in the first symbol after the end of the CE reception | Short |
| DRX Command MAC CE received | shortDRX not configured | Stop drx-onDurationTimer and drx-InactivityTimer | Long |
drx-ShortCycleTimer expires | -- | Nothing to stop | Long |
| Long DRX Command MAC CE received | -- | Stop drx-ShortCycleTimer | Long |
Table 4. The complete cycle-selection state table, TS 38.321 cl. 5.7. There is no transition from long back to short except by way of Active Time — the UE must be given traffic first.
There is deliberately no direct long-to-short transition. To move a UE back onto the short cycle the network must schedule it, which starts drx-InactivityTimer, whose expiry then selects the short cycle. A scheduler that wants a UE responsive again therefore has to spend a grant on it, even an empty one — and that grant is visible in a log as an apparently pointless single-TB transmission just before a period of tighter wake-ups.
Sizing is a two-parameter decision, and the useful quantity is the product. With drx-ShortCycle = ms40 and drx-ShortCycleTimer = 8, the UE spends 320 ms on the short cycle after every burst before falling back — which is eight extra wake-ups if no further data arrives. Set against a drx-LongCycle of ms160 that is two long-cycle periods spent at four times the wake-up rate, so the short cycle must earn its place from the actual inter-burst distribution of the traffic, not from intuition.
7. The DRX MAC Control Elements
Two MAC Control Elements exist purely to shorten Active Time, and both are zero-length: they carry no payload at all, and the LCID in the subheader is the entire message TS 38.321 cl. 6.1.3.3, 6.1.3.4. They travel on DL-SCH like any other CE, so they are subject to HARQ, they can be lost, and there is no acknowledgement at MAC or RRC level.
| MAC CE | LCID | Direction | Length | Effect on the UE |
|---|---|---|---|---|
| DRX Command | 60 | DL-SCH only | 0 octets | Stop drx-onDurationTimer and drx-InactivityTimer. If shortDRX is configured, start or restart drx-ShortCycleTimer and use the Short cycle; otherwise use the Long cycle. |
| Long DRX Command | 59 | DL-SCH only | 0 octets | Stop drx-ShortCycleTimer and use the Long cycle. Does not itself stop drx-onDurationTimer or drx-InactivityTimer. |
Table 5. The two DRX CEs, TS 38.321 Table 6.2.1-1. Encoded as a single octet each: two reserved bits then the six-bit LCID, giving 0x3C and 0x3B on the wire.
drx-InactivityTimer, then a second CE to skip the short-cycle stage entirely. Both decisions are made from scheduler state the UE cannot see.A DRX Command MAC CE lost to a HARQ failure leaves the UE monitoring for the rest of drx-InactivityTimer while the gNB believes it is asleep. Nothing breaks — the gNB is over-conservative about when it can schedule, and the UE wastes power — so the fault is invisible except as a UE whose measured battery drain does not match its configuration. If you are chasing a power regression, check the HARQ success rate on the downlink carrying these CEs before you re-tune any timer.
8. DRX and HARQ: Sleeping Through a Retransmission
HARQ creates an obligation that outlives Active Time. If the UE NACKs a transport block, a retransmission is owed to it, and the UE must be listening when the grant arrives. Naively that means staying awake from the NACK until the retransmission — potentially a long time on a loaded cell. The four HARQ-related DRX timers exist to cut that window down to only the part where a grant is actually possible.
The mechanism has two halves, and they do opposite things:
drx-HARQ-RTT-TimerDLis a licence to sleep. It starts in the first symbol after the end of the transmission carrying the HARQ feedback for that process, and it encodes the minimum turnaround the gNB physically needs to process the NACK and prepare a retransmission. During it, no grant for that process can arrive, so the UE has nothing to listen for. It is not an Active Time contributor.drx-RetransmissionTimerDLis an obligation to listen. It starts when the RTT timer expires and the transport block was not successfully decoded. It is an Active Time contributor, and it bounds how long the UE will wait for the retransmission grant before giving up on it.
Both are per-HARQ-process. A UE with eight processes can have eight RTT timers and eight retransmission timers in different states at once, which is why PDCCH monitoring outside onDuration often looks ragged rather than block-shaped in a log. The uplink pair works identically, with drx-HARQ-RTT-TimerUL starting after the end of the first repetition of the corresponding PUSCH transmission.
drx-InactivityTimer above zero this gap is usually swallowed by the inactivity extension and never observed.30 kHz SCS: slot = 0.5 ms, symbol = 0.5 / 14 ~ 35.7 us.
drx-HARQ-RTT-TimerDL = 56 symbols
= 56 x 35.7 us = 2.0 ms (= 4 slots, exactly)
drx-RetransmissionTimerDL = sl16
= 16 x 0.5 ms = 8.0 ms
Worst-case Active Time contributed by one failed TB:
0 ms during the RTT timer + 8.0 ms of retransmission window
= 8.0 ms, against 10.0 ms of elapsed time -> 20% of the post-NACK window is sleep.
Same configuration on a 120 kHz FR2 BWP:
slot = 0.125 ms, symbol ~ 8.93 us
RTT timer = 56 x 8.93 us = 0.5 ms
retransmission window = 16 x 0.125 = 2.0 ms
The sleep opportunity shrinks to 0.5 ms and the window the scheduler has to hit shrinks to 2.0 ms — on the frequency range where scheduling is most congested.
drx-RetransmissionTimerDL is stopped the moment a PDCCH for that HARQ process arrives, and that PDCCH — being a retransmission — does not restart drx-InactivityTimer. So a UE can receive a retransmission grant, decode the retransmitted TB, send an ACK, and be back asleep within a millisecond, with no inactivity extension at all. This is correct and it surprises people. See companion 05 HARQ.
The interaction runs the other way too. If drx-RetransmissionTimerDL is configured too short for the cell's actual scheduling delay, the UE stops listening before the gNB gets round to the retransmission. The gNB sends it anyway, gets no HARQ feedback, and the process stalls until RLC notices the missing PDU and asks for it again — turning a 1 ms HARQ recovery into a tens of milliseconds RLC recovery. In logs this appears as HARQ DTX on retransmissions only, never on first transmissions.
9. DRX Groups, Carrier Aggregation and Dual Connectivity
DRX is configured per cell group, inside mac-CellGroupConfig. That one sentence answers most carrier-aggregation questions: all serving cells of a cell group share one DRX configuration and one Active Time, so a UE with a PCell and three SCells wakes and sleeps on all four together. It cannot monitor the PCell while an SCell sleeps, because there is only one set of timers.
| Scope | What is shared | What is per-entity | Practical consequence |
|---|---|---|---|
| One cell group, Rel-15 | One drx-Config; one Active Time across all serving cells of the group | drx-HARQ-RTT-Timer and drx-RetransmissionTimer instances are per HARQ process, and HARQ entities are per serving cell | Adding an SCell does not add wake-ups, but every SCell's retransmissions can extend the shared Active Time. |
| Two DRX groups, Rel-16 | drx-LongCycleStartOffset, drx-ShortCycle, the HARQ timers and the cycle arithmetic | drx-onDurationTimer and drx-InactivityTimer can differ between the primary and secondary DRX group | An FR1 anchor can run a long onDuration while co-configured FR2 cells run a much shorter one, since FR2 reception is far more expensive. |
| MCG and SCG in NR-DC | Nothing | Each cell group has its own independent drx-Config, timers and Active Time | The two legs sleep independently. A UE can be in Active Time on the SCG and asleep on the MCG at the same instant. |
| EN-DC (LTE anchor) | Nothing | LTE DRX on the MCG, NR DRX on the SCG, separate specifications | Power measurements must be attributed per leg; an NR DRX change cannot explain an LTE-leg drain. |
| Cells in a dormant BWP (Rel-16) | The cell group's Active Time | The dormant SCell is excluded from PDCCH monitoring regardless of Active Time | A dormant SCell keeps its CSI reporting but costs no PDCCH decoding — cheaper than deactivating and re-adding it. |
Table 6. DRX scoping across CA and DC. The one-Active-Time-per-cell-group rule is the fact that resolves most confusion; the Rel-16 second DRX group is the only partial exception.
Because Active Time is per cell group, an SCell that keeps retransmitting is a power problem on the PCell. Its drx-RetransmissionTimerDL runs hold the whole group in Active Time. A UE that shows unexplained drain with CA enabled and none without it is usually looking at exactly this: check the SCell HARQ failure rate before the DRX configuration.
10. C-DRX and I-DRX: Two Mechanisms, One Name
The word DRX is used for two things that share only a concept. Connected-mode DRX (C-DRX) is everything above: dedicated RRC configuration, PDCCH monitoring for the UE's own C-RNTI, timers that react to grants. Idle-mode DRX (I-DRX) is the paging cycle: broadcast configuration, PDCCH monitoring for the P-RNTI, no reaction to anything because there is nothing scheduled to react to. They are specified in different documents and do not interact except in one place — a UE in RRC_CONNECTED does not monitor paging occasions for its own paging, because the network can reach it directly.
| C-DRX (connected mode) | I-DRX (idle / inactive paging DRX) | |
|---|---|---|
| RRC state | RRC_CONNECTED | RRC_IDLE and RRC_INACTIVE |
| Configured by | drx-Config in mac-CellGroupConfig, dedicated signalling | PCCH-Config in SIB1 (defaultPagingCycle, nAndPagingFrameOffset, ns), optionally overridden per UE by UE-SpecificDRX |
| Cycle range | ms10 to ms10240 | rf32, rf64, rf128, rf256 — i.e. 320 ms to 2560 ms; Rel-17 eDRX extends this further for RedCap |
| What the UE monitors | PDCCH for its own C-RNTI (plus CS-RNTI, SFI, etc.) in configured search spaces | PDCCH for the P-RNTI in the Type2-PDCCH common search space at its Paging Occasion |
| Wake-up instant derived from | [(SFN x 10) + subframe] mod cycle == drx-StartOffset (§5) | Paging Frame and Paging Occasion from the UE_ID, itself derived from 5G-S-TMSI mod 1024 |
| Reacts to traffic | Yes — drx-InactivityTimer, HARQ timers, SR, RACH | No. The cycle is fixed until reconfigured or the UE changes state |
| Network-side control | DRX Command and Long DRX Command MAC CEs, DCP | None per-UE at MAC level; Rel-17 PEI (DCI format 2_7) is the closest equivalent |
| Governing spec | TS 38.321 cl. 5.7 | TS 38.304, TS 38.331 PCCH-Config |
Table 7. C-DRX and I-DRX side by side. The companion 19 Paging document covers the I-DRX column in full; the companion 14 RRC States document covers which applies when.
During a state transition both can appear to be in force. A UE that has sent RRCReleaseRequest-triggering signalling, or that is executing RRCRelease, drops C-DRX and picks up the paging cycle — and the two have unrelated wake-up instants. A log window spanning the transition will show wake-ups at two incompatible periods, which is not a fault.
11. Power, Latency and Duty Cycle: Worked Numbers
The trade-off is quantifiable, and it is worth doing the arithmetic once because the intuition is wrong. Power saving saturates quickly; latency does not.
11.1 Duty cycle and receiver power
drx-onDurationTimer = ms8, drx-LongCycle = ms160, no traffic at all.
Duty cycle = 8 / 160 = 5.0%
Take an illustrative relative-power model (order of magnitude only; real figures are chipset-specific):
full PDCCH monitoring ......... 100 units
deep sleep ..................... 1 unit
wake / settle transient ........ 8 units of extra cost per wake-up,
lasting ~1 ms each side
Time budget per 160 ms cycle:
monitoring ................. 8.0 ms at 100 -> 800
transitions ................ 2.0 ms at 50 -> 100
deep sleep ................. 150.0 ms at 1 -> 150
total ...................... 160.0 ms -> 1050 units
Always-on reference: 160 x 100 = 16 000 units.
Saving = 1 - 1050 / 16000 = ~93%
Now halve the cycle to ms80. Duty cycle doubles to 10%, and the total becomes (8 x 100) + (2 x 50) + (70 x 1) = 970 units per 80 ms = 1940 per 160 ms -> saving ~88%. Doubling the wake-up rate cost five percentage points; the latency it bought back was 80 ms (§11.2).
11.2 The latency a sleeping UE adds to a downlink packet
A packet arriving while the UE is asleep waits until the next onDuration. For a packet arrival uniformly distributed over the cycle, with cycle C and onDuration On, the added delay is zero with probability On/C and uniform on [0, C − On] otherwise:
worst case = C - On mean = ((C - On) / C) x ((C - On) / 2) = (C - On)^2 / 2C
drx-onDurationTimer = ms8, drx-LongCycle = ms160, packet arrives 1 ms after the onDuration ends:
Time to the next occasion = 160 - 8 - 1 = 151 ms
Across all arrival phases:
worst case = 160 - 8 = 152 ms
mean = (152)^2 / (2 x 160) = 23104 / 320 = 72.2 ms
And that is only the wake-up delay. The full first-packet latency also includes the PDCCH decode, the PDSCH, the HARQ round trip and any RLC reordering — but those are milliseconds against 72.
Same arithmetic at ms40: mean = 32^2 / 80 = 12.8 ms. Four times the wake-up rate, one fifth of the mean delay, and only ~5 percentage points more receiver power (§11.1).
| Profile | onDur | Inact | Long | Short | Duty | Mean added latency | Fits |
|---|---|---|---|---|---|---|---|
| Low latency | ms8 | ms100 | ms40 | -- | 20% | ~13 ms | Active voice or video call, cloud gaming, screen-on interactive use |
| Balanced | ms8 | ms40 | ms80 | ms40 x 4 | 10% | ~32 ms | General smartphone use; the most commonly shipped default shape |
| Power saving | ms8 | ms10 | ms160 | ms40 x 4 | 5% | ~72 ms | Screen off with background sync; connected but idle |
| Deep saving | ms4 | ms0 | ms320 | -- | 1.25% | ~156 ms | Periodic telemetry where the application already tolerates delay |
| Strictly periodic | ms4 | ms0 | ms20 | -- | 20% | ~8 ms | VoIP-shaped traffic; cycle matched to the codec period so the packet always lands in onDuration |
Table 8. Illustrative profile shapes with the arithmetic of §11.2 applied. Duty figures are the no-traffic floor. The last row is the interesting one: matching the cycle to a known packet period beats any generic tuning, because the mean added latency stops being (C-On)^2/2C and becomes approximately zero.
The "strictly periodic" row is why drx-InactivityTimer = ms0 exists. If the traffic period and the DRX cycle are equal and the phase is right, every packet arrives inside onDuration and the inactivity extension is pure waste. Getting the phase right is the hard part — drx-StartOffset and drx-SlotOffset are the only tools, and neither is renegotiated when the application's jitter drifts. A profile like this that works in a lab and fails in the field has almost always drifted out of phase.
12. Rel-16 Power Saving Beyond DRX
Rel-16 added a set of features that do not replace DRX but adapt it dynamically. The common theme is that Rel-15 DRX is a static contract — the wake-up pattern is fixed until RRC reconfigures it — and the network often knows, a few milliseconds in advance, that a particular wake-up will be wasted.
12.1 DCP: the wake-up signal (DCI format 2_6)
DCP — DCI with CRC scrambled by PS-RNTI — is a small group-common DCI monitored shortly before the onDuration would start TS 38.213 cl. 10.3. It carries one wake-up indication bit per UE in the group, at a bit position given by ps-PositionDCI-2-6 in a payload of sizeDCI-2-6 bits. If the bit says wake, the UE starts drx-onDurationTimer normally. If it says sleep, the UE does not start it at all and the whole onDuration is skipped.
| Field | Range | Effect | What to check if DCP is not working |
|---|---|---|---|
ps-RNTI | RNTI-Value | The group-common RNTI the UE descrambles DCI 2_6 with | A mismatch means the UE never detects DCP; behaviour then depends entirely on ps-Wakeup. |
ps-Offset | 1..120 | How far ahead of the onDuration start the DCP monitoring occasion sits | Too small and the UE cannot power up its receiver in time to act on the indication; too large and the network must decide earlier than it knows. |
sizeDCI-2-6 | 1..max | Total payload size of the DCI, i.e. how many UEs and dormancy bits share it | Must match on both sides exactly — the DCI has no length field, so a mismatch is a silent decode failure. |
ps-PositionDCI-2-6 | 0..size-1 | Which bit in that payload is this UE's wake-up indication | Two UEs given the same position will wake and sleep together, which looks like a scheduler fault. |
ps-Wakeup | true or absent | true: if no DCP is detected, wake anyway. Absent: if no DCP is detected, do not start drx-onDurationTimer | This one field decides whether a DCP coverage hole costs power or costs reachability. Absent is the aggressive setting and the one that produces unreachable UEs at cell edge. |
ps-TransmitPeriodicL1-RSRP | true or absent | true: keep sending periodic L1-RSRP reports even when DCP said sleep | Without it, a UE told to sleep stops reporting L1-RSRP, and beam management degrades — visible as slower beam switching on power-saving UEs. See companion 12 Beam Failure Recovery. |
Table 9. DCP-Config fields, TS 38.331. ps-Wakeup is the field to read first when diagnosing anything DCP-related.
DCP is a net loss when the DCP occasion costs more than the onDuration it cancels. With drx-onDurationTimer ms8 the saving is large. With subMilliSeconds onDuration values — a few hundred microseconds — the UE may spend more energy waking up to read the wake-up signal than it would have spent simply monitoring. Enabling DCP on an already-aggressive DRX profile can measurably increase drain.
12.2 Search space set group switching
Rather than deciding whether to monitor at all, SSSG switching changes how much the UE monitors. Search space sets are tagged into groups by searchSpaceGroupIdList, and the network moves the UE between groups — typically a dense group for active traffic and a sparse group for idle periods — either explicitly with a bit in DCI format 2_0, or implicitly after searchSpaceSwitchTimer slots without scheduling. searchSpaceSwitchDelay bounds how long the UE may take to apply the change. The saving comes from fewer blind decodes per slot rather than fewer awake slots, so it composes with DRX instead of competing with it. See the companion 08 Scheduling document for the search space structures involved.
12.3 Cross-slot scheduling adaptation
A UE that might be scheduled with K0 = 0 — PDSCH in the same slot as its PDCCH — has to buffer every slot's samples while it decodes PDCCH, because the data might already have arrived. Rel-16 lets the network signal a minimum applicable scheduling offset (minimumSchedulingOffsetK0 for downlink, the K2 equivalent for uplink) and change it with DCI. Once the minimum is at least one slot, the UE can stop buffering speculatively, run its receiver front-end at lower power, and micro-sleep between PDCCH and PDSCH. The cost is a slot or more of added scheduling latency on every transmission, which is why the value is adapted rather than fixed.
12.4 SCell dormancy and dormantBWP
Deactivating an SCell and re-activating it is expensive — hundreds of milliseconds including CSI re-acquisition. A dormant BWP is the cheap middle state: the SCell is switched to the BWP identified by dormantBWP-Id, in which the UE performs no PDCCH monitoring but continues CSI measurement and reporting. Reactivation is therefore immediate, because the channel estimate is current. Dormancy is indicated by DCI format 1_1 while the UE is in Active Time (withinActiveTimeConfig) and by DCI format 2_6 while it is not (outsideActiveTimeConfig), so DCP and dormancy share one DCI.
SCell dormancy and SCell deactivation look similar in a log — both stop PDCCH on the SCell — but a dormant SCell keeps reporting CSI. If you see CSI reports arriving from a cell you believe is deactivated, it is dormant, and the reactivation delay you should expect is a few milliseconds rather than a few hundred.
13. Rel-17 and Rel-18: eDRX, PEI and PDCCH Skipping
Rel-17's power-saving work is aimed mostly at the idle-mode side and at RedCap devices, which have very different economics from a smartphone: a sensor that reports twice an hour cares nothing about a two-second paging delay and everything about ten years of battery.
- Extended DRX (eDRX) raises the idle- and inactive-mode paging cycle beyond the Rel-15 ceiling of 2.56 s, up to 10.24 s, by locating the paging occasion within a paging hyperframe rather than within the 1024-frame SFN space. It is gated by broadcast permission and by UE capability, and it is specific to RedCap and low-power use — a normal smartphone is not offered it.
- Paging Early Indication (PEI) puts a small group-common DCI (format 2_7, with PEI-RNTI) shortly before a paging occasion, so a UE can learn there is no page for my group without decoding the Paging PDCCH and its PDSCH. It is the idle-mode analogue of DCP. Configured by
pei-Configin SIB. - PDCCH monitoring adaptation extends the Rel-16 SSSG idea with explicit PDCCH skipping: a field in a scheduling DCI (formats 0_1/1_1/0_2/1_2) tells the UE to skip PDCCH monitoring for a duration drawn from
pdcch-SkippingDurationList. Unlike DRX this is immediate and per-DCI, so the network can stop monitoring the instant it knows a burst has ended, without spending a MAC CE.
Rel-18 shifts the emphasis from UE power to network power. Cell DTX/DRX gives the gNB its own discontinuous transmission and reception pattern, so a lightly loaded cell can stop transmitting reference signals and stop listening for uplink during configured windows. For DRX debugging this matters in one specific way: a UE's onDuration can now land inside a cell's non-transmission window, and the resulting missed scheduling opportunity is a network-side energy-saving decision, not a UE fault.
From Rel-16 onward, "the UE is not monitoring PDCCH" has at least five possible causes: outside Active Time; DCP said sleep; a dormant BWP; a sparse search space set group; or a PDCCH skipping instruction. They are configured in four different IEs and signalled by three different DCI formats. Any log analysis that assumes DRX is the only reason a UE stops listening will produce wrong conclusions on a Rel-16-or-later network.
14. Configuration Reference (ASN.1 and Ranges)
DRX-Config sits at CellGroupConfig -> mac-CellGroupConfig -> drx-Config, as a SetupRelease. Abridged to the fields that determine behaviour; ... marks omitted enumeration members, spares and extension markers:
DRX-Config ::= SEQUENCE {
drx-onDurationTimer CHOICE {
subMilliSeconds INTEGER (1..31),
milliSeconds ENUMERATED {
ms1, ms2, ms3, ms4, ms5, ms6, ms8, ms10, ms20, ms30, ms40,
ms50, ms60, ms80, ms100, ms200, ms300, ms400, ms500, ms600,
ms800, ms1000, ms1200, ms1600, spare8, ... }
},
drx-InactivityTimer ENUMERATED {
ms0, ms1, ms2, ms3, ms4, ms5, ms6, ms8, ms10, ms20, ms30, ms40,
ms50, ms60, ms80, ms100, ms200, ms300, ms500, ms750, ms1280,
ms1920, ms2560, spare10, ... },
drx-HARQ-RTT-TimerDL INTEGER (0..56), -- symbols
drx-HARQ-RTT-TimerUL INTEGER (0..56), -- symbols
drx-RetransmissionTimerDL ENUMERATED {
sl0, sl1, sl2, sl4, sl6, sl8, sl16, sl24, sl33, sl40, sl64,
sl80, sl96, sl112, sl128, sl160, sl320, spare15, ... },
drx-RetransmissionTimerUL ENUMERATED { ... same list ... },
drx-LongCycleStartOffset CHOICE {
ms10 INTEGER (0..9),
ms20 INTEGER (0..19),
ms32 INTEGER (0..31),
ms40 INTEGER (0..39),
ms60 INTEGER (0..59),
ms64 INTEGER (0..63),
ms70 INTEGER (0..69),
ms80 INTEGER (0..79),
ms128 INTEGER (0..127),
ms160 INTEGER (0..159),
ms256 INTEGER (0..255),
ms320 INTEGER (0..319),
ms512 INTEGER (0..511),
ms640 INTEGER (0..639),
ms1024 INTEGER (0..1023),
ms1280 INTEGER (0..1279),
ms2048 INTEGER (0..2047),
ms2560 INTEGER (0..2559),
ms5120 INTEGER (0..5119),
ms10240 INTEGER (0..10239)
},
shortDRX SEQUENCE {
drx-ShortCycle ENUMERATED {
ms2, ms3, ms4, ms5, ms6, ms7, ms8, ms10, ms14, ms16, ms20,
ms30, ms32, ms35, ms40, ms64, ms80, ms128, ms160, ms256,
ms320, ms512, ms640, spare9, ... },
drx-ShortCycleTimer INTEGER (1..16)
} OPTIONAL,
drx-SlotOffset INTEGER (0..31) -- units of 1/32 ms
}Listing 1. Abridged from TS 38.331. Note that the cycle and its offset are one field, that shortDRX is optional as a block, and that drx-SlotOffset is mandatory even when it is zero.
DCP-Config-r16 ::= SEQUENCE {
ps-RNTI-r16 RNTI-Value,
ps-Offset-r16 INTEGER (1..120),
sizeDCI-2-6-r16 INTEGER (1..maxDCI-2-6-Size-r16),
ps-PositionDCI-2-6-r16 INTEGER (0..maxDCI-2-6-Size-1-r16)
OPTIONAL,
ps-WakeUp-r16 ENUMERATED {true} OPTIONAL,
ps-TransmitPeriodicL1-RSRP-r16 ENUMERATED {true} OPTIONAL,
ps-TransmitOtherPeriodicCSI-r16 ENUMERATED {true} OPTIONAL,
...
}Listing 2. DCP-Config, Rel-16, abridged from TS 38.331. The three optional true-only fields are all presence means enabled — absence is the aggressive setting in each case.
15. Failure Modes and What Each One Means
DRX has no failure indication. Nothing in the protocol reports that the UE and the gNB disagree about when the receiver is on, and no timer expires to tell you. Every failure mode below is diagnosed indirectly, from HARQ statistics, latency distributions or power measurements.
| Failure | Detected by | What the UE does | Diagnostic pointer |
|---|---|---|---|
| UE and gNB disagree on the cycle occasion (offset or cycle mismatch after a reconfiguration) | Nobody, directly | Sleeps through every scheduling attempt at the gNB's believed onDuration | HARQ DTX — not NACK, DTX — on first transmissions, at a period equal to the cycle. Recompute the congruence of §5 from the logged SFN and compare with the gNB's own onDuration log. |
drx-onDurationTimer too short for the cell's PDCCH load | Nobody | Sleeps before the scheduler reaches it in the round-robin | Latency for the first packet of a burst is much worse than §11.2 predicts, and worsens with cell load. Distinguish from a coverage problem by the load correlation. |
drx-InactivityTimer too long | Nobody | Stays awake correctly, just far longer than necessary | Power drain much worse than the duty cycle suggests. Measure the ratio of Active Time to scheduled slots; a ratio above about 10 means the timer is paying for nothing. |
drx-RetransmissionTimerDL too short for scheduler delay | Nobody | Stops monitoring before the retransmission grant arrives; HARQ process stalls until RLC recovers it | HARQ DTX on retransmissions only, first transmissions clean. Look at the PDCCH-to-retransmission delay distribution against the configured slot count. |
| DRX Command MAC CE lost to HARQ | Nobody | Keeps monitoring for the rest of drx-InactivityTimer; gNB assumes it is asleep | Harmless but wasteful. Shows as occasional Active Time longer than the gNB's own record. Check downlink HARQ BLER before re-tuning timers. |
drx-ShortCycle does not divide drx-LongCycle | UE RRC, at reconfiguration | The configuration is invalid; many implementations reject the whole RRCReconfiguration | RRCReconfigurationFailure or a re-establishment immediately after a DRX change. Validate the divisibility before blaming the radio. |
drx-onDurationTimer >= drx-ShortCycle | Nobody | Never sleeps while on the short cycle — the next onDuration starts before the previous ends | Duty cycle pinned at 100% during the short-cycle stage only, returning to normal when drx-ShortCycleTimer expires. A very distinctive power signature. |
Every UE in the cell given the same drx-StartOffset | Nobody | Behaves correctly; all UEs wake simultaneously | Periodic PDCCH blocking and CCE exhaustion at exactly the cycle period, with no corresponding traffic peak. Spread the offsets. |
DCP not detected (ps-RNTI or sizeDCI-2-6 mismatch) | Nobody | With ps-Wakeup = true, wakes anyway (safe). Without it, never starts drx-onDurationTimer at all | In the unsafe case the UE becomes unreachable except through RLM/RLF recovery. Any UE that stops responding entirely after DCP is enabled is this. |
| Periodic traffic drifting out of phase with the cycle | Nobody | Correct behaviour; packets begin missing onDuration | Latency that is excellent for hours then degrades to nearly a full cycle. Look for the phase relationship, not for a fault. |
Table 10. DRX failure modes. Note the second column: eight of the ten are detected by nobody, which is the defining characteristic of this mechanism and the reason the checklist in §18 starts with recomputing the arithmetic.
The single most useful DRX diagnostic is the distinction between HARQ DTX and HARQ NACK. NACK means the UE was listening and failed to decode — a radio problem. DTX means the UE sent no feedback at all, which usually means it was not listening — a DRX problem. Conflating them sends you looking for coverage faults that are not there.
16. Illustrative Message Traces
Illustrative trace. Field names and encodings follow 3GPP; the values are constructed for this document and are not a capture from any deployed or lab network.
16.1 The configuration the UE is given
RRCReconfiguration
criticalExtensions rrcReconfiguration
secondaryCellGroup / masterCellGroup
mac-CellGroupConfig
drx-Config setup
drx-onDurationTimer
milliSeconds ................. ms8
drx-InactivityTimer ........... ms40
drx-HARQ-RTT-TimerDL .......... 56 -- symbols; 2.0 ms @ 30 kHz
drx-HARQ-RTT-TimerUL .......... 56
drx-RetransmissionTimerDL ..... sl16 -- slots; 8.0 ms @ 30 kHz
drx-RetransmissionTimerUL ..... sl16
drx-LongCycleStartOffset
ms80 ......................... 27 -- cycle 80 ms, offset 27
shortDRX
drx-ShortCycle ............... ms20
drx-ShortCycleTimer .......... 4 -- 4 x 20 = 80 ms residency
drx-SlotOffset ................ 16 -- 16/32 = 0.5 ms
schedulingRequestConfig ........ (see companion 10 BSR, PHR, SR)
bsr-Config ..................... (idem)
-- derived by the UE, not signalled:
-- long-cycle occasions : SFN = 2 mod 8, subframe 7, +0.5 ms -> slot 15
-- short-cycle occasions : subframe 7 of every even SFN, +0.5 ms
-- floor duty cycle : 8 / 80 = 10%Listing 3. A drx-Config as it would appear decoded, with the arithmetic of §5 already applied. The derived lines are what a good MAC trace prints alongside the configuration.
16.2 An empty cycle, then a burst
-- C-RNTI 0x5C11 throughout, 30 kHz SCS, config as above
09:41:02.007 [MAC] DRX cycle occasion SFN 82 sf 7 slot 1655
cycle=long(80) offset=27 slotOffset=16
-> start drx-onDurationTimer (ms8 = 16 slots)
09:41:02.007 [MAC] ACTIVE TIME begin reason=onDurationTimer
09:41:02.015 [MAC] drx-onDurationTimer expiry, no PDCCH decoded
09:41:02.015 [MAC] ACTIVE TIME end -> sleep 72 ms
09:41:02.087 [MAC] DRX cycle occasion SFN 90 sf 7
-> start drx-onDurationTimer
09:41:02.087 [MAC] ACTIVE TIME begin reason=onDurationTimer
09:41:02.090 [PHY] PDCCH DCI 1_1 C-RNTI 0x5C11 HARQ 2 NDI toggled
09:41:02.090 [MAC] new DL transmission -> start drx-InactivityTimer ms40
09:41:02.091 [PHY] PDSCH 1248 bytes, decoded OK -> ACK on PUCCH
09:41:02.091 [MAC] start drx-HARQ-RTT-TimerDL(HARQ 2) = 56 sym
09:41:02.093 [MAC] drx-HARQ-RTT-TimerDL(HARQ 2) expiry, TB decoded OK
-> drx-RetransmissionTimerDL NOT started
09:41:02.095 [MAC] drx-onDurationTimer expiry
-> ACTIVE TIME continues, reason=InactivityTimer
09:41:02.104 [PHY] PDCCH DCI 1_1 HARQ 3 NDI toggled
09:41:02.104 [MAC] new DL transmission -> RESTART drx-InactivityTimer ms40
(28 ms of the previous run discarded)
09:41:02.144 [MAC] drx-InactivityTimer expiry
09:41:02.144 [MAC] shortDRX configured -> start drx-ShortCycleTimer (4)
-> cycle=short(20)
09:41:02.144 [MAC] ACTIVE TIME end -> sleep
09:41:02.147 [MAC] DRX cycle occasion SFN 94 sf 7 cycle=short(20)
-> start drx-onDurationTimerListing 4. One empty cycle and one cycle with traffic. The two lines worth reading twice are the InactivityTimer restart at .104 and the cycle switch at .144.
16.3 A retransmission with a sleep inside it
-- same UE; drx-InactivityTimer temporarily reconfigured to ms0 to make
-- the HARQ-driven wake-ups visible on their own
09:44:17.400 [MAC] DRX cycle occasion SFN 174 sf 7
-> start drx-onDurationTimer (ms4)
09:44:17.401 [PHY] PDCCH DCI 1_1 HARQ 5 NDI toggled MCS 22
09:44:17.401 [MAC] drx-InactivityTimer = ms0 -> no extension
09:44:17.402 [PHY] PDSCH 2408 bytes CRC FAIL
09:44:17.403 [PHY] PUCCH HARQ-ACK HARQ 5 = NACK
09:44:17.403 [MAC] start drx-HARQ-RTT-TimerDL(HARQ 5) = 56 sym = 2.0 ms
09:44:17.404 [MAC] drx-onDurationTimer expiry
09:44:17.404 [MAC] ACTIVE TIME end
-- HARQ-RTT timer is running but is NOT Active Time
-> receiver OFF for 1.3 ms
09:44:17.405 [MAC] drx-HARQ-RTT-TimerDL(HARQ 5) expiry, TB NOT decoded
-> start drx-RetransmissionTimerDL(HARQ 5) = sl16 = 8.0 ms
09:44:17.405 [MAC] ACTIVE TIME begin reason=RetransmissionTimerDL
09:44:17.407 [PHY] PDCCH DCI 1_1 HARQ 5 NDI unchanged -- retransmission
09:44:17.407 [MAC] stop drx-RetransmissionTimerDL(HARQ 5)
-- retransmission grant: drx-InactivityTimer NOT restarted
09:44:17.408 [PHY] PDSCH combined with earlier attempt, decoded OK
09:44:17.410 [PHY] PUCCH HARQ-ACK HARQ 5 = ACK
09:44:17.410 [MAC] start drx-HARQ-RTT-TimerDL(HARQ 5) = 2.0 ms
09:44:17.410 [MAC] ACTIVE TIME end -> sleep to SFN 182 sf 7
09:44:17.412 [MAC] drx-HARQ-RTT-TimerDL(HARQ 5) expiry, TB decoded OK
-> drx-RetransmissionTimerDL NOT startedListing 5. The 1.3 ms of sleep at 17.404 is the whole reason drx-HARQ-RTT-TimerDL exists. Note also that Active Time ends at 17.410 even though a PDSCH was received two milliseconds earlier.
16.4 The DRX Command MAC CE
09:47:55.612 [PHY] PDCCH DCI 1_1 C-RNTI 0x5C11 HARQ 1 NDI toggled
09:47:55.613 [MAC-DL] MAC PDU, 34 octets
subheader R=0 F=0 LCID=1 L=32 -- DCCH SDU
(RRC message, 32 octets)
subheader R=0 R=0 LCID=60 -- 0x3C
DRX Command MAC CE -- zero length
subheader R=0 R=0 LCID=63 -- padding to 34 octets
09:47:55.613 [MAC] DRX Command MAC CE received
-> stop drx-onDurationTimer
-> stop drx-InactivityTimer (37 ms remaining, discarded)
-> shortDRX configured: start drx-ShortCycleTimer (4 x ms20)
-> cycle = short(20)
09:47:55.613 [MAC] ACTIVE TIME end
09:47:55.693 [MAC] drx-ShortCycleTimer expiry -> cycle = long(80)
-- alternative ending: the gNB skips the short-cycle stage
09:47:55.627 [MAC-DL] MAC PDU, 1 octet
subheader R=0 R=0 LCID=59 -- 0x3B
Long DRX Command MAC CE -- zero length
09:47:55.627 [MAC] Long DRX Command MAC CE received
-> stop drx-ShortCycleTimer
-> cycle = long(80)
-- next onDuration at SFN = 2 mod 8, subframe 7Listing 6. Both CEs on the wire. The Long DRX Command arrives as a single-octet MAC PDU, which is as small as a downlink transmission can usefully be.
16.5 A failure path: offset mismatch after reconfiguration
-- gNB believes offset 27; UE applied offset 7 (a stale configuration
-- retained after a reconfiguration the UE did not fully apply)
[gNB-MAC] 10:02:14.007 UE 0x5C11 onDuration expected SFN 82 sf 7
[gNB-MAC] 10:02:14.009 DL data queued (1240 B) -> schedule DCI 1_1
[gNB-PHY] 10:02:14.010 PDSCH sent, HARQ 4, awaiting PUCCH k1=2
[gNB-PHY] 10:02:14.011 PUCCH occasion empty -- HARQ 4 = DTX
[gNB-MAC] 10:02:14.012 retransmit HARQ 4 (adaptive)
[gNB-PHY] 10:02:14.014 PUCCH occasion empty -- HARQ 4 = DTX
[gNB-MAC] 10:02:14.016 retransmit HARQ 4, RV 2
[gNB-PHY] 10:02:14.018 PUCCH occasion empty -- HARQ 4 = DTX
[gNB-MAC] 10:02:14.020 HARQ 4 abandoned -> RLC will recover
[UE-MAC] 10:02:13.987 DRX cycle occasion SFN 82 sf 7? no
[(82 x 10) + 7] mod 80 = 27 ... offset in use = 7
27 != 7 -> not an occasion, stay asleep
[UE-MAC] 10:02:14.047 DRX cycle occasion SFN 88 sf 7
[(88 x 10) + 7] mod 80 = 7 == offset -> wake
-> start drx-onDurationTimer
-- signature: three DTX in a row on a FIRST transmission, then a clean
-- exchange exactly 20 ms later; repeating every 80 ms. Not a radio fault.Listing 7. An offset mismatch, seen from both sides. Three DTX on a first transmission followed by a clean exchange one offset-difference later, repeating at the cycle period, is the fingerprint.
In the failure trace the UE is behaving perfectly and the gNB is behaving perfectly; only the offsets differ. Everything visible on the radio — DTX, adaptive retransmission, RLC recovery — points at coverage, and none of it is a coverage problem. The only way to see it is to recompute the congruence of §5 from both sides' logged offsets. This is the single most valuable habit for DRX debugging.
17. Release Deltas: Rel-15 to Rel-18
| Release | Change | Why it matters when reading DRX |
|---|---|---|
| Rel-15 | DRX-Config with the full timer set; long and short cycles; DRX Command and Long DRX Command MAC CEs; Active Time as a union | The baseline. Everything in §2 to §8 is Rel-15 and unchanged since. |
| Rel-16 | DCP — DCI format 2_6 with PS-RNTI, ps-Offset, ps-Wakeup, ps-TransmitPeriodicL1-RSRP | An onDuration can now simply not happen. Absence of a wake-up is no longer evidence of a fault (§12.1). |
| Rel-16 | Search space set group switching — searchSpaceGroupIdList, searchSpaceSwitchTimer, searchSpaceSwitchDelay, a flag in DCI 2_0 | The number of blind decodes per awake slot is now dynamic, so Active Time no longer maps linearly onto power. |
| Rel-16 | Cross-slot scheduling adaptation — minimumSchedulingOffsetK0 / K2, changed by DCI | K0 = 0 may be temporarily prohibited; a scheduler that assumes same-slot PDSCH will be rejected. |
| Rel-16 | SCell dormancy — dormantBWP-Id, withinActiveTimeConfig, outsideActiveTimeConfig, dormancy bits in DCI 1_1 and 2_6 | A silent SCell that is still reporting CSI is dormant, not deactivated (§12.4). |
| Rel-16 | Two DRX groups — a secondary group with its own drx-onDurationTimer and drx-InactivityTimer | FR1 and FR2 serving cells of one cell group can now have different onDurations, so "one Active Time per cell group" acquires an exception. |
| Rel-17 | eDRX for RedCap — idle/inactive paging cycles beyond 2.56 s, up to 10.24 s, using a paging hyperframe | Paging latency of several seconds becomes normal for a whole device class (§13). |
| Rel-17 | PEI — Paging Early Indication, DCI format 2_7 with PEI-RNTI, pei-Config in SIB | An idle UE may decode nothing at its paging occasion and still be correct. |
| Rel-17 | PDCCH monitoring adaptation — PDCCH skipping via a field in DCI 0_1/1_1/0_2/1_2, pdcch-SkippingDurationList; SSSG switching extended | Monitoring can now stop mid-onDuration, on a per-DCI basis, without any MAC CE. |
| Rel-18 | Cell DTX/DRX — network-side discontinuous transmission and reception for energy saving | A missed scheduling opportunity inside a valid onDuration may be the cell sleeping, not the UE. |
| Rel-18 | Further power-saving refinements motivated by XR and always-on traffic, including better alignment of DRX with periodic media frame rates | Profiles tuned to application periodicity (§11.2, last row) become more common, so phase relationships matter more than duty cycles. |
Table 11. DRX-relevant changes by release. Confirm feature presence against the UE capability exchange before assuming any of it is active — see the companion 26 UE Capability document.
18. Reading DRX in Logs: A Checklist
1. Recompute the cycle occasions from both sides' configuration. Take the SFN from the log, evaluate [(SFN x 10) + subframe] mod cycle, and compare against drx-StartOffset (§5). Do this before anything else; an offset or cycle mismatch explains symptoms that otherwise look like a radio fault.
2. Convert every timer into wall-clock time for the BWP actually in use. The HARQ RTT timers are symbols, the retransmission timers are slots. A configuration is a different mechanism at 30 kHz and at 120 kHz (§4).
3. Separate HARQ DTX from HARQ NACK. DTX means the UE was not listening and points at DRX; NACK means it was listening and points at the radio. This single distinction resolves most DRX investigations.
4. Establish which cycle is in use at the moment of interest. Long, short, or Active Time. drx-ShortCycleTimer expiry changes the wake-up spacing with no signalling at all, so infer it from the intervals, not from messages.
5. Check whether the PDCCH monitoring you are seeing outside onDuration is a retransmission timer. Match it against a HARQ process that NACKed one drx-HARQ-RTT-Timer earlier (§8). If it matches, it is correct behaviour.
6. Look for the DRX Command MAC CE. LCID 60 on DL-SCH, a single octet, easy to miss in a PDU dump. Its presence tells you the scheduler is actively managing Active Time; its absence tells you the whole drx-InactivityTimer is being spent every burst.
7. Measure the ratio of Active Time to scheduled slots. A UE awake for many multiples of the time it is actually being scheduled has drx-InactivityTimer set too long — that ratio is a more useful number than the configured duty cycle.
8. Before blaming DRX for a UE that stopped listening, rule out the other four Rel-16+ reasons: DCP said sleep, a dormant BWP, a sparse search space set group, or a PDCCH skipping instruction (§12, §13).
9. For latency complaints, compare the measured delay against (C - On)^2 / 2C. If the measured mean is close to the prediction, the configuration is working as designed and the fix is a shorter cycle, not debugging. If it is much worse, look at PDCCH load during onDuration.
10. Check the offset distribution across UEs in the cell. Identical drx-StartOffset values produce synchronised wake-ups and periodic CCE exhaustion that looks like a capacity problem (§15).
19. Glossary
| Term | Expansion | Meaning in this document |
|---|---|---|
| DRX | Discontinuous Reception | A set of permissions not to monitor PDCCH, evaluated per monitoring occasion. Not a state. |
| C-DRX | Connected-mode DRX | DRX in RRC_CONNECTED, configured by drx-Config per cell group (§1-§9). |
| I-DRX | Idle-mode DRX | The paging cycle in RRC_IDLE and RRC_INACTIVE, configured by broadcast PCCH-Config (§10). |
| Active Time | -- | The union of conditions under which the UE must monitor PDCCH. The only quantity that actually decides whether the receiver is on (§3). |
| onDuration | -- | The mandatory monitoring window at the start of each cycle, bounded by drx-onDurationTimer. |
| Cycle occasion | -- | A subframe satisfying the congruence of §5; where onDuration starts. |
drx-StartOffset | -- | The INTEGER inside the drx-LongCycleStartOffset CHOICE. Fixes the phase of the cycle within the SFN space. |
| DCP | DCI with CRC scrambled by PS-RNTI | The Rel-16 wake-up signal, DCI format 2_6, monitored before onDuration would start (§12.1). |
| WUS | Wake-Up Signal | Informal name for the DCP wake-up indication bit. |
| SSSG | Search Space Set Group | A tagged set of search space sets the network can switch a UE between, changing how many blind decodes each awake slot costs (§12.2). |
| Dormant BWP | -- | An SCell BWP in which the UE does no PDCCH monitoring but continues CSI reporting (§12.4). |
| eDRX | Extended DRX | Rel-17 idle/inactive paging cycles beyond 2.56 s for RedCap, using a paging hyperframe (§13). |
| PEI | Paging Early Indication | Rel-17 DCI format 2_7 that lets an idle UE skip decoding its paging occasion (§13). |
| DTX | Discontinuous Transmission | Here: the gNB detected no HARQ feedback at all, as distinct from a decoded NACK. The primary DRX symptom (§15). |
| Duty cycle | -- | drx-onDurationTimer / cycle. A floor on PDCCH monitoring with no traffic, not a prediction of real awake time (§11). |
20. References
- 3GPP TS 38.321 — NR MAC protocol specification. Clause 5.7 (DRX: Active Time definition, cycle start condition, timer handling, HARQ RTT and retransmission timer rules, short/long cycle transitions), 5.4.4 (Scheduling Request, for the pending-SR contributor), 5.4.5 (BSR), 6.1.2 (MAC subheader formats), 6.1.3.3 / 6.1.3.4 (DRX Command and Long DRX Command MAC CEs), Table 6.2.1-1 (DL-SCH LCID values).
- 3GPP TS 38.331 — RRC protocol specification.
DRX-Config,MAC-CellGroupConfig,DCP-Config,SearchSpace,BWP-DownlinkDedicatedand the dormant BWP fields,PCCH-Config(for I-DRX),pei-Config. - 3GPP TS 38.213 — Physical layer procedures for control. Clause 10.3 (monitoring DCI format 2_6 for DCP), clause 10.4 (search space set group switching), clause 10.1 (search space monitoring generally).
- 3GPP TS 38.212 — Multiplexing and channel coding. DCI format 2_6 contents, and the scheduling DCI fields carrying PDCCH skipping and SSSG indications.
- 3GPP TS 38.304 — UE procedures in Idle and Inactive. Paging Frame and Paging Occasion derivation, the I-DRX cycle, and the Rel-17 eDRX extension.
- 3GPP TS 38.300 — NR overall description. Clause 9.2.4 and the DRX overview text placing the mechanism in the RRC state model.
- 3GPP TS 38.133 — Requirements for support of radio resource management. Interruption and delay requirements the UE is allowed when waking and switching BWPs, which bound how aggressive a DRX profile can usefully be.
Companion documents in this set
- 02 Radio Frame Structure — SFN, subframes and slots; the numbering the cycle arithmetic of §5 operates on.
- 03 Random Access —
ra-ContentionResolutionTimer, an Active Time contributor, and the CFRA case in the last Active Time row. - 05 HARQ — the NDI semantics that decide whether a PDCCH restarts
drx-InactivityTimer, and the process state the HARQ RTT timers key off. - 07 MAC PDU and Control Elements — the general subheader format that §7 specialises for zero-length CEs.
- 08 Scheduling — search spaces, CORESETs and PDCCH monitoring occasions; what DRX switches off.
- 10 BSR, PHR, SR — the Scheduling Request whose pending state is an Active Time contributor.
- 12 Beam Failure Recovery — why
ps-TransmitPeriodicL1-RSRPmatters, and the CFRA that keeps the UE awake awaiting a response. - 14 RRC States — which of C-DRX and I-DRX applies in each state.
- 16 RLM and RLF — what happens when a UE becomes unreachable because it is not listening.
- 19 Paging — the I-DRX column of the table in §10, in full.
- 21 Measurement Gaps and SMTC — the other periodic pattern the UE must obey, and its interaction with onDuration.
- 26 UE Capability — where DCP, SSSG switching, dormancy and eDRX support is declared.