>
HomeLTE 4GVoice — VoLTE & IMSVoLTE & ROHC
📞 Voice — VoLTE & IMSIntermediate

VoLTE with ROHC

Why voice needs Robust Header Compression — shrinking the RTP/UDP/IP header on the QCI=1 voice DRB to boost capacity.

📚 3GPP-basedTS 36.323TS 26.114

A VoLTE voice frame is tiny — an AMR/AMR-WB speech frame is only about 32 bytes every 20 ms — yet the RTP/UDP/IP header stacked on top of it is roughly 40 bytes (IPv4) to 60 bytes (IPv6). The header is as big as the voice it carries, or bigger. Sending that uncompressed over the LTE air interface would waste scarce radio resources on fields that barely change, and would slash how many simultaneous voice calls a cell can hold. Robust Header Compression (ROHC) is the fix: it squeezes that header down to as little as 1–3 bytes on the voice bearer. This page is grounded in TS 36.323 (PDCP) and TS 26.114 (IMS multimedia telephony), with the ROHC profiles coming from the IETF framework.

Introduction

Robust Header Compression (ROHC) is the PDCP-layer function that makes VoLTE spectrally affordable. Voice over LTE is IMS media — small AMR/AMR-WB speech frames wrapped in RTP/UDP/IP — and on that traffic the protocol header is as large as, or larger than, the payload it carries. ROHC collapses that header to a couple of bytes on the dedicated voice radio bearer, and it is one of the handful of features that separates "voice as an afterthought" from "hundreds of concurrent calls per cell."

It runs inside the PDCP entity (TS 36.323), turned on per radio bearer by RRC, and it works because a voice flow is extraordinarily regular: the addresses and ports never change, and the RTP counters advance by a fixed step every 20 ms — the cadence set by the AMR codec (TS 26.114). ROHC learns that pattern, then stops sending everything it can predict.

From an operations point of view ROHC is a live, stateful process on each bearer: a compressor and decompressor keep a synchronised context, move through initialization/refresh states, and must recover from packet loss and from mobility events that wipe the context. When VoLTE quality degrades — robotic audio, silent gaps after a handover, poor cell-edge voice — the ROHC context and its state machine are among the first things to check. This page keeps that practical, debuggable lens.

Why ROHC is needed

💡

In plain words: imagine mailing a one-line note, but every envelope also repeats the full sender and recipient postal addresses, the return address, and a tracking code — and you mail 50 of these notes every second for the whole call. After the first envelope, the postman already knows both addresses. ROHC is the agreement that says "from now on just write the one line and a tiny counter; I remember the rest." The note is the speech; the addresses are the RTP/UDP/IP header.

The concrete purpose is capacity and coverage on the voice bearer. For a bulk download the header is a rounding error against a 1500-byte payload; for conversational voice the header is the packet, and it repeats 50 times a second per user for the entire call. Multiply that by every active caller in a cell and a large fraction of the LTE air interface is spent on header fields that barely change. Compressing them is not a nice-to-have — it is what lets an LTE cell carry hundreds of simultaneous VoLTE calls instead of a handful, and what lets a shrunken voice packet survive at the cell edge.

🎯

The core problem: for bulk data the header is a rounding error against a 1500-byte payload; for VoLTE the header is the packet. Compressing it is not a nice-to-have — it is what makes VoLTE spectrally viable.

The Problem: Header Bigger Than the Voice

VoLTE carries voice as media over IMS: the codec frame (typically AMR narrowband or AMR-WB wideband) rides inside RTP, which rides inside UDP, which rides inside IP. Each layer adds a fixed header, and the trouble is the imbalance between that header and the speech it wraps. For a bulk download the header is trivia against a 1500-byte payload; for conversational voice the header is the packet.

Look at the numbers layer by layer. The IP header is 20 bytes for IPv4 or 40 bytes for IPv6; UDP adds a fixed 8 bytes; RTP adds 12 bytes. That is a 40-byte transport stack over IPv4 and a 60-byte stack over IPv6 — and IMS deployments increasingly run IPv6, so the 60-byte case is the one that hurts most. Around it sits an AMR/AMR-WB frame of roughly 32 bytes.

