CHAPTER ONE

Why random access exists at all

Picture the moment your phone wakes up in a new city. It has read the synchronisation signal block, decoded the MIB and SIB1, and it now knows everything about the cell except one thing the cell does not yet know about it: timing. The UE has no uplink timing advance, no dedicated resources, no identity the scheduler recognises. It is, from the gNB's point of view, an anonymous transmitter sitting somewhere between zero and tens of kilometres away. Every other uplink channel in 5G NR — PUSCH, PUCCH, SRS — assumes the UE is already time-aligned to within a fraction of a cyclic prefix. Random access is the one procedure that does not assume that. It is the bootstrap.

The random access procedure solves four problems in one shot. It lets an uncoordinated UE announce its presence; it lets the gNB measure the round-trip delay and hand back a timing advance so the UE's later transmissions land inside the cyclic prefix; it hands the UE a first uplink grant so it can say who it is; and — because many UEs may try at once — it resolves contention so exactly one of them keeps the grant. Strip away the acronyms and RACH is just a politely structured shouting match: everyone who wants in shouts a code, the gNB shouts back “I heard code 37, here is when and where to talk,” and a final exchange settles who code 37 actually belonged to.

The analogy

RACH is a busy reception desk with no appointments. Walk-ins (UEs) each say a numbered ticket phrase out loud (the preamble). The receptionist (gNB) calls back a ticket number with a time slot and a desk (the RAR grant). If two people happened to say the same ticket phrase at the same instant, only one will match the name written down at the desk — the other has to take a fresh ticket and try again. That last step is contention resolution.

Getting RACH right matters more than its airtime suggests. It is the gate every connection passes through: an idle-to-connected transition, a handover, a beam-failure recovery, an uplink that has gone out of sync — all of them run random access first. If RACH is mis-tuned, the symptom is not “slow RACH,” it is accessibility failures, dropped handovers and coverage holes that look like everything-else problems. That is why this article spends as much time on the counters and the optimization as on the message flow.

Where this lives in 3GPP. The procedure itself is in TS 38.321 (MAC) §5.1. The preamble waveform, formats and PRACH mapping are in TS 38.211 §6.3.3. The power control, RA-RNTI and timing rules are in TS 38.213 §7 and §8. The IEs you configure (RACH-ConfigCommon, RACH-ConfigGeneric, RACH-ConfigCommonTwoStepRA) are in TS 38.331. Keep those four open and you can trace any RACH question to its source.

CHAPTER TWO

The RACH map — triggers, CBRA vs CFRA, 4-step vs 2-step

Before the message-by-message walk-through, fix the taxonomy in your head, because half of all RACH confusion is people talking about different variants without saying so. Random access in NR is classified along two independent axes.

Axis 1 — contention-based (CBRA) vs contention-free (CFRA)

In contention-based random access the UE picks its preamble at random from a shared pool, so two UEs can collide and a contention-resolution step is mandatory. In contention-free random access the network has already handed this specific UE a dedicated preamble (via rach-ConfigDedicated in an RRC Reconfiguration, or a PDCCH order) — nobody else will use it, so there is no collision and no Msg4 contention step. CFRA is what handover and beam-failure recovery use, because the target already knows the UE is coming and wants the fastest, most reliable access possible.

Axis 2 — 4-step vs 2-step

This is the axis that defines the message count. 4-step is the classic Msg1–Msg2–Msg3–Msg4 flow. 2-step (introduced in Release 16) folds Msg1+Msg3 into a single MsgA and Msg2+Msg4 into a single MsgB. The two axes combine: you can have 4-step CBRA, 4-step CFRA, 2-step CBRA and 2-step CFRA. The table below is the whole solution space.

VariantPreambleMessagesContention step?Typical trigger
4-step CBRArandom, from shared poolMsg1·2·3·4Yes (Msg4)Initial access from idle, RRC re-establishment, UL data with no SR/PUCCH
4-step CFRAdedicatedMsg1·2 (no 3/4)NoHandover, beam-failure recovery, PDCCH-ordered RA
2-step CBRArandom, from shared poolMsgA·MsgBWithin MsgB (successRAR)Small cells, NR-U, low-latency / small-data access
2-step CFRAdedicatedMsgA·MsgBNoHandover in good coverage (FR2), latency-critical

Before going deeper, watch the whole 4-step handshake play out once. The diagram below animates the four messages in order — uplink shots from the UE in amber, downlink answers from the gNB in violet — so the sequence and direction of every message is unmistakable.

The 4-step handshake, message by message UE gNB ① Msg1 · PRACH preamble (1 of 64) ② Msg2 · RAR — RA-RNTI, TA, UL grant ③ Msg3 · identity (RRCSetupRequest / C-RNTI) ④ Msg4 · contention resolution → RRC_CONNECTED
One full contention-based access — Msg1 up, Msg2 down, Msg3 up, Msg4 down — looping so you can follow the rhythm.

