product updates

Swiss Ephemeris in Astrolium: Engineering Walkthrough

How Astrolium's Swiss Ephemeris service works: the Rust rewrite that cut chart calculation from 340 ms to 8 ms, JPL validation, and why we open-sourced the bindings.

Oleg Kopachovets
7 min read
Dense columns of numerical ephemeris data flowing into a digital node diagram

Astrolium rebuilt its ephemeris layer in Rust on top of the Swiss Ephemeris with aggressive caching, and brought average chart calculation time from 340 ms to under 8 ms — without sacrificing accuracy at the arc second level. See features, pricing, and try the Saturn return calculator to feel the difference in your browser.

People ask, sometimes politely and sometimes not, whether Astrolium is "really doing the math" or just calling someone else's API. Short answer: we're really doing the math. Long answer: here's what's inside.

The dependency tree

Astrolium's position calculations bottom out in the Swiss Ephemeris, a C library maintained since 1997 by Astrodienst. It's the de facto standard. Solar Fire uses it, AstroGold uses it, half the open source astrology projects use it. Astrolium uses it too. We're not in the business of re-deriving the JPL DE441 development ephemeris from scratch when an audited library already does that work.

Above Swiss Ephemeris, the stack is ours: Rust bindings (originally written for an open source side project, now upstreamed), a thin position service in Rust, and a TypeScript client library that the Astrolium frontend talks to.

The interesting work isn't in the ephemeris. It's in the layer above the ephemeris: caching, batching, and getting house system math right.

What "computing a chart" actually involves

For a single natal chart, the Astrolium service does:

  • Convert birth date/time/location to Julian Day in the appropriate time scale (UT, ET, TDB)
  • Compute geocentric ecliptic position for 10 planets, plus Chiron, plus the lunar nodes (mean and true)
  • Compute house cusps for the chosen house system, factoring in geographic latitude
  • Compute aspect relationships between every pair of planets, with applying/separating distinction
  • Identify dignities, debilities, and rulerships per planet, both traditional and modern
  • Build the response payload

Steps 2 through 6 each take microseconds. Step 1, perhaps surprisingly, is where the gnarliness lives. Historical timezone data, daylight saving rules that changed mid-century, and locations where the local time was different from the legal time. We use IANA's tzdata, but we patch a few entries. There are roughly 40 edge cases where the published rules don't match contemporaneous legal documents we've checked against.

Time, in particular

Russia in 1918 changed the calendar mid-February. Fourteen days vanish. The Julian Day calculation has to handle that, and many libraries don't. South American countries adjusted timezones repeatedly during the 20th century, often by political decree taking effect within days of announcement. Even Berlin, where I'm writing this, was in the British zone in 1945 and on different DST rules than the rest of Germany for a year.

None of this matters for charts after 2000. All of it matters for natal charts of clients born before 1980. Astrolium stress-tested 50,000 historical births against three other ephemeris implementations; positions agree to 4 decimal places in 99.97% of cases, and the remaining 0.03%, invariably, are timezone disputes where Astrolium and at least one other tool disagree on which legal time was actually in force.

House systems, calmly

House calculation is where most astrology software either gets it right and quietly, or gets it wrong and noisily. Astrolium did a lot of the latter on the way to the former.

Whole sign is trivial: cusp equals sign boundary. Placidus is iterative. There's no closed-form solution; you solve for a specific arc-time relationship using Newton's method or similar. Regiomontanus is geometric and runs in closed form once you have the right rotations. Alcabitius involves trisecting a particular arc and is also closed-form. Campanus is closed-form but the geometry is unintuitive.

House systemAlgorithmClosed-formMedian (μs)p99 (μs)
Whole signSign boundary lookupyes0.40.6
EqualAscendant + 30°yes0.50.7
PorphyryQuadrant trisectionyes34
AlcabitiusArc trisectionyes69
CampanusPrime vertical rotationyes914
RegiomontanusEquator rotationyes1218
PlacidusNewton iterationno180640
KochNewton iterationno210720

The bug we shipped in v0.16.4 was in Placidus iteration: at extreme latitudes (above 60°), the iteration occasionally converged to a local minimum instead of the global one, producing a house cusp that was 30° off. Caught during a stress test of charts in Tromsø and Reykjavík; fixed by widening the search interval and adding a second pass refinement. The fix added 200 microseconds to high-latitude calculations, which is fine. Read whole sign default for the reasoning on which system Astrolium ships as the default.

Caching, the boring part

Roughly 80% of Astrolium's position queries are for a small set of dates: the current date, dates within the next 90 days, dates within the previous 90 days. We cache the position-per-day-per-planet for those windows aggressively, and the cache hit rate is around 92%.

Cache misses fall into two buckets: historical births (random distribution, no real pattern) and the long range transit scans for predictive timing (sequential dates, easy to prefetch). Astrolium prefetches the timing scans, which means the dashboard can show 12 months of transits in under 200 ms even on a cold cache. The predictive timing feature is the heaviest user of this.

Validation

Every Astrolium release runs the same validation suite:

  • 10,000 random charts compared against Swiss Ephemeris's own tools. Must agree to 6 decimal places.
  • 500 published example charts from Hellenistic, medieval, and modern textbooks. House cusps must match the published values to 30 arcseconds.
  • Edge case battery: each timezone change we've patched, each historical calendar transition, each pre-1900 chart Astrodienst publishes a worked example for.

The suite takes 4 minutes to run. We block releases on it. It has caught 3 bugs in the last year that would have shipped otherwise.

Performance

The Astrolium position service runs in 1 vCPU containers, two replicas in each region. p50 is 9 ms, p95 is 22 ms, p99 is 41 ms. The slowest queries are full decade transit scans (used by ZR), which we serve in 60 to 80 ms by computing in parallel.

Pre-rewrite, on the old Node + JS bindings, the same workload took 340 ms. Cold cache on the new Rust service is 42 ms. Warm cache, which reflects 92% of production traffic, runs at 8 ms median. That's a 42x improvement from where Astrolium started 6 months ago.

This isn't fast because the math is clever. It's fast because the layer above the math is unremarkable: small services, sensible caching, and a Rust binary that does one thing.

Why we open sourced the bindings

The Rust bindings to Swiss Ephemeris started as a side project before Astrolium existed. They've been used in 3 other open source astrology tools that we know of. Keeping them open means the bindings stay clean (because outside contributors notice when they don't), and it means the underlying math is independently auditable. If you don't trust Astrolium's positions, run the same library and check.

This is the bar Astrolium wants astrology software to be held to. Not "trust the vendor," but "verify the calculation." See the comparison page for how this stacks up against Solar Fire and AstroGold on the audit-trail question.

What we don't do, on purpose

Astrolium doesn't compute heliocentric positions yet. We will eventually. We don't ship hypothetical bodies (Lilith Black Moon mean vs. true is a mess we're staying out of for now). We don't compute Vedic-specific points. The roadmap addresses some of these; some are decided "no" for the foreseeable future.

The principle is: ship what we can audit and explain. The thing we're proudest of is not what's in the ephemeris service. It's that everything in it, we can defend. For the running list of what shipped on which version, the public changelog is the source of truth.

More than a chart calculator.

Astrolium keeps charts, notes, and client work in one place. Mac, PC, tablet.