>
Home5G NTNAccess & PHYTiming Advance & Koffset
📶 Access & PHYAdvanced

Timing Advance & Koffset in NTN

The headline NTN problem — huge, varying propagation delay. UE GNSS-based TA pre-compensation, common vs UE-specific TA, and the Koffset / Kmac scheduling offsets.

📚 3GPP-basedTS 38.211TS 38.213TS 38.321

On the ground a cell is a few kilometres wide, so the uplink timing the UE has to pre-empt is a few microseconds and the gNB can nudge it in a closed loop. Point the same UE at a satellite and the one-way delay jumps to tens or hundreds of milliseconds — and it drifts as the satellite races across the sky. No single timing-advance command can span that, and no closed loop can chase it fast enough. NR-NTN's answer is to make the UE do most of the work itself: using its own GNSS position and the satellite ephemeris, the UE computes and pre-compensates almost all of the timing before the network ever sends a correction. This page walks through the three components of NTN timing advance, the scheduling offsets cellSpecificKoffset and kmac that keep uplink and downlink timing relationships from landing in the past, and the validity timer that stops the UE transmitting once its ephemeris goes stale. The mechanics live in TS 38.213 and TS 38.321, with the broadcast parameters in TS 38.331.

Introduction

Timing advance (TA) is the amount by which a UE pulls its uplink transmission earlier than the downlink frame timing it observes, so that after propagation its signal arrives at the receiver aligned to the expected slot boundary. In terrestrial NR it is a small closed-loop correction the gNB measures and signals. In NR-NTN it becomes the single largest number in the whole uplink budget — and the point in the UE lifecycle where the satellite geometry first forces a fundamentally different design.

TA matters at two moments. First at random access, where the UE must arrive inside the gNB's preamble-detection window and then hit the Msg3 grant. Second, continuously in RRC_CONNECTED, where every scheduled PUSCH, PUCCH, and SRS must stay aligned as the satellite moves. Get the TA model wrong and nothing else in the uplink works — the preamble is missed, Msg3 lands in the wrong slot, or a connected UE drifts out of sync mid-pass.

Because NTN splits the timing advance into three separately-computed terms — one the UE derives itself, one the network broadcasts, one the gNB trims — a timing failure almost always lives in one specific term. Knowing which term is wrong (stale ephemeris, bad GNSS fix, a wrong ta-Common, an under-sized cellSpecificKoffset) narrows the root cause enormously. That is why this page treats TA as a step-by-step, component-by-component procedure.

Why NTN needs a new TA model

💡

In plain words: imagine throwing a ball to a friend on a moving train. On a station platform (terrestrial) you barely lead the throw and can correct next time. On a bullet train hurtling past (NTN), by the time you see where your friend is and adjust, they have already moved half a kilometre — so you don't react, you predict: you work out the train's speed and position first, then throw to where they will be. NTN timing advance is that predictive throw.

Uplink timing advance exists so that transmissions from UEs at different distances all arrive at the gNB aligned to the same slot boundary. In a terrestrial macro cell the round-trip propagation is at most a few hundred microseconds, and the gNB measures each UE's arrival and issues a Timing Advance Command (in the RAR for Msg3, then in a MAC CE afterwards) to pull it into line. The whole correction fits inside the timing-advance field, and because a UE barely moves between updates, an occasional command keeps it synced.

NTN shatters both assumptions. A LEO service link is on the order of a few milliseconds one way; a GEO service link is around 270 ms one way, so the round trip approaches 540 ms — thousands of times larger than the field a terrestrial Timing Advance Command was sized for. Worse, a low-orbit satellite moves several kilometres per second (see orbits & geometry), so the delay is not merely large, it is continuously changing. A closed loop that samples arrival time, computes an error, and signals a correction one round trip later is always correcting a delay that has already moved on.

🎯