The seven things that trigger random access

TS 38.321 §5.1.1 lists the events that kick off the procedure. Worth memorising, because the trigger changes what the UE puts in Msg3 and whether CFRA is even possible:

  1. Initial access from RRC_IDLE — the cold start; Msg3 carries RRCSetupRequest.
  2. RRC re-establishment after radio-link failure — Msg3 carries RRCReestablishmentRequest.
  3. Handover — the target cell usually pre-assigns a dedicated preamble (CFRA).
  4. DL data arrival while uplink is “non-synchronised” — the gNB sends a PDCCH order to make the UE do RACH and regain timing.
  5. UL data arrival while non-synchronised, or when no PUCCH scheduling-request resource is configured.
  6. SR failure — scheduling requests went unanswered up to the configured maximum.
  7. Beam failure recovery — the serving beam died; RACH (often CFRA on a recovery preamble) requests a new one.
  8. (Rel-16+) Request for Other SI, transition out of RRC_INACTIVE, and timing-advance re-acquisition.

The mental model that never fails you. 4-step is “knock, get told where to sit, introduce yourself, get acknowledged.” 2-step is “knock-and-introduce-yourself in the same breath, then get acknowledged.” CFRA is “you were expected, your seat has your name on it.” Everything below is just the engineering of those three sentences.

CHAPTER THREE

Msg1 part 1 — the preamble: Zadoff–Chu, roots and Ncs

Msg1 is a single preamble transmitted on PRACH. The preamble is not data — it carries exactly log2(64) = 6 bits of information: which of 64 preambles the UE chose. Everything clever about Msg1 is in the waveform, because that waveform has to be detectable by a receiver that does not yet know the UE's timing, at SNRs where ordinary data would be undecodable.

Why Zadoff–Chu

NR preambles are Zadoff–Chu (ZC) sequences. A root ZC sequence of odd length L is defined as:

Root Zadoff–Chu sequence · TS 38.211 §6.3.3.1 xu(n) = exp( −j · π · u · n · (n+1) / LRA ),   n = 0,1,…,LRA−1
u = physical root index, LRA = 839 (long preambles) or 139 (short preambles). Both are prime, which is what makes every non-zero cyclic shift orthogonal.

ZC sequences have two magical properties for this job. First, constant amplitude — the time-domain signal has a low peak-to-average power ratio, so the UE's power amplifier can drive it hard at the cell edge. Second, perfect (zero) cyclic autocorrelation — a ZC sequence correlated against a cyclically shifted copy of itself produces a sharp single peak at exactly the shift offset. That is the entire detection trick: the gNB correlates the received signal against each root, and the position of the correlation peak tells it both which preamble and how late it arrived — i.e. the round-trip delay it will turn into a timing advance.

From one root to 64 preambles — cyclic shifts and Ncs

A cell needs exactly 64 preambles. Rather than use 64 different roots (which correlate imperfectly against each other), NR generates many preambles from a single root by applying cyclic shifts. Each shift is a multiple of Ncs, the “zero-correlation zone” spacing:

Cyclic-shifted preamble xu,v(n) = xu( (n + Cv) mod LRA ),   Cv = v · Ncs
Number of preambles obtainable from one root = ⌊ LRA / Ncs ⌋. If that is < 64, the cell uses additional consecutive roots until 64 preambles are assembled.

Ncs is the single most physically meaningful PRACH parameter you will tune, because it encodes the cell radius. The zero-correlation zone must be wider than the largest round-trip delay you expect, plus delay spread, or two UEs at different distances using shifts of the same root will alias onto each other's correlation windows. Bigger cell → bigger required Ncs → fewer shifts per root → more roots consumed per cell. You set Ncs indirectly through zeroCorrelationZoneConfig (values 0–15), which indexes a table in TS 38.211 (the table chosen depends on preamble format and restricted-set type).

Worked example — how many roots does a 5 km cell need?
Long format, LRA = 839, SCS 1.25 kHz → one ZC sample ≈ 0.93 µs.
Round trip for 5 km ≈ 33.4 µs → ≈ 36 samples; add delay spread & guard → Ncs ≈ 46 (a typical table entry).
Shifts per root = ⌊839 / 46⌋ = 18 preambles.
Roots needed for 64 preambles = ⌈64 / 18⌉ = 4 logical roots.
A 5 km cell consumes ~4 root sequences. Plan neighbours so their root sets do not overlap — this is “PRACH root planning,” the RACH equivalent of PCI planning.

Here is why the zero-correlation property matters in practice. When the gNB correlates the received signal against a root sequence, the output is flat noise except at one sharp peak — and the position of that peak is the round-trip delay, which becomes the timing-advance command. Watch the detector sweep and lock onto it:

