Pro edition only

Starlink Viewer

Overview

The Starlink Viewer displays a live 3D globe with all ~10,000 Starlink satellites animating in real time, your dish location, and an inferred connection to the satellite most likely serving your terminal.

The ideal Starlink monitoring tool would show you exactly which satellite your dish is communicating with at any given moment, when it hands off to a new satellite, and the signal path from your dish through the satellite to the ground station. This would require the dish to expose the serving satellite’s identity and the electronic beam steering direction. SpaceX does not expose either, so Nexus infers the serving satellite from the data that is available.

Why Inference Is Necessary

SpaceX locks satellite identification data behind authenticated gRPC endpoints that are inaccessible on consumer firmware.

  • dish_get_context contains an initial_satellite_id field, but has returned PermissionDenied on consumer hardware since firmware 9f4d05a4 (June 2021).
  • transceiver_get_telemetry exposes lmac_satellite_id and target_satellite_id, but returns UNIMPLEMENTED on all consumer terminals.
  • PKI challenge-response authentication with SpaceX-controlled keys means no community bypass exists.
  • Electronic beam steering direction: which would directly identify the serving satellite, is not exposed through any endpoint.
  • The dish’s phased array antenna steers its beam electronically up to ±50° from boresight, but this steering angle is entirely invisible to external consumers of the API.

Available Data

Measured from the dish

Data What it tells us Update rate
Boresight azimuth and elevation Physical orientation of the dish body 1 Hz
PoP ping latency Round-trip time to the point of presence 1 Hz
Downlink and uplink throughput Current throughput 1 Hz
Slot timer Satellite slot timer (always 0 on tested hardware) 1 Hz
GPS coordinates Dish location On demand
Outage history (did_switch) Confirmed satellite switch during a service disruption Per outage event
Obstruction map (SNR grid) 123×123 pixel sky map; contains real-time satellite signal data when reset at handover boundaries (see Obstruction Map and Satellite Tracking) 1 Hz

External sources

Data What it tells us
TLE orbital elements for ~10,000 Starlink satellites (CelesTrak / 18th Space Defence Squadron) Computed azimuth, elevation, and slant range of every satellite from any observer position

What is not available

Data Why we want it Status
Serving satellite ID Direct identification Locked behind authentication
Electronic beam steering angle Precise beam direction Not exposed in any endpoint
Functional slot timer Handoff timing signal Field exists but reads 0 on current consumer firmware

How Matching Works

Satellite matching

The viewer performs the following computation at 1 Hz:

  1. Observer position: the dish’s GPS coordinates from get_location establish where you are on Earth.

  2. Satellite positions: using SGP4 orbital propagation on TLE data from CelesTrak, the viewer computes the azimuth, elevation, and slant range of every Starlink satellite as seen from your dish’s location.

  3. Field of view filtering: only satellites above 10° elevation are considered. The dish’s physical boresight direction (from alignment_stats) defines the centre of the phased array’s ~100° field of view cone.

  4. Nearest candidate selection: the satellite with the smallest angular distance from the physical boresight centre is selected as the most likely serving satellite.

The boresight crosshair

The crosshair on the polar sky plot represents the physical orientation of the dish body, not the electronic beam direction. The Starlink phased array antenna is largely stationary after initial alignment; the boresight values change by fractions of a degree over hours due to wind or thermal effects. The dish does not physically move to track individual satellites.

The actual beam steering happens electronically within the phased array at the RF level, sweeping up to ±50° from the physical boresight to track the serving satellite. This electronic beam direction is not exposed through any consumer API endpoint.

Satellite change detection

When the nearest satellite candidate changes (a different NORAD ID becomes the geometric nearest), this is observed as an inferred satellite change. These changes correlate with but do not confirm actual dish handoffs. They reflect orbital mechanics; as satellites pass overhead at ~7.5 km/s, the one nearest to the dish’s boresight centre changes naturally every few minutes.

Real satellite handoffs on Starlink are engineered to be seamless (make-before-break), producing no measurable discontinuity in latency or throughput that could be used as a reliable detection signal on current firmware.

Confidence scoring

The confidence score reflects the geometric likelihood that the matched satellite is the actual serving one:

Confidence Criteria Interpretation
High < 10° from boresight, ≤ 3 nearby candidates Few satellites in the vicinity; strong geometric candidate
Medium < 25° from boresight Well within the field of view; reasonable candidate
Low < 50° from boresight Within the dish’s steering range but many nearby candidates
No Match > 50° from boresight No satellite within the dish’s electronic steering range

These thresholds are calibrated for the physical boresight (dish body direction), not the electronic beam. Because the phased array can steer ±50° from the dish face, the serving satellite will typically be 10-40° from the physical boresight centre. A “High” confidence match means there is a single strong geometric candidate; it does not mean the identification is confirmed.

Degree of Accuracy

What you can trust

Satellite positions on the globe are accurate. TLE data from CelesTrak is authoritative (sourced from the US Space Force 18th Space Defence Squadron) and SGP4 propagation is the standard method used by the space tracking community. Positional accuracy is typically within a few kilometres for recently updated TLEs.

Your dish location is accurate. It comes directly from the dish’s onboard GPS.

The physical boresight direction is accurate. It is measured by the dish’s IMU (inertial measurement unit) with an uncertainty of ~0.6°.

The set of visible satellites is accurate. The computed look angles from your position to each satellite are geometrically precise, so the polar plot correctly shows which satellites are overhead and where they are in the sky.

What is inferred

The identified satellite is an educated guess. The nearest satellite to the boresight centre is the best geometric candidate, but the dish may be communicating with any satellite within its ±50° electronic steering range. At any given moment, dozens of satellites may be within the field of view.

Satellite changes are observed geometry, not confirmed handoffs. When the nearest candidate changes, this reflects orbital drift, a different satellite becoming geometrically closest. Real dish handoffs may or may not coincide with these geometric changes. Some real handoffs will be invisible to the inference (the dish switches to a different satellite but the geometric nearest doesn’t change), and some observed changes will be pure orbital drift (the geometric nearest changed but the dish didn’t actually switch).

Confidence scores are geometric, not signal-based. A “High” confidence match means good geometry, not a validated connection. Without access to the electronic beam direction or the serving satellite ID, no consumer-firmware-based tool can confirm which satellite the dish is actually using.

Signals We Investigated

During development, several signals were evaluated for handoff detection. All were tested against real hardware (rev3_proto2, firmware 2026.02.16.cr74084 and 2026.04.07.mr77639.1).

Signal Hypothesis Finding
seconds_to_first_nonempty_slot Should count down per satellite slot and reset on handoff Always reads 0 on tested consumer hardware; field is unpopulated
pop_ping_latency_ms discontinuities Latency should jump when slant range changes during a handoff Latency remains smooth through handoffs; SpaceX likely uses make-before-break switching that absorbs path changes
did_switch from outage history Confirmed switch flag in outage records Only fires during service disruptions, not routine ~15-second clean handoffs
Boresight discontinuities Physical dish repositioning might accompany handoffs The dish body barely moves; electronic beam steering handles satellite tracking silently
Obstruction map SNR (without reset) Per-cell SNR changes should track satellite movement through the field of view Without resetting the map, it returns a static cumulative clear-sky mask on an unobstructed dish; all visible cells read ~1.0 with zero variation between consecutive polls. The accumulated data is fully saturated, so frame-to-frame differencing shows no changes.
Obstruction map SNR (with reset) After calling dish_clear_obstruction_map, the map should rebuild from empty and reveal the serving satellite’s position as it paints new pixels each second Confirmed working. After resetting at handover boundaries, 1 Hz polling produces clean single-pixel satellite trajectories. See Obstruction Map and Satellite Tracking.

Obstruction Map and Satellite Tracking

Background

