How SatRadar draws ten thousand satellites at 60 to 120 frames a second.
SatRadar is a viewer for the actual sky. Every dot on the globe is propagated from public TLE catalogs using the same SGP4 algorithm published in Vallado et al. 2006 — the reference implementation. The trick to keeping it smooth at constellation scale is moving the math off the CPU.
SGP4 (Simplified General Perturbations 4) is the standard analytical propagator for Earth-orbiting satellites. It was developed by NORAD in the 1970s and refined over decades; SDP4 is the deep-space variant, used for satellites whose orbital period exceeds about 225 minutes — the geostationary belt, the highly-elliptical Molniya orbits, and (just barely) the GNSS constellations in MEO with their ~12-hour periods. Most modern libraries unify the two under the SGP4 banner and pick the right path internally based on each TLE's mean motion.
The input to SGP4 is a two-line element set (TLE) — a compact, fixed-width ASCII record describing a satellite's orbital state at a specific epoch. Each TLE gives mean motion, eccentricity, inclination, RAAN, argument of perigee, mean anomaly, drag terms, and a small handful of secular correction coefficients. From that, SGP4 propagates the satellite's position forward (or backward) in time, accounting for Earth's oblateness (the J2 / J3 / J4 zonal harmonics), atmospheric drag, and lunar / solar gravitational perturbations.
It is not the most accurate propagator that exists. It is the most accurate propagator that runs in a handful of microseconds. TLEs themselves carry no formal error bar, and real-world accuracy depends on the object, drag environment, recent maneuvers, and TLE age. As a rough guide for LEO with fresh TLEs (under a day or two old) positions tend to be within a few kilometers of truth, with steady degradation past a week. We refresh the catalog every session. SatRadar is a visualisation tool, not a conjunction-analysis or operational pointing tool — for those use cases, talk to your nearest astrodynamics group.
The interesting engineering problem with constellation-scale orbital viewers is not the math — SGP4 has been in textbooks for fifty years. It's the throughput. Ten thousand satellites at 60 frames a second means SGP4 has to run six hundred thousand times every second, every frame, without falling behind. At 120 fps on a ProMotion display it's over a million propagations a second. Doing that in JavaScript on the CPU is somewhere between difficult and impossible.
The solution is to push the whole propagator onto the GPU and run it in parallel for every satellite at once. SatRadar's GLSL implementation lives inline in web/public/orbit/orbit.js; each satellite's orbital elements are packed into a texture, the vertex shader pulls them per-vertex, runs the full SGP4 (including all the trig identities the textbook spells out longhand), and emits the satellite's position. The native Metal version on Mac / iPhone / iPad / Apple TV / Vision Pro mirrors the same GLSL approach, transpiled through Apple's shading language.
Sixty frames a second on a phone with the full mesh on screen is the headline. On iPad Pro and iPhone Pro models the viewer hits the 120 Hz ProMotion ceiling; on the Vision Pro it runs at the device's native refresh; on a recent M-series Mac the WebGL2 path holds 120 fps in a Chrome window. Cross-platform accuracy is verified by a test harness that runs the same TLE inputs through the GPU shader, the CPU reference implementation, and a third-party validation library, and reports per-platform deviation in a published JSON report.
View the latest cross-platform accuracy test results →
CelesTrak — Dr. T.S. Kelso has maintained this for almost as long as there have been satellites to track. SatRadar pulls fresh TLEs from CelesTrak's grouped endpoints (active, Starlink, GPS, GLONASS, Galileo, BeiDou, weather, etc.) at session start. CelesTrak republishes from the official US Space Force catalog (the 18th Space Defense Squadron) hosted at Space-Track.
The current active catalog runs to roughly 15,000 objects in 2026 — the "10,000+" figure that turns up around the site is the deliberately conservative public claim and the bar the renderer was originally tuned to clear. We pull the live count every session and render whatever CelesTrak says is active that day, so on most days the viewer is showing well past ten thousand.
For Time Travel scrubbing, we ingest archival TLE snapshots from Space-Track — the same source CelesTrak draws from for current data. Our archival catalog starts in 1962 and is snapshotted at multi-month intervals through to the present; each constellation appears in the viewer from the year it actually launched. Sputnik 1 itself (1957) predates the modern TLE format, so its orbital parameters are hand-curated from the well-documented launch record. We could push the snapshot floor earlier with more careful TLE-format normalisation, but the catalog of Earth-orbiting objects between 1957 and 1962 is small enough that we've left that pass for later.
The 8K Earth texture is composited from public-domain NASA Blue Marble imagery and topographic relief. At close zoom the viewer switches to live OpenStreetMap tiles for terrain detail. Country borders are rendered from Natural Earth's public data set.
The pale blue ring around the Earth's limb is a Rayleigh / Mie atmospheric scattering pass computed in the fragment shader. The pass takes the Sun's true position in scene space (computed from the simulation clock, not faked) and integrates scattering along the view ray for every pixel near the limb. Day-side pixels get a subtle pale blue tint; night-side pixels get the deep-blue twilight band. The terminator is the boundary between the two and is mathematically continuous — no hand-painted falloff.
The cloud cover is a procedural noise texture, three octaves of Perlin / curl noise, rotated subtly over time so it doesn't feel frozen. It is not real-time weather data. The satellites are the live thing in this viewer; piping in real cloud imagery made the planet busier without making it more accurate. If that ever changes, NOAA's GOES imagery is the public source we'd most likely wire up.
The ocean has a low-frequency sun-glint specular pass — bright spots appear where the Sun reflects off the water relative to your viewpoint. The terrain elevation is read from a relief map texture baked offline and sampled in the vertex shader for true 3D landmasses (you can see this most clearly when the camera grazes the limb).
The star field draws the BSC5 bright-star catalog, projected from real RA / Dec coordinates into scene space. The Sun is a billboard with a screen-space lens flare; its position is computed from the simulation clock against standard solar ephemeris. The Moon is rendered as a true 3D body with its own phase texture and lit by the same scene Sun — its phase matches reality on any given date.
SatRadar runs on six platforms: web (WebGL2), iPhone, iPad, Mac, Apple TV, Apple Vision Pro (all Metal), and macOS as a screensaver. The same orbital math runs on every one. We verify this with a visual regression suite: identical scenes captured headlessly on every platform every push, pixel-diffed against a known-good baseline, with AI-assisted validation for the inevitable sub-pixel WebGL nondeterminism.
View the visual regression dashboard →
Native is Swift 6 with SwiftUI for the UI layer and Metal for the rendering. Web is hand-written JavaScript with WebGL2 — no React, no bundler, no framework. The screensaver is a tiny NSView host around the same Metal renderer the Mac app uses. Shared orbital math lives in OrbitCore, a Swift Package; the JavaScript port is hand-written but verified against the same test vectors.
Every piece of data SatRadar shows is publicly available. Nothing is scraped, locked, or proprietary. If you want to build your own satellite tracker, the ingredients are: CelesTrak for TLEs, the published SGP4 algorithm (Vallado et al., 2006) for the math, and a fairly conventional 3D engine. The harder part is making it feel inevitable.
Questions, corrections, or curiosities? Send us a message.