PRACH detection — the Zadoff–Chu correlation peak correlation cyclic-shift / delay → detected! τ (round-trip delay) → TA
The peak's position is the propagation delay — that is how Msg1 alone lets the gNB compute the timing-advance command in Msg2.

Restricted sets — the high-speed problem

At high Doppler (think a UE on a 350 km/h train) the frequency offset rotates the ZC correlation peak into a spurious secondary peak, which the receiver can mistake for a different shift — a false alarm or a wrong timing estimate. NR fixes this with restricted sets: restrictedSetConfig = unrestricted, restrictedSetTypeA or restrictedSetTypeB. Restricted sets blacklist the cyclic shifts that would alias under Doppler, at the cost of fewer usable shifts per root. Use unrestricted for normal cells; switch to Type A/B only on genuinely high-speed cells (rail, highway), and expect to consume more roots.

Preamble formats — long vs short

The format sets the subcarrier spacing, the sequence length, how many times the ZC sequence repeats, and the cyclic-prefix length — which together fix the maximum cell radius and the robustness. There are two families.

Long preambles (LRA = 839, FR1 only)

FormatSCSZC repetitionsMax cell radius (approx.)Use
01.25 kHz1≈ 14.5 kmDefault macro
11.25 kHz2 (long CP)≈ 100 kmVery large / rural macro
21.25 kHz4≈ 22 kmCoverage-limited (repetition gain)
35 kHz4≈ 14.5 kmHigh-speed (wider SCS tolerates Doppler)

Short preambles (LRA = 139, FR1 & FR2)

Short formats use the same subcarrier spacing as data (15/30 kHz in FR1, 60/120 kHz in FR2, plus 480/960 kHz for FR2-2), so the PRACH slot lines up neatly with the data numerology and the gNB receiver is simpler. They come in two sub-families: A-formats (A1/A2/A3) have a cyclic prefix sized for back-to-back occasions, and B-formats (B1–B4) use a shorter CP for tighter packing. The number after the letter is the count of ZC repetitions: more repetitions → more coverage, fewer occasions per slot. Format B4 (12 symbols) is the most robust short format and is common in FR2 cell-edge configurations; C0/C2 are the long-CP short formats for larger short-preamble cells.

Format selection is a coverage decision, not a default. Pick the shortest format that still closes the uplink link budget at your cell edge. Over-provisioning (e.g. Format 1 or B4 everywhere) wastes PRACH airtime and reduces the number of RACH occasions, which raises collision probability under load — you trade a coverage problem for an accessibility problem.

CHAPTER FOUR

PRACH configuration & RACH occasions — the SSB→RO map

A UE cannot transmit a preamble whenever it likes. PRACH is confined to specific time-frequency RACH occasions (ROs), and those ROs are mapped to SSB beams so that a preamble in a given RO tells the gNB which downlink beam the UE prefers. This mapping is the heart of beam-based access and the part engineers most often get subtly wrong.

The time domain — prach-ConfigurationIndex

One number, prach-ConfigurationIndex (0–255), selects a row of TS 38.211 Table 6.3.3.2 that fixes the preamble format, in which system frames PRACH appears (the PRACH configuration period — every frame, every other frame, etc.), the subframe/slot numbers, the starting symbol, the number of PRACH slots within a 60 kHz slot, and the number of time-domain ROs per PRACH slot. Choosing this index sets how often RACH opportunities recur — the lever for RACH capacity in the time domain.

The frequency domain — msg1-FDM and msg1-FrequencyStart

msg1-FDM (one/two/four/eight) sets how many ROs sit side by side in frequency in the same time instant — multiplying RACH capacity. msg1-FrequencyStart places the PRACH frequency block as an offset from the bottom of the initial uplink BWP. Together they decide the PRACH frequency footprint inside the carrier.

The SSB→RO mapping — ssb-perRACH-OccasionAndCB-PreamblesPerSSB

This single IE does two jobs at once. Its first part says how many SSBs map to each RACH occasion — values from oneEighth (one SSB spreads over 8 ROs, used when you have many beams) up to sixteen (16 SSBs share one RO). Its second part says how many contention-based preambles per SSB are carved out of the 64. The UE first measures the SSBs, picks the strongest one above rsrp-ThresholdSSB, finds the RO(s) that SSB maps to, and only then chooses a preamble. That is how a contention-based preamble still carries beam information.