The core shift: terrestrial TA is reactive — the gNB measures error and corrects it. NTN TA is predictive — the UE knows the geometry (its own position plus the satellite's orbit) and pre-computes the delay before transmitting, leaving the network only a small residual to trim.

The three components of NTN timing advance

NR-NTN keeps the closed-loop mechanism but demotes it to a fine-trim role, and adds two large open-loop terms the UE and network compute in advance. The total timing advance the UE applies is the sum of all three:

NTA = NTA,closed-loop + NTA,UE-specific + NTA,common

closed loopTiming Advance Command (RAR / MAC CE) · residual only
UE-specific ← UE GNSS position + satellite ephemeris · the service link
commonta-Common broadcast in SIB19 · feeder link + network offset
What

Three additive terms: a network closed-loop correction, a UE-specific pre-compensation, and a network-common pre-compensation. Only the sum matters at the gNB, but each is computed by whoever holds the information needed for it.

Why

No single party knows the whole delay. The UE knows the service-link geometry (from GNSS + ephemeris); the network knows the feeder link and any reference-point offset the UE cannot see; the gNB alone measures the tiny leftover error. Splitting the job puts each term where its information lives.

How

The UE reads the satellite ephemeris and epoch time from SIB19, fixes its own position with GNSS, computes the UE-specific and common terms, adds the closed-loop Timing Advance Command, and applies the total before every uplink transmission.

NTA,UE-specific — the service link the UE computes itself

This is the delay between the UE and the satellite. Because the UE knows where it is (GNSS is mandatory in NR-NTN — see GNSS & registration) and where the satellite is (the ephemeris in SIB19 gives position and velocity at a stated epoch), it can compute the geometric range to the satellite, convert it to a propagation delay, and pre-advance its uplink by exactly that much. As the satellite moves, the UE keeps recomputing the range from the propagated ephemeris, so this term tracks the drift on its own without any signalling.

NTA,common — the part only the network knows

The UE can compute the service link, but it has no way to know the delay on the far side of the satellite: the feeder link down to the gateway, plus whatever reference-point offset the network chooses so that all UEs align to a common timing reference. That is broadcast as ta-Common in SIB19. Because this delay also drifts (the feeder-link geometry changes too), SIB19 adds ta-CommonDrift and ta-CommonDriftVariation, letting the UE extrapolate the common term between SIB updates instead of waiting for a fresh broadcast every slot.

NTA,closed-loop — the residual trim

After the two open-loop terms, only a small error remains — imperfect GNSS, ephemeris quantisation, unmodelled effects. The gNB measures that residual and corrects it with the ordinary Timing Advance Command in the RAR (during random access) and later in a MAC CE. It is the same mechanism as terrestrial NR, just carrying a tiny leftover rather than the whole delay.

Precisely: at random access the residual is carried in the RAR's 12-bit Timing Advance Command (T_A, range 0–3846). In RRC_CONNECTED it is adjusted relatively by the 6-bit Timing Advance Command MAC CE (T_A 0–63, where 31 = no change). The RAR itself rides on PDSCH scheduled by DCI format 1_0 with CRC scrambled by RA-RNTI in the Type1-PDCCH common search space; the MAC CE later rides on a normal C-RNTI-scheduled PDSCH.

📄

Spec anchor: the decomposition of NTA into UE-specific, common, and closed-loop parts and the use of ephemeris + GNSS for self-computation are defined in TS 38.213; ta-Common, ta-CommonDrift, and ta-CommonDriftVariation are carried in SIB19 per TS 38.331.

✅ Debugging steps

  • Confirm the UE has a valid GNSS fix before it computes any TA — no fix means no UE-specific term, so the whole pre-advance is wrong.
  • Check the ephemeris in SIB19 decoded correctly (orbital elements or state vector) and that the UE propagated it from the right epochTime.
  • Verify ta-Common (and the drift terms) were read from SIB19 and are being added on top of the UE-specific term.
  • Cross-check the residual Timing Advance Command in the RAR is small — a large residual means the UE's open-loop computation was off, not that the gNB is doing the whole job.

⚠ Common causes of failure

  • No or stale GNSS fix, so the UE-specific delay is computed from a wrong position.
  • Ephemeris propagated past its epoch, or the wrong epoch applied, so the satellite range is off.
  • ta-Common missing, mis-scaled, or drift terms ignored, so the feeder-link portion is uncompensated.
  • UE applies only the closed-loop term (treating NTN like terrestrial) — the RAR TA field cannot express hundreds of ms, so the preamble/Msg3 lands far outside the window.

Who compensates which delay

The clearest way to hold this in your head is to draw the link and label each segment with the party responsible for it.

Delay budget on the NTN uplink path Satellite UE + GNSS Gateway / gNB service link UE pre-computes (N TA,UE-specific) feeder link network models (N TA,common) gNB trims the leftover with the Timing Advance Command (closed loop)
Figure 1. The UE pre-compensates the service link from GNSS + ephemeris; the network folds the feeder link and reference offset into ta-Common; the gNB closed loop removes only the residual.

A concrete sense of scale helps. On a GEO system the service link alone is roughly 270 ms one way, so the UE pre-advances its uplink by about 540 ms round trip — more than half a second of pre-emption computed entirely from geometry. Contrast that with a terrestrial macro cell, where the whole timing advance is a few microseconds. The pre-compensation in NTN is not a refinement of the terrestrial value; it is five to six orders of magnitude larger, and it exists only because the UE can calculate it before transmitting.

K_offset — giving the UE time to react

Pre-compensating the delay fixes arrival alignment, but it creates a second problem. Many NR timing relationships are defined as "do X in the uplink k slots after receiving Y in the downlink" — the gap from a grant to the scheduled PUSCH, from a RAR to Msg3, from a downlink assignment to its HARQ feedback. Those gaps were sized for microsecond round trips. In NTN, by the time the UE has applied a half-second pre-advance, the slot it is told to transmit in has already gone by: the required uplink instant lands in the past.

The fix is a scheduling offset. cellSpecificKoffset (written Koffset), broadcast in SIB19, is added to those downlink-to-uplink timing relationships so that the UE always has enough lead time to pre-compensate and transmit. It shifts the whole reference forward by a cell-chosen number of slots that covers the cell's worst-case round-trip delay — which is why it is cell-specific rather than one global value: a low LEO beam and a GEO beam need very different offsets.

slots → DL grant slot n terrestrial n + k UL (Msg3/PUSCH) n + k + K offset + K offset (from SIB19) extra lead time to pre-compensate & transmit
Figure 2. K_offset pushes the uplink instant from the terrestrial n + k out to n + k + K_offset, so the pre-advanced uplink no longer lands in the past.

Koffset is the cell-wide value covering the largest delay in the beam. Because different UEs in the same beam actually experience different delays, NR-NTN also defines a UE-specific differential offset: once the network knows a UE's own service-link delay (from its TA reporting), it can signal a smaller per-UE correction so that UE need not always pad to the cell worst case. The cell-specific value bootstraps access; the differential value tunes it afterwards.

✅ Debugging steps

  • Read the broadcast cellSpecificKoffset from SIB19 and confirm it is at least the cell's worst-case round-trip time in reference-SCS slots.
  • Verify the UE applies Koffset to all DL-to-UL relationships (RAR-to-Msg3, DCI-to-PUSCH k2, DL-assignment-to-HARQ), not just Msg3.
  • If Msg3 is never decoded despite a good preamble, check whether the scheduled Msg3 slot fell in the past — a sign Koffset is too small or not applied.
  • For a connected UE, confirm any UE-specific differential Koffset was signalled and applied on top of the cell value.

⚠ Common causes of failure

  • cellSpecificKoffset under-sized for the beam's RTT, so the granted UL slot is unreachable and Msg3/PUSCH is dropped.
  • UE reads Koffset in the wrong SCS units, so the applied offset is off by a numerology factor.
  • Koffset applied to some timing relationships but not others, so HARQ feedback or CSI lands in the wrong slot.
  • Differential UE-specific offset not applied, so a near-overhead UE over-pads and wastes latency (or under-pads at low elevation).

Kmac and the UL/DL timing reference

Koffset protects uplink transmissions. There is a matching issue in the downlink direction. Some actions the network schedules — the moment a MAC CE takes effect, an activation timing — are defined relative to when the gNB assumes its downlink frame timing aligns with the UE's uplink frame timing. Because the common TA is applied at a network reference point and is not fully pre-compensated at the gNB, that assumed alignment is offset in time. kmac, also provided to the UE, carries that offset so the UE and network agree on when such downlink-referenced actions apply.

💡

One-line split: cellSpecificKoffset shifts uplink timing relationships forward so the UE has time to pre-compensate; kmac aligns downlink-referenced action timing at the point where the network assumes UL and DL frames coincide. One protects when the UE transmits, the other when network commands take effect.

ntn-UlSyncValidityDuration — when the maths goes stale

Every open-loop term depends on the ephemeris and common-TA parameters being current. Ephemeris is a snapshot at an epoch; propagate it too far and the predicted satellite position drifts from reality, so the UE's computed delay and drift become wrong. To bound that error, SIB19 carries ntn-UlSyncValidityDuration: the length of time the current ephemeris and common-TA information may be used before the UE must re-acquire SIB19.

While the timer runs, the UE freely extrapolates delay and Doppler from the ephemeris, drift terms, and epoch time. When it expires without a fresh SIB19, the UE considers itself no longer uplink-synchronised and stops transmitting — better to go silent than to fire an uplink burst that, mis-computed, would arrive in the wrong slot and interfere with other users. It must re-read SIB19 (and re-check GNSS) to restore uplink sync before it may transmit again.

🎯

Fail-safe, not best-effort: an expired ntn-UlSyncValidityDuration halts uplink outright. NTN would rather lose a UE's uplink briefly than let a stale-timing transmission corrupt the shared slot for everyone else in the beam.

✅ Debugging steps

  • When a connected UE suddenly goes silent on the uplink, check whether ntn-UlSyncValidityDuration expired without a fresh SIB19 read.
  • Confirm the UE is re-acquiring SIB19 (and re-checking GNSS) before the timer elapses, not after.
  • Compare the timer value against how fast the ephemeris drifts for this orbit — a fast LEO needs a shorter validity than a GEO.
  • Correlate uplink stalls with SIB19 modification periods; a missed SIB update is a common trigger.

⚠ Common causes of failure

  • SIB19 not refreshed before ntn-UlSyncValidityDuration expires, so the UE halts uplink mid-session.
  • GNSS lost (indoor, jamming, tunnel) so the UE cannot restore uplink sync even after re-reading SIB19.
  • Validity set too long for a fast-moving LEO, so extrapolation error grows and TA drifts out of the residual budget.
  • Validity set too short, forcing constant SIB19 re-reads and wasting downlink capacity.

Reading NTN timing in the logs

NTN timing shows up in the trace as two linked events: the UE's open-loop computation (its GNSS fix, the propagated ephemeris, and the UE-specific + common terms it derived) and the gNB's residual measurement (the small leftover it signals in the RAR or MAC CE). Reading them side by side tells you whether a timing problem is in the UE's maths, the broadcast parameters, or the closed-loop trim.

Representative UE NTN-timing log — illustrative, values vary by vendor/build:

NTN TA compute: gnssFixValid=1, gnssAgeMs=420 ephemeris: model=stateVector, epochSFN=512, epochAgeMs=1830, propOk=1 satRange_km=1972.4, elevationDeg=41.2 N_TA_ue_us=13.16 (service-link one-way = 6.58 ms) ta_common_us=17020.4 (from SIB19: taCommon=4181766, drift=-118) kOffset_slots=52, kMac_slots=18, ulSyncValid_s=180 (remaining=142) NTN TA apply: N_TA_total_us=17033.6 + residual RAR TA cmd (12-bit) T_A=21 -> residual N_TA=+0.66 us (closed-loop trim) MAC CE TA cmd (6-bit) T_A=33 -> relative +0.13 us (connected update)
FieldMeaningExampleCheck
gnssFixValid / gnssAgeMsWhether the UE has a current GNSS position and how old it is.1 / 420Must be valid and fresh; a stale/invalid fix invalidates the whole UE-specific term.
epochSFN / epochAgeMsThe ephemeris reference epoch (epochTime) and how far the UE propagated past it.512 / 1830Propagation age must stay well inside ntn-UlSyncValidityDuration; too old = drift error.
N_TA_ue_usUE-specific service-link pre-compensation derived from range.13.16Should track satRange/elevation across the pass; a frozen value means ephemeris not being re-propagated.
ta_common_usCommon term from SIB19 ta-Common (+ drift), covering feeder link + reference offset.17020.4Must be non-zero for a transparent payload; zero/absent means the feeder link is uncompensated.
kOffset_slotscellSpecificKoffset the UE applies to DL-to-UL timing.52Must cover the cell RTT; compare against the worked-example sizing below.
ulSyncValid_s / remainingntn-UlSyncValidityDuration and time left before re-read.180 / 142If remaining hits 0 without a SIB19 refresh, the UE halts uplink.
RAR T_A (12-bit)Residual timing command in the RAR closed loop.21Should be small; a large residual means the open-loop computation was off.
MAC CE T_A (6-bit)Relative connected-mode TA adjustment (31 = no change).33Repeated large corrections signal the UE is not tracking drift itself.

Worked example — timing over one LEO-600 pass, and the Koffset it needs

Numbers make the geometry concrete. Take a LEO satellite at 600 km and follow one overhead pass. The service-link one-way delay is just the slant range divided by the speed of light, and the UE must pre-advance its uplink by the round trip of that:

tone-way = dslant / c   →   overhead (elevation 90°, d = 600 km): 600×103 / (3×108) = 2.0 ms  →  service-link RTT ≈ 4.0 ms
low elevation (30°, d ≈ 1075 km): 1075×103 / (3×108) = 3.6 ms  →  service-link RTT ≈ 7.2 ms

So across a single pass the UE-specific timing advance the UE pre-applies slides continuously from about 4.0 ms (satellite overhead) to about 7.2 ms (near the minimum elevation). That drift — several milliseconds within one pass — is exactly why the UE computes it from GNSS and ephemeris every moment rather than waiting for a one-shot Timing Advance Command. For a transparent payload the feeder link is added on top via ta-Common; the full UE↔gNB round trip for LEO-600 transparent reaches about 25.77 ms (see Orbits, Delay & Doppler).

That total round trip is what cellSpecificKoffset has to cover: the gap from a downlink grant (or RAR) to the scheduled uplink must be at least the worst-case round trip, or the pre-advanced uplink would be scheduled in the past. Sizing it:

Koffset ≥ RTTmax , in slots of the reference SCS (15 kHz → 1 slot = 1 ms)
LEO-600 transparent: RTTmax25.77 ms → Koffset26 slots  (≈ 52 at 30 kHz UL)
GEO transparent: RTTmax541 ms → Koffset541 slots
🎯

Why the range is 1..1023: at a 15 kHz reference (1 slot = 1 ms) a cellSpecificKoffset of 1023 spans just over 1 second of round trip — deliberately sized so a single IE covers everything from a low-RTT LEO cell (~26) to a worst-case GEO cell (~541). Each beam broadcasts its own value because its worst-case delay differs.

NTN timing parameters at a glance (TS 38.331)

Parameter (IE)Range / typeUnit & meaning
epochTimeSFN 0–1023, subframe 0–9Reference instant the ephemeris & common-TA values apply to; the UE propagates forward from it.
ta-Common0 … 66485757Steps of 4.072 ns → up to ≈ 270.7 ms. The network-side common timing offset (feeder link + reference).
ta-CommonDriftsigned integerRate of change of ta-Common (fine sub-ns/s granularity) — lets the UE extrapolate between SIB19 reads.
ta-CommonDriftVariationunsigned integerSecond-order (drift-of-drift) term for longer-validity extrapolation.
cellSpecificKoffset1 … 1023Slots at the 15 kHz reference SCS → up to ≈ 1 s. Scheduling offset added to UL timing relationships.
kmac1 … 512Downlink timing-reference offset used when the common TA is not fully pre-compensated at the gNB.
ntn-UlSyncValidityDurationenum s5 … s900Seconds the ephemeris/common-TA stay valid; on expiry the UE halts UL and re-reads SIB19.

Ranges follow the NTN-Config / TA-Info IEs in TS 38.331; consult the ASN.1 for the exact normative bounds and step sizes.

🔀

LTE ↔ NR · TN ↔ NTN: in terrestrial LTE and NR the UE never computes its own timing — the eNB/gNB measures the preamble and signals the entire TA (an 11-bit command in the LTE RAR, 12-bit in NR), and a UE with no GNSS is fine. NR-NTN inverts this: the UE must hold a GNSS fix and self-compute the UE-specific + common terms, leaving the gNB only the residual. Terrestrial NR has no ta-Common, no cellSpecificKoffset, no kmac, and no ntn-UlSyncValidityDuration — all four exist only because a satellite link's delay is both enormous and time-varying. IoT-NTN (eMTC/NB-IoT over satellite) reuses the same three-component model with its own narrowband parameter set.

Summary

NTN timing advance is a predictive replacement for the terrestrial reactive closed loop. The applied TA is the sum of three terms: NTA,UE-specific (the service link, computed by the UE from GNSS + ephemeris), NTA,common (the feeder link + reference offset, broadcast as ta-Common with drift terms in SIB19), and NTA,closed-loop (the small residual the gNB trims via the RAR 12-bit and MAC CE 6-bit Timing Advance Command). If timing is wrong, isolate the term: a bad GNSS fix or stale ephemeris breaks the UE-specific term; a missing or mis-scaled ta-Common breaks the common term; a large residual command means the open-loop maths was off.

Two scheduling offsets keep the timing relationships sane: cellSpecificKoffset pushes DL-to-UL relationships (RAR-to-Msg3, grant-to-PUSCH, HARQ) forward so the pre-advanced uplink never lands in the past, and kmac aligns downlink-referenced action timing where the network assumes UL and DL frames coincide. Finally, ntn-UlSyncValidityDuration is the fail-safe: when the ephemeris goes stale the UE halts uplink rather than transmit a mis-aligned burst.

Read the trace top-down: GNSS fix → propagated ephemeris → UE-specific term → ta-Common → Koffset/kmac applied → residual RAR/MAC-CE command → validity timer. The first value that does not line up is your root cause.

Q&A Interview quickfire

Q. Why can't NTN just use ordinary closed-loop timing advance like a terrestrial cell?

A. Two reasons. The delay is far too big — up to ~540 ms round trip on GEO versus a few µs terrestrial, thousands of times larger than the terrestrial TA field was sized for — and it drifts continuously as the satellite moves, so a loop that corrects one round trip late is always chasing a delay that has already changed. NTN instead has the UE pre-compute the bulk of the delay from GNSS + ephemeris and leaves the closed loop to trim only the small residual.

Q. What are the three components of NTN timing advance and who provides each?

A. N_TA,UE-specific (the service link, computed by the UE from its GNSS position and the satellite ephemeris in SIB19), N_TA,common (the feeder link plus a network reference offset, broadcast as ta-Common with drift terms in SIB19), and N_TA,closed-loop (the residual, corrected by the gNB's Timing Advance Command in the RAR and MAC CE). The applied TA is their sum.

Q. What is K_offset for, why is it cell-specific, and what happens when ntn-UlSyncValidityDuration expires?

A. cellSpecificKoffset is added to downlink-to-uplink timing relationships (grant-to-PUSCH, RAR-to-Msg3, HARQ timing) so the pre-advanced uplink doesn't land in the past; it is cell-specific because each beam's worst-case round-trip delay differs (LEO vs GEO). When ntn-UlSyncValidityDuration expires, the ephemeris/common-TA info is no longer trusted, so the UE stops uplink transmission and must re-acquire SIB19 before resuming, preventing mis-aligned bursts.

Where this leads next

Pre-computed timing is only half of the geometry problem — the same GNSS-plus-ephemeris inputs also drive frequency pre-compensation, and the offsets here reshape how initial access and the HARQ timers behave. Continue with the mechanisms that share this machinery.