Layer / headerBytes beforeAfter ROHC (SO state)
IP header20 (IPv4) / 40 (IPv6)≈ 1–3 B combined
UDP header8
RTP header12
Total header≈ 40 B (IPv4) / 60 B (IPv6)≈ 1–3 B
AMR/AMR-WB payload≈ 32 B (unchanged)≈ 32 B (unchanged)

So a single voice packet might be 40–60 bytes of header around 32 bytes of speech — the overhead is half to two-thirds of the packet. A call fires one of these every 20 ms — 50 packets per second per user — for its whole duration. Multiply that overhead by every active caller in a cell and you are burning a large fraction of the LTE air interface on header fields that are, packet after packet, almost identical. The IP addresses never change during the call, the UDP ports never change, and the RTP stream identifier never changes; only a couple of counters tick predictably. That is a compression opportunity begging to be taken.

What ROHC Does

ROHC exploits a simple observation: across the thousands of packets in one call, most header fields never change and the rest change predictably. The source/destination IP addresses, the UDP ports and the RTP SSRC are constant for the whole call. The RTP sequence number increments by one each packet, and the timestamp jumps by a fixed sample count every 20 ms. Once both ends agree on those starting values and steps, almost nothing needs to be sent on the wire.

What

A compressor/decompressor pair that replaces the full RTP/UDP/IP header with a few-byte compressed header, while the two ends keep a synchronised context holding the static and dynamic field values.

Why

The header is enormous relative to the AMR/AMR-WB payload. Collapsing 40–60 bytes to 1–3 bytes roughly doubles the useful payload ratio on the voice bearer, directly increasing VoLTE cell capacity and improving cell-edge coverage.

How

Send the static fields once (the IR state), then send only the unpredictable delta — usually just a few low-order bits of the sequence number. The decompressor rebuilds the full header from its stored context plus that delta.

The deep mechanics — exactly how each profile encodes individual fields, the W-LSB (windowed least-significant-bits) sequence-number encoding, the CRC verification of each reconstructed header, and the full compressor and decompressor state machines — are covered on the general ROHC Header Compression page. This page does not repeat that machinery. Here the focus is narrower and concrete: what ROHC buys the VoLTE voice bearer, how it is switched on, how it interacts with the AMR codec, and why it is the linchpin of LTE voice capacity. Read the two pages together — this one for the VoLTE application, that one for the algorithm.

💡

One-line intuition: the first packet of a call is a full letter carrying both addresses; every later packet is a postcard that says “same as before, plus one.” VoLTE sends postcards, 50 a second, for minutes on end.

Where ROHC Lives — PDCP on the QCI 1 Voice DRB

ROHC is a PDCP function (TS 36.323). It runs inside the PDCP entity of a specific radio bearer — on the transmit side as the compressor and on the receive side as the decompressor — and it is turned on per DRB by RRC. In the PDCP transmit chain the ordering is fixed: header compression happens first, then ciphering, then the PDCP header is prepended. On receive the mirror applies — deciphering first, then decompression — because the compressor must see the original clear-text IP header, not encrypted bytes.

For VoLTE the bearer in question is the dedicated GBR voice DRB mapped to the QCI=1 EPS bearer — the standardised QCI for conversational voice, with a guaranteed bit rate sized for the codec. RRC configures header compression through the PDCP-Config of that DRB. The headerCompression field is a CHOICE: either notUsed, or rohc. When set to rohc it carries the list of enabled profiles plus the maximum context identifier maxCID — how many parallel contexts (flows) the entity may track at once. A voice bearer needs only a couple of contexts (one per media direction/flow), so maxCID is small; the field exists mainly for bearers multiplexing many IP flows.