SSB → RACH-Occasion mapping (example: 1 SSB per RO, 4 beams) SSB #0 (beam 0) SSB #1 (beam 1) SSB #2 (beam 2) SSB #3 (beam 3) RO 0 · 64 preambles RO 1 · 64 preambles RO 2 · 64 preambles RO 3 · 64 preambles gNB infers preamble in RO 2 → UE wants beam 2 → RAR on beam 2
The RO a preamble lands in tells the gNB which SSB beam to answer on — beam-correspondent access.
Parameter (TS 38.331)Range / valuesWhat it controls
prach-ConfigurationIndex0–255Format + time-domain RO pattern (frame/slot/symbol)
msg1-FDMone, two, four, eightFrequency-multiplexed ROs per time instant
msg1-FrequencyStart0–(NBWP−1) PRBPRACH frequency offset in the UL BWP
zeroCorrelationZoneConfig0–15Ncs → cyclic-shift spacing → cell radius
restrictedSetConfigunrestricted / A / BHigh-speed (Doppler) shift restriction
ssb-perRACH-OccasionAndCB-PreamblesPerSSBoneEighth…sixteen + NSSB→RO ratio & CB preambles per SSB
prach-RootSequenceIndex0–837 (L=839) / 0–137 (L=139)Logical root the cell starts from
rsrp-ThresholdSSBRSRP levelMin SSB quality the UE will RACH against
Premium interactive lab

Build a PRACH configuration and watch it light up

Drag prach-ConfigurationIndex, msg1-FDM and Ncs and see the RACH occasions, SSB→RO mapping and per-cell preamble budget redraw in real time — on the same engine that powers this article's diagrams. Lifetime access — ₹999 / $9.99.

Open the 4-step RACH lab
CHAPTER FIVE

Msg1 part 2 — preamble selection & power ramping

With the configuration understood, here is exactly what the UE's MAC does the instant random access is triggered, step by step from TS 38.321 §5.1.2–5.1.3.

  1. Select an SSB. Measure all SSBs; pick one whose RSRP exceeds rsrp-ThresholdSSB. If none qualifies, pick any SSB (the UE still has to try).
  2. Select a preamble group. For CBRA, the 64 preambles may be split into Group A and Group B. The UE chooses Group B if its Msg3 will be large and its path loss is low enough (controlled by ra-Msg3SizeGroupA, messagePowerOffsetGroupB, numberOfRA-PreamblesGroupA). This lets the gNB infer the Msg3 size from the preamble group and grant accordingly.
  3. Select a preamble at random from the chosen group mapped to the chosen SSB. For CFRA, use the assigned dedicated preamble — no randomness.
  4. Determine the RACH occasion that the selected SSB maps to.
  5. Set the transmit power (below) and transmit.

Open-loop power and the ramping ladder

The UE has never heard back from this cell, so it cannot do closed-loop power control. It estimates path loss from the SSB it just measured and aims for a target received power the gNB published:

PRACH target & transmit power · TS 38.213 §7.4 PREAMBLE_RECEIVED_TARGET_POWER = preambleReceivedTargetPower + DELTA_PREAMBLE + (PREAMBLE_POWER_RAMPING_COUNTER − 1) × powerRampingStep
PPRACH = min( PCMAX,  PREAMBLE_RECEIVED_TARGET_POWER + PL )
PL = path loss estimated from the selected SSB's RSRP. DELTA_PREAMBLE depends on the preamble format (TS 38.213 Table 7.3-1). PCMAX = UE's configured maximum output power.

If the attempt fails — no matching RAR inside ra-ResponseWindow, or contention not resolved — the UE increments PREAMBLE_POWER_RAMPING_COUNTER and retransmits a fraction of a dB louder. It keeps climbing this ladder until it succeeds or hits preambleTransMax attempts, at which point the MAC reports a random-access problem to RRC (which, for initial access, means the cell selection failed and the UE looks elsewhere).

The counter does not ramp when you switch beams. If the UE re-selects a different SSB between attempts (because the first beam faded), PREAMBLE_POWER_RAMPING_COUNTER is held, not incremented — otherwise the open-loop estimate for the new beam would be polluted by ramping done against the old one. This subtlety is why naïve “average preamble attempts” counters can mislead in beamformed cells.

Preamble power ramping ladder Tx power attempt # (counter) 1 2 3 4 5 ↑ +powerRampingStep each retry stop at preambleTransMax → report to RRC
Each failed attempt steps the target up by powerRampingStep (0/2/4/6 dB) until success or preambleTransMax.
Power / retry parameterTypical rangeEngineering effect
preambleReceivedTargetPower−202…−60 dBm (step 2), e.g. −110Target Rx power at gNB; too low → Msg2 misses, too high → UL interference
powerRampingStep0, 2, 4, 6 dBHow fast the UE climbs; bigger = faster access, more interference overshoot
preambleTransMaxn3,n4,n5,n6,n7,n8,n10,n20,n50,n100,n200Max attempts before declaring failure
ra-ResponseWindowsl1…sl80 (slots)How long the UE waits for Msg2; too short → false Msg2 failures
ra-ContentionResolutionTimersf8…sf64 (subframes)How long the UE waits for Msg4 before declaring contention lost
CHAPTER SIX