The SatInView study by Ahangarpour, Zhao, and Pan (ACM MobiCom '24 LEO-NET Workshop) demonstrated that the serving satellite can be identified by resetting the dish’s obstruction map at 15-second handover boundaries, polling it at 1 Hz, and XORing adjacent frames to extract the satellite’s trajectory as it moves across the field of view. The observed trajectory is then matched against TLE-propagated satellite positions to achieve near-unambiguous identification.

During initial development of the Starlink Viewer, we tested the obstruction map without performing a reset. On an unobstructed dish, the map appeared static — a fully saturated clear-sky mask with no frame-to-frame variation. We concluded that the data did not contain real-time satellite signal information. This conclusion was accurate for the unreset map, but incomplete: the map appeared static because every pixel the current satellite could paint was already lit from previous satellite passes. Without clearing the accumulated data first, there was nothing new for the XOR to detect.

Updated findings

Following correspondence with the SatInView research team, we tested the full reset-based approach on rev3_proto2 hardware running firmware 2026.04.07.mr77639.1 (April 2026). The results confirm that the technique works on current hardware and firmware:

  • dish_clear_obstruction_map is available and functional. Calling it clears the accumulated SNR data (377 active pixels reduced to 1 in testing).
  • After a reset, the map rebuilds at approximately one new pixel per second as the serving satellite moves through the field of view.
  • XORing adjacent frames at 1 Hz produces clean, single-pixel trajectory points with near-zero spread.
  • The 15-second handover timing (12th, 27th, 42nd, and 57th seconds of each minute, globally synchronised) was confirmed on our hardware. Consecutive intervals tracked the same satellite continuously, with a clear trajectory jump when an actual handover occurred.
  • The map reports FRAME_EARTH on stationary active dishes, meaning the grid is oriented with the top-centre pixel corresponding to true north. Mobile or inactive dishes may report FRAME_UT, where the bottom-centre pixel corresponds to the boresight direction.

Trade-off: why Nexus does not reset the map by default

The dish_clear_obstruction_map call is destructive — it erases the dish’s accumulated obstruction profile. For users with obstructed installations (trees, buildings, or other structures), this data is valuable for diagnosing signal issues and is built up over time across many satellite passes. Resetting it every 15 seconds prevents the dish from accumulating any obstruction data, and the Starlink mobile app will show an empty or partial map.

Nexus currently uses geometric inference (boresight direction + TLE matching) as its default satellite identification method. This approach is non-destructive — it does not call any write endpoints on the dish and has no side effects on the user’s obstruction data.

We are using the trajectory-based approach as a calibration tool to validate and improve the accuracy of our geometric inference. We are also evaluating whether to offer trajectory tracking as an opt-in mode for advanced users and researchers, with clear disclosure about the map reset trade-off.

What Could Change This

Future firmware updates or hardware revisions could expose additional telemetry that would improve inference accuracy:

  • Functional seconds_to_first_nonempty_slot: if this field is populated on newer firmware or hardware, it would provide a reliable per-handoff timing signal.
  • Electronic beam steering angles: any exposure of the phased array’s actual beam direction would enable direct satellite identification.
  • Relaxed authentication on dish_get_context: if SpaceX were to re-enable the initial_satellite_id field, the problem would be solved entirely.
  • Non-destructive real-time signal data: if future firmware exposes per-satellite signal information through a separate endpoint or a non-destructive variant of the obstruction map, the trajectory-matching approach could be used without resetting the user’s obstruction data.
  • New hardware generations: SpaceX is deploying V3 satellites and new terminal hardware. Different firmware or hardware revisions may populate currently-dead fields or expose new telemetry.

Prior Art

Nexus uses geometric inference (boresight direction + TLE-propagated satellite positions) to estimate which satellite is serving the dish. This is a heuristic approach — effective and non-destructive, but limited in precision.

For higher-accuracy identification, the SatInView technique developed by Ahangarpour, Zhao, and Pan at the University of Victoria (ACM MobiCom 2024, LEO-NET Workshop) achieves near-unambiguous satellite identification by correlating obstruction map trajectories with TLE data. Their approach requires resetting the obstruction map at handover boundaries, which we have confirmed works on current hardware and firmware (see Obstruction Map and Satellite Tracking). Their implementation is available at github.com/aliahan/SatInView.

We are using their trajectory-based technique as a reference to calibrate and improve the accuracy of the geometric inference used in the Starlink Viewer.

Orbital Data

Satellite positions are sourced from the CelesTrak supplemental GP endpoint, which provides SpaceX-contributed ephemeris merged with standard 18th Space Defence Squadron catalogue data. The data is cached locally by the Rust backend and refreshed every 6 hours, with a 48-hour stale cache fallback if CelesTrak is unreachable. The status bar shows the current satellite count and data age.

Dish Location

The viewer uses GPS coordinates from the dish’s get_location endpoint when available. If GPS data is not accessible, you can manually enter your latitude and longitude in the configuration panel.