ProfileCompressesRelevance to VoLTE
profile 0x0001 (RTP/UDP/IP)Full RTP/UDP/IP stackThe voice profile. RTP-aware: understands the sequence-number/timestamp relationship, so the steady-state header is near-minimal.
0x0002 (UDP/IP)UDP/IP onlyNon-RTP UDP flows; not the voice media path.
0x0003 (ESP/IP)IP with IPsec ESPEncrypted transport flows; not the VoLTE media bearer.
0x0004 (IP)IP onlyGeneric IP flows with no useful transport regularity.
0x0000 (uncompressed)Nothing (passthrough)Fallback profile; always implicitly supported.

For voice, the profile that matters is profile 0x0001 (RTP/UDP/IP) — the only profile that is aware of RTP timing. Because it knows the timestamp advances by a fixed stride every packet and the sequence number increments by one, it can extrapolate almost the entire header from a single small sequence-number field. The UDP/IP and IP-only profiles still help, but they leave the RTP layer uncompressed and so give a much smaller win — useless for the voice media path.

📗

Spec note: TS 36.323 defines how PDCP invokes ROHC and the order in the PDCP chain (header compression before ciphering on transmit, decompression after deciphering on receive). The profiles themselves come from the IETF ROHC framework and the per-profile RFCs. The permitted profile set and maxCID are signalled to the UE in PDCP-Config inside the RRCConnectionReconfiguration that sets up the voice bearer.

💡

Why per-DRB matters here: the network enables rohc with profile 0x0001 on the QCI=1 voice DRB, but typically leaves headerCompression set to notUsed on the default QCI=9 data DRB — a 40-byte header against a 1500-byte download is not worth the compressor state.

Reading the ROHC bearer setup in the logs

Header compression either got negotiated onto the voice bearer or it did not — and that decision is visible in the RRCConnectionReconfiguration that establishes the QCI=1 DRB. If headerCompression comes back notUsed, or profile 0x0001 is absent from the list, the voice bearer will carry full 40/60-byte headers and cell voice capacity collapses.

Representative UE RRC log — illustrative, values vary by vendor/build:

RRC: RRCConnectionReconfiguration drb-Identity=2 eps-BearerIdentity=6 (QCI=1, GBR) pdcp-Config: rlc-AM absent; rlc-UM present (voice) headerCompression: rohc maxCID : 15 profiles: profile0x0001=true profile0x0002=false profile0x0004=false drb-ContinueROHC: not present logicalChannelIdentity : 4
FieldMeaningExample (from log)Check
eps-BearerIdentity / QCIWhich bearer this PDCP config applies to.6 (QCI=1)ROHC should be on the QCI=1 voice DRB, not the default data DRB.
headerCompressionThe CHOICE: rohc or notUsed.rohcIf notUsed on the voice DRB, no compression happens — full headers on air.
profile0x0001The RTP/UDP/IP (voice) profile enabled flag.trueMust be true for voice; without it the RTP layer is never compressed.
maxCIDMax parallel contexts the entity may track.15A couple suffices for voice; a wrong small value on a multi-flow bearer starves contexts.
drb-ContinueROHCOn handover, tells the UE to keep the existing context instead of resetting.not presentAbsent = context reset at target (full headers briefly); present = context preserved.

✅ Debugging steps

  • Confirm the RRCConnectionReconfiguration that set up the QCI=1 DRB carried headerCompression: rohc (not notUsed).
  • Verify profile 0x0001 is in the enabled profile list — it is the only RTP-aware (voice) profile.
  • Check maxCID is large enough for the flows on the bearer (small is fine for pure voice).
  • Confirm the ROHC ordering assumption holds: compression before ciphering (Tx), decompression after deciphering (Rx).

⚠ Common causes of failure

  • headerCompression left notUsed on the voice DRB, so full headers are sent and voice capacity crashes.
  • Profile 0x0001 not enabled (only 0x0002/0x0004), so the RTP layer stays uncompressed — little benefit for voice.
  • UE/network profile-set mismatch, so the compressor falls back to the uncompressed profile 0x0000.
  • maxCID too small on a multi-flow bearer, starving contexts and forcing repeated re-initialisation.

Compressor States, Context and Learning the Fields

The compressor cannot emit tiny headers from the very first packet, because the decompressor has no context yet — it does not know the IP addresses, the ports, or the SSRC of this new flow. So it works through three states, sending progressively less as it gains confidence the far end is in sync. (For the full state machine, the transition triggers and the decompressor side, see the general ROHC page; this is the short version for the VoLTE case.)