Msg2 — RA-RNTI and the 27-bit RAR grant

The gNB detected a preamble. Now it answers with the Random Access Response. Msg2 is a PDSCH transmission scheduled by a PDCCH whose CRC is scrambled with a special identity the UE can compute on its own: the RA-RNTI. This is elegant — the UE doesn't have an identity yet, so the network derives a temporary one purely from when and where the preamble was sent.

RA-RNTI · TS 38.321 §5.1.3 RA-RNTI = 1 + s_id + 14 × t_id + 14 × 80 × f_id + 14 × 80 × 8 × ul_carrier_id
s_id = first OFDM symbol of the PRACH occasion (0–13); t_id = first slot of the PRACH occasion in the frame (0–79); f_id = frequency index of the PRACH occasion (0–7); ul_carrier_id = 0 for NUL, 1 for SUL.
Worked example — compute an RA-RNTI
Preamble sent in: symbol s_id = 0, slot t_id = 9, freq index f_id = 0, normal UL (ul_carrier_id = 0).
RA-RNTI = 1 + 0 + 14×9 + 0 + 0 = 1 + 126 = 127.
RA-RNTI = 127 — the UE blind-decodes PDCCH for exactly this RNTI inside ra-ResponseWindow.

The UE only listens for a PDCCH scrambled with its RA-RNTI, during ra-ResponseWindow, starting a fixed offset after the preamble. When it finds one, it reads the RAR PDSCH. A RAR PDSCH can contain multiple RAR subPDUs — one per preamble the gNB heard in that occasion — each tagged with a RAPID (Random Access Preamble Identifier). The UE scans for the RAPID matching the preamble it sent. Match found → this RAR is for me. No match → keep waiting, or fail the window.

Inside one RAR subPDU

MAC RAR subPDU layout (TS 38.321 §6.2.3) R1 bit Timing Advance Cmd12 bits UL Grant27 bits → schedules Msg3 TC-RNTI16 bits UL Grant = freq-hop flag(1) + PUSCH freq RA(14) + time RA(4) + MCS(4) + TPC(3) + CSI req(1)
The RAR hands the UE timing, a Msg3 grant, and a temporary identity (TC-RNTI) all in one.

Three fields do the real work. The Timing Advance Command (12 bits) tells the UE how much to advance its uplink clock so Msg3 lands inside the gNB's receive window. The UL Grant (27 bits) schedules Msg3 on PUSCH — frequency-hopping flag, frequency and time allocation, modulation/coding, a power-control command and a CSI-request bit. The TC-RNTI (Temporary C-RNTI, 16 bits) is the identity the UE will use for Msg3 and until contention resolution promotes it (or not) to a real C-RNTI.

For CFRA, this is the finish line. Because a contention-free UE used a dedicated preamble, a matching RAR means the access succeeded — there is no Msg3/Msg4. That is why handover and beam-failure recovery feel instant: they are two-message procedures (Msg1+Msg2) with a pre-known identity.

CHAPTER SEVEN

Msg3 — the first scheduled uplink & the UE identity

Msg3 is the first time the UE transmits scheduled data on PUSCH using the grant from the RAR — and now timing-aligned, so it actually lands cleanly. Its job is to carry the UE's identity so the network can finish the handshake. What it carries depends on why RACH was triggered:

TriggerMsg3 payload (CCCH/DCCH)Identity mechanism
Initial access (idle→connected)RRCSetupRequest (CCCH SDU)48-bit CCCH SDU echoed back in Msg4
RRC re-establishmentRRCReestablishmentRequestCCCH SDU echoed in Msg4
RRC resume (from INACTIVE)RRCResumeRequestresume identity + CCCH echo
Connected UE (already has C-RNTI)C-RNTI MAC CEPDCCH to C-RNTI resolves contention

Msg3 is HARQ-protected. If it isn't decoded, the gNB schedules a retransmission with a DCI format 0_0 addressed to the TC-RNTI, and the UE combines retransmissions. Msg3 can also use frequency hopping (the hop flag in the RAR grant) to get a diversity gain on this critical, low-SINR transmission. Because Msg3 is the cell-edge UE's hardest uplink, its reliability is often the real bottleneck of accessibility — not Msg1.

“Operators chasing accessibility almost always blame Msg1 coverage. Pull the per-step counters and the truth is usually Msg3: the preamble got through, the RAR was sent, and then the cell-edge PUSCH collapsed.”

— a pattern you will see again and again in RACH KPIs
CHAPTER EIGHT

Msg4 — contention resolution

Here is the problem Msg4 exists to solve. In CBRA, several UEs can pick the same preamble in the same RACH occasion. The gNB hears one preamble, sends one RAR, and now multiple UEs all think the grant is theirs. They all transmit Msg3 on the same PUSCH resource — usually one survives the collision and is decoded. Contention resolution is how the network tells the colliding UEs which one won.

Two mechanisms, depending on what Msg3 carried:

Contention: two UEs, one preamble UE-A UE-B gNB Msg1: preamble 37 Msg1: preamble 37 one RAR (RAPID 37) Msg4 echoes UE-A's 48-bit CCCH ID UE-A: match → WIN (RRCSetup) UE-B: no match → timer expiry → retry
The loser's ra-ContentionResolutionTimer expires; it ramps power and starts a fresh attempt.

The ra-ContentionResolutionTimer starts when Msg3 is transmitted. If the UE doesn't get a matching PDCCH (C-RNTI case) or a matching identity (CCCH case) before it expires, the attempt failed: the UE flushes the HARQ buffer for Msg3, increments the preamble counter, backs off a random time (ra-msg3-Backoff / the Backoff Indicator the gNB may send in Msg2), and starts again from preamble selection. The Backoff Indicator is the network's load-shedding valve: under congestion the gNB tells UEs to wait longer before retrying, spreading the load.

When contention is resolved on an initial access, Msg4 also carries the RRCSetup that promotes the UE into RRC_CONNECTED, and the TC-RNTI is promoted to the UE's C-RNTI. The bootstrap is complete: from anonymous transmitter to fully scheduled, time-aligned connection in four messages.

CHAPTER NINE

2-step RACH — MsgA, MsgB and fallback

Every round trip in 4-step costs latency — and in unlicensed spectrum (NR-U), every round trip also costs a fresh listen-before-talk gamble. Release 16 introduced 2-step RACH to cut the four messages to two. The idea is bold: send the preamble and the payload that would have been Msg3 together, before you have any timing advance at all.

MsgA = preamble + PUSCH payload

MsgA has two parts transmitted close together: a PRACH preamble (exactly like Msg1, drawn from a 2-step preamble pool) followed by a PUSCH payload that carries what Msg3 would have carried (e.g. the RRCSetupRequest CCCH SDU, or a C-RNTI MAC CE). The PUSCH part rides on a pre-configured resource called the MsgA PUSCH Occasion, associated with the preamble the UE chose. Because there is no timing advance yet, the MsgA PUSCH uses a generous guard period and is dimensioned for the cell's expected delay spread.

MsgB = successRAR or fallbackRAR

The gNB's response, MsgB, is scrambled with the MSGB-RNTI (computed like RA-RNTI but offset into a separate range so 2-step and 4-step responses never alias). MsgB can be one of two things:

2-step RACH with fallback UE gNB MsgA = preamble + PUSCH payload MsgB successRAR → DONE (1 RTT) MsgB fallbackRAR → send Msg3 (→ 4-step) MSGB-RNTI on the response · msgB-ResponseWindow bounds the wait
Best case: one round trip. Worst case: gracefully degrades into the familiar 4-step flow.

2-step configuration & when to switch

2-step has its own parameter block (RACH-ConfigCommonTwoStepRA): msgA-PreambleReceivedTargetPower, msgA-PUSCH-Config (the PUSCH occasions, DMRS, MCS), msgA-CB-PreamblesPerSSB, msgB-ResponseWindow, preambleTransMax for 2-step, and crucially msgA-RSRP — the threshold that decides, when both 2-step and 4-step are configured, which one a UE uses. Good-coverage UEs (RSRP above msgA-RSRP) use 2-step; cell-edge UEs use 4-step, because their large unknown delay would likely corrupt the MsgA PUSCH and force a fallback anyway.

Dimension4-step2-step
Messages / round trips4 / 22 / 1 (best case)
LatencyHigherLower
UL resource costLower (Msg3 only after grant)Higher (PUSCH sent speculatively)
Robust to large unknown delayYes (TA before Msg3)No (falls back)
Best fitMacro, cell edge, congestionSmall cells, FR2, NR-U, low latency
Response RNTIRA-RNTIMSGB-RNTI
Premium interactive lab

Run MsgA / MsgB and trigger a fallback yourself

Step through 2-step RACH frame by frame, force a PUSCH-payload failure, and watch the gNB drop you into the 4-step path with a fallbackRAR — the clearest way to understand why msgA-RSRP matters. Lifetime access — ₹999 / $9.99.

Open the 2-step RACH lab
CHAPTER TEN

Failure analysis — the four places RACH breaks

Now the part that pays the bills. When accessibility KPIs dip, RACH is the first suspect, and the procedure breaks in exactly four places. Knowing which one tells you which knob to turn.

RACH failure tree Msg1 sentpreamble on PRACH Msg2 RAR? FAIL 1 · no RARcoverage / config / N_cs / PRACH interf. Msg3 decoded? FAIL 2 · Msg3 lostUL coverage / wrong TA / HARQ out Contention? FAIL 3 · lost collisionCR timer expiry → backoff & retry SUCCESS FAIL 4 · ramp outhit preambleTransMax
Localise the stage first, then choose the fix. The most common real-world culprit is FAIL 2 (Msg3), not FAIL 1.