StateWhat it sends on the voice flowHeader size
IR stateInitialization & Refresh — the full static context (IP addresses, ports, SSRC) so the decompressor can build its context from scratch.Largest (full header + profile info)
FO stateFirst Order — updates to the dynamically changing fields once the static part is known (e.g. establishing the timestamp stride and any irregular changes).Medium
SO stateSecond Order — the steady state, where the header collapses to essentially just a few sequence-number bits and everything else is extrapolated.Smallest (≈ 1–3 B)

How does the compressor “learn” the pattern? It classifies each header field as static, static-known, or changing. Static fields (addresses, ports, SSRC, IP version) are sent once in the IR state and never again. Semi-static fields that change by a constant delta — the RTP sequence number (+1) and timestamp (+ a fixed stride) — are established in the FO state; once the decompressor knows the stride, the compressor stops sending the timestamp at all and lets the decompressor derive it from the sequence number. From then on the only thing that genuinely needs transmitting each packet is a few low-order bits of the sequence number, protected by a small CRC. That is the SO state.

For a steady VoLTE stream the SO state is where the win lives. A voice call is exactly the kind of long, regular flow ROHC was designed for: after the first handful of packets the compressor settles into SO state and stays there for the rest of the call, sending 1–3 byte headers 50 times a second. The CID (context identifier) tags which flow a compressed header belongs to, so a PDCP entity can track several contexts at once up to maxCID. The compressor also periodically drops back to IR state for a single packet to refresh the context — cheap insurance so that a decompressor which somehow lost sync recovers within a bounded time.

💡

Mental model: the first packet is a full letter with both addresses (IR state). The next few teach the recipient the rhythm (FO state). Every packet after that is a postcard that says “same as before, plus one” (SO state). VoLTE sends postcards for minutes on end — which is why ROHC pays off so spectacularly here.

Reading the ROHC context in the logs

PDCP ROHC statistics show whether the compressor reached and stayed in the SO state and whether the decompressor is rebuilding headers cleanly. A high compressed-header size, frequent IR refreshes, or rising decompression CRC failures all mean the context is not holding — the audible symptom is robotic or dropped audio.

Representative UE PDCP/ROHC statistics log — illustrative, values vary by vendor/build:

PDCP ROHC stats drb=2 cid=0 profile=0x0001 comp_state=SO pkts_IR=3 pkts_FO=6 pkts_SO=14921 avg_comp_hdr=3B decomp_mode=O-mode decomp_state=FULL_CONTEXT decomp_crc_ok=14930 decomp_crc_fail=2 context_invalidations=0 feedback_NACK=1
FieldMeaningExample (from log)Check
comp_stateCompressor state; SO is the steady, minimal-header state.SOIf it never reaches SO (stuck in IR/FO), no capacity gain — check feedback/loss.
avg_comp_hdrAverage compressed header size on the flow.3BShould be ~1–3 B in steady state; large values mean the flow keeps re-initialising.
decomp_stateDecompressor context state.FULL_CONTEXTNO_CONTEXT/STATIC_CONTEXT means it cannot rebuild headers — packets discarded.
decomp_crc_failReconstructed headers that failed the ROHC CRC.2A rising count = context desync; correlate with radio loss and audio glitches.
context_invalidationsTimes the context had to be thrown away and relearned.0Spikes here (e.g. after handover) explain brief full-header bursts and audio gaps.

✅ Debugging steps

  • Confirm the compressor reached SO state and the average compressed header is ~1–3 B, not tens of bytes.
  • Check the decompressor is in FULL_CONTEXT; NO_CONTEXT/STATIC_CONTEXT means it is discarding packets.
  • Watch decomp_crc_fail and context_invalidations — rising values point at context desync (usually radio loss or a mobility event).
  • Correlate NACK feedback and IR refreshes with audio glitches to confirm ROHC is the cause rather than plain packet loss.