FAIL 1 — Msg1/Msg2 (no RAR)

The gNB never detected the preamble, or the UE never decoded the RAR in ra-ResponseWindow. Causes: downlink/uplink coverage hole; wrong prach-ConfigurationIndex (UE and gNB disagree on where PRACH is); root-sequence / Ncs collision with a neighbour (the gNB correlates a neighbour's UE as a ghost); PRACH-band interference; or ra-ResponseWindow set too short so the UE gives up before a (slightly late) RAR arrives.

FAIL 2 — Msg3 lost

RAR decoded, but the scheduled Msg3 PUSCH was never received. This is the cell-edge killer: Msg3 is a low-SINR uplink and if the link budget doesn't close, no amount of preamble tuning helps. Also caused by a bad timing-advance estimate (Msg3 lands outside the cyclic prefix) or HARQ retransmissions exhausting before success. Fixes live in uplink coverage, Msg3 MCS/repetition and TA accuracy — not in PRACH.

FAIL 3 — contention lost

Two UEs collided, one won, the loser's ra-ContentionResolutionTimer expired. A little of this is normal. A lot of it means too few preambles/ROs for the offered load — collision probability rises sharply as the per-RO preamble pool fills. The fix is PRACH dimensioning (more ROs via msg1-FDM or a denser prach-ConfigurationIndex, more CB preambles per SSB) and Backoff-Indicator tuning under congestion.

FAIL 4 — ramp exhaustion

The UE climbed the whole power ladder and still failed preambleTransMax times. This is the symptom of 1–3 persisting, plus possibly a too-low preambleReceivedTargetPower or too-small powerRampingStep (the UE never gets loud enough fast enough). It is what the user experiences as “no service” or a failed call setup.

CHAPTER ELEVEN

Counters, KPIs & the optimization playbook

You localise RACH failures with per-step PM counters. Every vendor exposes equivalents of the same logical set — the names differ (Ericsson pmRadioRa… families, Huawei N.RA.… / RACH measurement counters, Nokia RACH_…, ZTE NR RA counters) but the meaning is universal. Map your vendor's names onto this logical model and the maths below is portable.

Logical counterCountsExposes
Preambles received (CBRA / CFRA, by group A/B)preambles the gNB detectedPRACH load & collision pressure
RARs transmitted (Msg2)responses sentMsg1→Msg2 yield
Msg3 received / decodedsuccessful first scheduled ULcell-edge UL health (FAIL 2)
Contention resolutions sent (Msg4)completed handshakescollision rate (FAIL 3)
Avg / distribution of preamble attemptsramping depthcoverage & power tuning
RA failures / ramp-outspreambleTransMax hitsaccessibility loss (FAIL 4)

The KPIs that matter

RACH KPIs — vendor-agnostic RACH setup success rate  =  (Msg4 contention resolved) / (Msg1 attempts)
Msg2 success rate  =  (RARs sent) / (preambles received)
Msg3 success rate  =  (Msg3 decoded) / (RARs sent)
Contention resolution rate  =  (Msg4 success) / (Msg3 decoded)
Avg preamble Tx attempts  =  Σ(attempts) / (successful accesses)
Decompose the end-to-end rate into the three stage rates — the stage with the lowest yield is your bottleneck, and it tells you which fix below to reach for.

The optimization playbook

Symptom (from counters)Most likely causeAction
Low Msg2 rate, low loadCoverage / target power too low / Ncs collisionRaise preambleReceivedTargetPower; pick a longer/repeated format; re-plan roots & Ncs; check PRACH interference
Low Msg2 rate, high loadToo few ROs / preambles — collisions look like missesIncrease msg1-FDM, denser prach-ConfigurationIndex, more CB preambles/SSB
Good Msg2, poor Msg3Cell-edge UL / bad TA / HARQ exhaustionMsg3 repetition & robust MCS; verify TA; improve UL link budget; check ra-ResponseWindow timing
High contention lossPreamble pool too small for demandMore ROs/preambles; tune Backoff Indicator; split Group A/B by Msg3 size
High avg attemptsRamp too slow / target too lowIncrease powerRampingStep; raise target power; reconsider format
RACH OK but latency high4-step round trips dominateEnable 2-step with a sensible msgA-RSRP split
High-speed cell, sporadic ghostsDoppler aliasing of cyclic shiftsSwitch restrictedSetConfig to Type A/B
Large rural cell, edge failsRTT exceeds Ncs zero-corr zoneLong format 1, larger Ncs, accept fewer shifts/root

The golden rule of PRACH dimensioning. Capacity (more ROs/preambles to cut collisions) and coverage (longer formats, bigger Ncs) both consume the same finite PRACH airtime and root budget. You cannot maximise both — size the cell for its actual radius and offered load, and re-check after every coverage or load change. Over-dimensioning PRACH steals PUSCH capacity for no benefit.

CHAPTER TWELVE

Developer & test view — RRC IEs, srsRAN/OAI, logs

If you build, test or simulate RACH rather than optimise a live network, here is where it surfaces.

Where the config lives in RRC

The cell broadcasts RACH config in SIB1 inside ServingCellConfigCommon → uplinkConfigCommon → initialUplinkBWP → rach-ConfigCommon. The key sub-structures:

Reading it in an open-source stack

In srsRAN Project or OpenAirInterface, the gNB config file sets prach_config_index, prach_root_sequence_index, zero_correlation_zone, msg1_frequency_start, preamble_rx_target_pw, etc.; the UE logs walk the exact MAC states — RA procedure init, preamble Tx with the chosen index and power, RAR reception with the decoded RAPID and TA, Msg3 Tx, and contention resolution outcome. A typical UE-side trace reads like the message flow in this article, one line per state transition. To read it from the air, decode the PDCCH for the RA-RNTI you expect (compute it with the formula in Chapter 6) and you'll find the RAR PDSCH that follows.

A debugging shortcut. If a UE seems to send Msg1 but never proceeds, compute the RA-RNTI by hand from the occasion it used and confirm the gNB is transmitting a PDCCH with that exact RNTI in the response window. A mismatch (wrong slot index, wrong f_id, NUL vs SUL confusion) means the UE is listening for the wrong identity — a classic and easily-missed integration bug.

The complete 5G PHY course

Master the entire 5G NR physical layer

100+ interactive topics — frame structure, SSB & cell search, RACH (4-step & 2-step), beam management, HARQ, channel coding, scheduling, measurements and more — built for engineers who want to understand, not memorise. RACH alone has live PRACH, RA-RNTI and contention labs. ₹999 / $9.99 one-time, lifetime access.

Enrol in the 5G PHY Lab
CHAPTER THIRTEEN

Frequently asked questions

What is the difference between 4-step and 2-step RACH?

4-step uses Msg1 (preamble), Msg2 (RAR with TA + grant), Msg3 (identity), Msg4 (contention resolution). 2-step folds Msg1+Msg3 into one MsgA (preamble + PUSCH payload) and Msg2+Msg4 into one MsgB (successRAR completes it, or fallbackRAR drops you back to 4-step at Msg3). 2-step halves the round trips at the cost of speculative uplink resources.

How is RA-RNTI calculated?

RA-RNTI = 1 + s_id + 14×t_id + 14×80×f_id + 14×80×8×ul_carrier_id, from the symbol, slot, frequency index and carrier of the PRACH occasion. The UE computes it itself and uses it to find its RAR. 2-step uses the parallel MSGB-RNTI.

What does the RAR contain?

A RAPID (which preamble was heard), a 12-bit Timing Advance Command, a 27-bit uplink grant scheduling Msg3, and a 16-bit TC-RNTI.

What is contention resolution and why is it needed?

Multiple UEs can pick the same preamble in the same occasion. Contention resolution decides who owns the grant: a PDCCH to the UE's C-RNTI (if Msg3 carried a C-RNTI MAC CE), or a Msg4 MAC CE echoing the first 48 bits of the UE's CCCH SDU (initial access). The loser's ra-ContentionResolutionTimer expires and it retries.

How does preamble power ramping work?

The UE targets preambleReceivedTargetPower + DELTA_PREAMBLE + (counter−1)×powerRampingStep plus path loss, capped at PCMAX. Each failed attempt steps the counter (and power) up, until success or preambleTransMax. The counter holds (doesn't ramp) when the UE switches SSB beams.

What are the main RACH failure points and how do I troubleshoot them?

Four: no RAR (coverage/config/Ncs collision/interference), Msg3 lost (cell-edge UL/TA/HARQ), contention lost (too few preambles/ROs for the load), and ramp exhaustion (the persistent symptom). Localise with per-step counters, then fix with PRACH dimensioning, root planning, power tuning or timer settings — see the playbook in Chapter 11.

When should I use 2-step instead of 4-step?

Use 2-step where latency dominates and timing advance is small or known: small cells, FR2, NR-U, low-latency/small-data. Use 4-step for macro, cell edge and congestion. Most networks configure both and split by msgA-RSRP.

• • •

That is the whole bootstrap: from an anonymous UE shouting a Zadoff–Chu code into the void, through timing advance, a grant and a contention fight, to a fully scheduled connection — in four messages, or two. Master RACH and you've mastered the gate every 5G connection walks through. The fastest way to make it stick is to watch it: open the 4-step and 2-step labs and run a preamble through every state yourself.