⚠ Common causes of failure

  • Excessive radio loss desynchronising the context faster than IR refreshes can recover it (robotic audio).
  • Decompressor stuck in NO_CONTEXT after a burst of loss, discarding voice packets until the next IR.
  • Context reset at handover without drb-ContinueROHC, causing a full-header burst and a short audio gap.
  • Feedback path problems in O-/R-mode, so the compressor is never told to refresh a lost context promptly.

The AMR / AMR-WB Codec and 20 ms Packetization

To see why the payload is so small — and so steady — you have to look at the codec. VoLTE uses the AMR family: narrowband AMR (8 kHz sampling, 8 bit-rate modes from 4.75 to 12.2 kbit/s) and wideband AMR-WB (16 kHz sampling, 9 modes from 6.60 to 23.85 kbit/s). TS 26.114 defines how these are carried over RTP for IMS telephony. Both codecs produce one compressed speech frame per 20 ms of audio, and that fixed 20 ms cadence is precisely what makes the RTP timestamp advance by a constant stride — the regularity ROHC feeds on.

ParameterAMR (narrowband)AMR-WB (wideband)
Sampling rate8 kHz16 kHz
Codec modes (bit rates)4.75–12.2 kbit/s (8 modes)6.60–23.85 kbit/s (9 modes)
Frame duration20 ms20 ms
Samples per frame160320
Packet rate50 frames/s50 frames/s
Speech payload (typical mode)≈ 31 B @ 12.2 kbit/s≈ 32 B @ 12.65 kbit/s
RTP timestamp stride+160 per frame+320 per frame

The codec can switch modes packet-to-packet (adaptive multi-rate: the network can request a lower rate under congestion or poor radio), so the speech payload size varies a little across the call — but the header structure does not, which is all ROHC cares about. Two related features also shape the traffic. Discontinuous transmission (DTX) stops sending full speech frames during silence and instead sends tiny SID (silence descriptor) comfort-noise frames roughly every 160 ms, cutting the packet rate during pauses. And the RTP payload can carry more than one 20 ms frame per packet (frame bundling), trading a little latency for fewer packets — though standard VoLTE keeps one frame per packet for lowest delay.

The key point for this page: a 20 ms frame at a typical wideband mode is about 32 bytes. That is the number the RTP/UDP/IP header must be measured against — and against 32 bytes, a 60-byte IPv6 header is catastrophic overhead. ROHC exists to make that ratio sane.

Robustness Modes and the LTE Voice Bearer

ROHC can run in three modes, which differ in how the decompressor confirms the context back to the compressor:

ModeFeedbackCharacter
U-mode (Unidirectional)NoneCompressor advances optimistically and refreshes periodically; used when no return path is assumed. ROHC always starts here.
O-mode (Bidirectional Optimistic)Occasional (NACK on error)Feedback mainly to recover from errors — a common choice on the LTE voice bearer, balancing low feedback traffic with fast recovery.
R-mode (Bidirectional Reliable)Frequent (ACK/NACK)Most conservative; every context-changing update is acknowledged. Lowest risk of loss of sync, most feedback traffic.

The “R” in ROHC is the point that matters for the radio link. The LTE air interface loses packets, and a scheme that broke every time a compressed header went missing would be useless for voice. ROHC tolerates loss in two ways: it encodes the sequence number in a window (W-LSB) so a few lost packets do not desynchronise the context, and the compressor periodically refreshes the full context via the IR state so a decompressor that lost sync recovers on the next refresh. In the bidirectional modes the decompressor can also NACK to pull the compressor back immediately. Robust does not mean it never loses sync — it means one lost packet cannot poison the whole flow, and recovery is bounded.

Two lower-layer choices work alongside ROHC to make the shrunken voice packet survive the radio. First, VoLTE maps its DRB to RLC Unacknowledged Mode (RLC-UM) rather than Acknowledged Mode. Voice is delay-sensitive and self-obsoleting — a retransmitted speech frame that arrives late is useless — so RLC does not retransmit; it just delivers in order and drops what is lost, which is exactly what a codec with error concealment wants. Second, at the cell edge the network can enable TTI bundling, where the same transport block is transmitted across several consecutive subframes (typically 4) to accumulate energy and improve the chance of decoding without waiting for HARQ round trips. TTI bundling is only worthwhile because ROHC has already made the transport block small — a compact block is what fits into a bundled, low-MCS grant at the edge of coverage.

⚠️

Handover caveat: ROHC context lives in the PDCP entity. On PDCP re-establishment (e.g. an X2 or S1 handover) the target starts with no context, so the compressor must run a fresh IR state phase again — which is why the first voice packets after a mobility event briefly carry full headers before collapsing back to the SO state.

✅ Debugging steps

  • Confirm which robustness mode is in use (typically O-mode on the LTE voice bearer) and that the feedback path is working.
  • After a handover, check whether the compressor re-ran IR and how quickly it settled back to SO state (and whether drb-ContinueROHC preserved the context).
  • Verify the voice DRB is on RLC-UM (not AM) so late frames are dropped rather than retransmitted.
  • At the cell edge, check whether TTI bundling is active and that the compressed transport block fits the bundled low-MCS grant.

⚠ Common causes of failure

  • Broken feedback path in O-/R-mode, so a lost context is not repaired until the next periodic IR refresh (audible gap).
  • Context loss at every handover (no drb-ContinueROHC), producing repeated full-header bursts on a mobile user.
  • Voice DRB wrongly on RLC-AM, adding retransmission delay that makes late speech frames useless.
  • TTI bundling misconfigured or unavailable at the edge, so the (already small) voice block still fails to decode.

Why It Matters for VoLTE Capacity and Coverage

Put the numbers side by side. Take an AMR-WB frame of 32 bytes at codec mode 12.65 kbit/s over IPv6:

One VoLTE packet — before vs after ROHC (IPv6, AMR-WB 32 B) Before IP 40 B UDP 8 RTP 12 AMR-WB 32 B header = 60 B payload = 32 B total ≈ 92 B ROHC profile 0x0001, SO state After hdr 3 B AMR-WB 32 B total ≈ 35 B ≈ 62% fewer bytes on air → more voice users per cell same speech, roughly a third of the bytes on the air interface
Figure 1. Before ROHC, a 60-byte header dwarfs the 32-byte AMR-WB frame (≈ 92 B total). In the SO state, the header collapses to ≈ 3 B (≈ 35 B total) — the same speech in roughly a third of the bytes.
Uncompressed: 60 B header + 32 B AMR-WB ≈ 92 B   →   ROHC SO: ≈ 3 B header + 32 B AMR-WB ≈ 35 B

That saving turns directly into VoLTE gains on the QCI=1 GBR voice DRB:

  • Cell voice capacity. Far fewer air-interface bytes per packet means many more simultaneous voice users share the same spectrum — the single biggest reason ROHC is used in practice for VoLTE. Halving the transport block size roughly doubles the number of concurrent calls a scheduler can fit.
  • Coverage and robustness. A smaller transport block can be sent at a lower code rate / lower MCS, or fits in fewer PRBs, so it is more likely to be decoded at the cell edge — better voice coverage, and it is what makes TTI bundling and RLC-UM effective.
  • Efficiency with SPS. VoLTE uses semi-persistent scheduling to avoid per-packet PDCCH signalling; shrinking the packet lets that periodic grant be smaller too, freeing control and data resources for other users.
🎯

Bottom line: ROHC plus a small semi-persistent grant is what lets an LTE cell carry hundreds of concurrent VoLTE calls instead of a handful. It is the difference between voice being an afterthought on the data network and voice being a first-class, spectrally efficient service.

🔀

LTE ↔ NR: ROHC carries straight over to 5G. In NR it is still a PDCP function, but defined in TS 38.323 rather than TS 36.323, and configured in the NR PDCP-Config (headerCompressionrohc with the same IETF profile numbers, profile 0x0001 for VoNR voice). NR PDCP adds an uplink data compression (UDC) option for data bearers that LTE lacks, and the voice bearer is identified by the 5QI value (5QI=1 for conversational voice) instead of QCI=1. The mechanics — IR/FO/SO states, W-LSB, per-DRB enablement, context loss on handover — are unchanged, so VoNR benefits from ROHC for exactly the same reasons VoLTE does.

Summary

ROHC exists because the RTP/UDP/IP header on a VoLTE packet (40 B IPv4, 60 B IPv6) is as big as or bigger than the ~32-byte AMR/AMR-WB speech frame, and it repeats 50 times a second. As a PDCP function (TS 36.323) it runs a compressor/decompressor pair with a synchronised context, enabled per DRB by RRC via headerCompression: rohc with profile 0x0001 on the QCI=1 voice bearer, and after a short IR/FO warm-up it settles into the SO state where headers collapse to 1–3 bytes. That is what multiplies VoLTE cell capacity and improves cell-edge coverage.

To debug it, follow the state, not just the packet. First confirm ROHC was even negotiated onto the voice DRB (profile 0x0001, not notUsed). Then confirm the compressor reached SO state with a ~1–3 B average header and the decompressor is in FULL_CONTEXT. Robotic audio, gaps after handover, and rising decomp_crc_fail/context_invalidations all point at context desync — usually radio loss, a mobility event that reset the context without drb-ContinueROHC, or a broken feedback path. ROHC works hand in hand with RLC-UM, TTI bundling, and SPS to make the shrunken voice packet survive and scale on the air interface.

Q&A Interview quickfire

Q. Why is ROHC essential for VoLTE but not for a big file download?

A. It is about the header-to-payload ratio. A VoLTE AMR/AMR-WB frame is only ~32 bytes but its RTP/UDP/IP header is 40–60 bytes, so the header can exceed the payload and it repeats 50 times a second. Compressing it to ~3 bytes roughly doubles the useful payload ratio and multiplies cell voice capacity. A file download has a ~1500-byte payload, so a 40-byte header is negligible — there is nothing worth compressing, and the network usually leaves ROHC off on that DRB.

Q. Which ROHC profile does VoLTE use, and where is it enabled?

A. Profile 0x0001 (RTP/UDP/IP) — the RTP-aware profile. It is enabled per DRB by RRC in PDCP-Config, via headerCompression set to rohc with the profile list and maxCID, on the QCI=1 GBR voice bearer. Profiles 0x0002 (UDP/IP) and 0x0004 (IP) exist but are not the voice media profile because they leave the RTP layer uncompressed.

Q. Where in the PDCP chain does ROHC run, and what state gives the big gain?

A. It is a PDCP function (TS 36.323), running as compressor/decompressor inside the PDCP entity, applied before ciphering on transmit (and after deciphering on receive). The saving comes in the SO state: after the initial IR state and FO state establish the context, the steady voice stream sits in SO state sending 1–3 byte headers.

Q. Why does the AMR codec's 20 ms framing help ROHC so much?

A. A fixed 20 ms frame means the RTP timestamp advances by a constant stride every packet (+160 for AMR, +320 for AMR-WB) and the sequence number increments by one. Those constant deltas are exactly what the 0x0001 profile extrapolates, so in the SO state the timestamp need not be sent at all — only a few sequence-number bits remain.

Q. How do RLC-UM and TTI bundling relate to ROHC on the voice bearer?

A. VoLTE runs the voice DRB in RLC-UM (no retransmission — a late speech frame is useless) and can use TTI bundling at the cell edge (repeat the transport block over consecutive subframes for coverage). Both are practical only because ROHC has already shrunk the header, keeping the transport block small enough to fit a low-MCS, bundled grant.

Q. What happens to ROHC compression across a handover?

A. The context lives in the PDCP entity, and PDCP is re-established at the target on X2/S1 handover, so the target has no context. The compressor must run a fresh IR state phase, so the first packets after handover carry full headers before collapsing back to the SO state — unless drb-ContinueROHC is signalled to preserve the context.

Where this connects

ROHC on the voice bearer is one piece of the VoLTE picture — it sits inside PDCP, feeds the semi-persistently-scheduled QCI=1 voice DRB, and builds on the general header-compression machinery covered elsewhere.