Astrology Data Sources and Calculation Methodology

What Zodiux runs on, where each dataset came from, how often it refreshes, and what goes wrong when a refresh does not happen.

Zodiux calls no astrology API. There is no chart service behind it, no licensed data feed, and no vendor whose output we reprint. The whole site runs on four datasets and two pieces of code: an open-source ephemeris, a city list with time-zone names, your browser's own copy of the time-zone rules, a precomputed sky almanac, a corpus of written interpretations, and a published scoring formula. This page names each one, says where it came from, gives its measured size, says how often it changes, and says what it gets wrong. It also states the update record plainly, including the five weeks a scheduled refresh job failed silently and froze the sky on every page it was supposed to keep current.

The six sources, in one table

Read this table first. Everything after it is one of these rows in detail.

Two of the six are code rather than data — the ephemeris computes positions instead of storing them, and the compatibility score is a formula with no dataset behind it at all. Both are listed anyway. A source-transparency page that quietly omits the parts that are not files is not being transparent.

Every source Zodiux uses, what it drives, and how often it changes
SourceWhat it drivesWhere it came fromRefresh triggerKnown limitation
Astronomy EngineEvery planetary position on the site: birth charts, moon sign, the live sky, retrograde datesOpen-source library by Don Cross, MIT-licensed, copied into this repository as two filesOnly when we deliberately update the vendored copy. Never at runtimeThe rising-sign step holds the obliquity of the ecliptic at a fixed 23.4367 degrees instead of varying it
City listThe birth-city typeahead: latitude, longitude, and which time zone your birth time is read inFiltered from the GeoNames cities5000 export by a script in this repositoryOnly when we re-run that script against a fresh GeoNames dump. Not on a schedule35,968 cities, so villages and small towns are missing. Coordinates are rounded to two decimals
Time-zone rulesConverting your wall-clock birth time into the UTC instant the astronomy needsThe IANA time-zone database, as shipped inside your own browser. Zodiux carries no copyWhenever your browser or operating system updates. Nothing on our side controls itWe cannot pin its version, audit it, or fix it. Two visitors can hold different releases of it
Sky almanacThe Today's sky strip on the 12 sign pages and 32 learn pagesPrecomputed at build time from the same ephemeris, one row per dayRebuilt on every deploy; a scheduled job runs daily at 13:17 UTCA 150-day horizon. Past it the strip stops claiming a date rather than printing a stale one
Interpretation corpusThe written reads on sign, compatibility, decan and learn pages, and inside paid reports487 reviewed units committed to this repository, 47 of them hand-authored, the rest machine-drafted against those and gatedEdited unit by unit. Nothing is generated at read timeIt is prose about traditional meanings, not a measurement. It cannot be checked the way a longitude can
Compatibility modelThe four dimension scores and the overall figure on the 78 sign-pair pagesA deterministic formula over element, modality and sign distance. No dataset at allChanges only if we change the formula, and then every affected page is rewritten in the same editOn those 78 pages it reads two sun signs and nothing else. See how compatibility scores work

The last row needs one clarification, because the same word covers two different things. The 78 static pages, one per sign pair, are scored from sun signs alone. The two-chart compatibility calculator is a different model: it computes both full charts in your browser and scores the real aspects between them, so it is reading twenty placements rather than two. Only the first of those is a published formula.

The ephemeris, and what is actually inside it

Planetary positions come from Astronomy Engine, an MIT-licensed open-source library by Don Cross. Every position on Zodiux traces back to it — your birth chart, your moon sign, today's sky, and the Mercury retrograde tracker. There is no lookup table anywhere on the site and no second source that could disagree with the first. What the library is asked for, and what happens to the answer, is set out step by step in how Zodiux calculates a birth chart; this page is about the library itself.

"One library" is accurate but it hides something a source page ought to say: the ten bodies are not all computed the same way. Reading the vendored file, three different methods are in there.

Vendored twice, on purpose, and served from our own origin

The library is committed to this repository in two forms. A minified browser build of 116 KB is served to the calculator and the retrograde tracker. An ES module of 412 KB is imported by the static build that writes these pages. Both are files in this repository, pinned to the same version, and the browser copy is loaded from a path on zodiux.io.

Two files rather than one is a bundling decision, not a second source. The library ships no version string, so “the same version” is not something either of us can check — what is checkable is that both files are committed here, both are fingerprinted, and the positions they produce agree. Nothing in the build enforces that agreement, so it is a property to re-verify rather than a guarantee to lean on. The reason it is vendored at all is that a third party then cannot change what your chart says, and an outage elsewhere cannot take the calculator down.

It also makes the numbers checkable, which is the only claim on this page that you can test without our cooperation. Take a birth moment, convert it to UTC, ask any ephemeris you trust for the apparent geocentric ecliptic longitude of a body, and compare. If your answer differs from ours by more than rounding, one of us has a bug and we would like to know which: hello@zodiux.io. That offer means something only because the code on both sides of it is readable — a hosted chart API's approximations are not something you can inspect.

Three models under one interface

None of that changes an answer you would notice at the 30-degree resolution of a zodiac sign. It is here because "which ephemeris" is the question this page exists to answer, and "Astronomy Engine" on its own is only two-thirds of the answer.

The city and time-zone dataset

The birth-city box is a typeahead over a single file in this repository, built from the GeoNames cities5000 export by a script that lives beside it. The raw GeoNames dump is not committed; only the compact file the browser loads is.

The selection rule is a deliberate choice rather than a default, so it is worth stating exactly. The generator keeps every city in the world with a population of 20,000 or more, plus every place with a population of 5,000 or more in the United States, Canada, the United Kingdom, Australia, New Zealand and Ireland. That second clause exists because a flat 20,000 threshold drops a great many American and British towns that people actually name as a birthplace. The script also evaluates three rival thresholds on every run and prints their row counts and file sizes next to the chosen one, so the trade-off is visible rather than assumed.

What the shipped file contains, counted from the file itself

The dataset carries no time-zone rules. It carries one zone name per city — America/Chicago, Asia/Kolkata — and the actual UTC offset for your birth date is resolved by your browser's own copy of the IANA time-zone database, through the standard date-formatting API. That split is the single most consequential architectural decision on this page, and it cuts both ways: Zodiux inherits every historical daylight-saving correction your operating system receives without us shipping an update, and Zodiux cannot pin a version, audit a rule, or fix a case the database gets wrong. Two people on different devices can in principle be running different releases of it. What that database does and does not know is covered on birth time, time zones and DST.

The daily sky almanac

The Today's sky strip that sits at the top of the 12 sign pages and 32 learn pages is baked into the HTML at build time. That is good for crawlers, which get real content instead of an empty container, and it used to be the site's most embarrassing accuracy problem. A baked strip is correct only on the day it was built, and only the homepage loaded the ephemeris needed to correct one. The homepage therefore showed the live sky while 44 other pages asserted a months-old one.

Shipping a 116 KB ephemeris to every page to refresh a decorative strip would have been a poor trade. So the build precomputes an almanac instead: one row per day for the next 150 days, written to a plain script file. Each row is seven values — moon phase index, moon sign index, phase fraction, a Mercury retrograde flag, Mercury's sign index, the Sun's sign index, and the date the current Sun season ends. Sign and phase names are stored once as separate arrays and referenced by index, which is why the whole file is 4.5 KB, about 1.1 KB gzipped.

What happens when you open one of those pages

  1. The page arrives with a baked strip and the ISO date it was baked on, held in a data attribute so nothing has to parse the human-readable stamp.
  2. A 3.4 KB script — 1.6 KB gzipped — compares that date with today. If the page was built today, it returns before touching the DOM and costs nothing at all.
  3. Otherwise it indexes into the almanac by your own calendar day — the rows are computed for midday UTC, but the lookup counts days in your local time zone — reads today's row, and rewrites the moon phase, moon sign, Mercury status and sign, Sun season and the visible stamp in place.
  4. If today falls outside the 150-day horizon, or the almanac file is missing, the strip drops its date claim entirely, relabels itself a snapshot, and links to today's sky instead.

That last step is the one worth noticing. The failure mode was chosen deliberately: stop asserting a date we cannot support, rather than print one that is wrong. A stale claim of freshness is worse than an admission of staleness.

Two things the almanac is not. It is not the ephemeris — it holds no positions, only the handful of derived facts the strip displays, which is why it fits in a kilobyte. And it does not cover every page: the decan pages, the compatibility pages and the live sky page carry no strip and no almanac, so nothing on them self-corrects between deploys.

Retrograde dates are computed, not stored

The Mercury retrograde tracker stores no dates. It has no table of periods, no annual list someone typed in, and no API call. It runs the vendored ephemeris in your browser and finds the stations itself, which means the page has no data source to name — only a method.

The method is short enough to describe completely. Starting 220 days before the moment you loaded the page, it takes 651 daily samples of Mercury's ecliptic longitude, ending about 430 days ahead. For each sample it subtracts that day's longitude from the next day's, wraps the difference into the range minus 180 to plus 180 degrees, and marks the day retrograde when the result is negative — Mercury losing ground against the zodiac. Consecutive retrograde days are paired into periods, the period containing the current moment becomes the yes-or-no answer at the top of the page, and the table lists every period whose end is no more than 45 days in the past. A typical 651-day scan finds about six retrograde periods of 20 to 24 days each; the table shows the four or five of them that have not already ended more than 45 days ago.

The same one-day differencing decides the retrograde marks on your birth chart and on the live sky page, for every body except the Sun and Moon, which are hard-coded as never retrograde because from Earth they never are. One detail differs and is easy to get wrong: the tracker differences forward, comparing a day with the next one, while the chart and the sky strip difference backward, comparing the birth instant with twenty-four hours earlier. Both answer "is it retrograde"; they just straddle the instant from opposite sides.

What day-resolution sampling costs, measured

Because the scan steps a whole day at a time, a station is located to within about a day rather than to the hour. That is easy to say and worth actually measuring, so we replayed the tracker's exact loop against the true stations, found by narrowing in on the instant Mercury's motion crosses zero.

Across the eleven stations in a scan run in August 2026, the reported date landed between 0.6 and 10.9 hours from the true station, averaging 5.5 hours. In every one of those eleven cases the reported calendar date was still the correct one. The sampling is coarse, but on this body at this cadence it is not usually wrong.

There is a second-order effect that is more interesting, because it is visible to two readers comparing notes. The scan is anchored to the moment you load the page, not to midnight, so the grid of sample instants shifts with your visit. Take the retrograde that begins 24 October 2026 at 07:15 UTC and ends 13 November at 15:52 UTC. Both stations fall inside a day rather than on its edge, so the sample either side of the turn can land on one date or its neighbour depending on where the grid happens to sit when you load — and the printed dates are then formatted in your own time zone, which can move a near-midnight station by another day on top of that. We are not going to publish a threshold hour for the flip, because there is not one: it depends on your load time and your offset together, so two readers can see different dates for the same station at the same instant. Same code, same sky, a one-day disagreement with two independent causes.

The interpretation corpus

Everything above is measurement. The written reads — what Venus in Aries means, what a Leo and Scorpio pairing tends to run into, what a decan is about — are not, and what Zodiux does not claim is the page that argues why that distinction matters. What belongs here is the narrower question: what the corpus physically is, how big it is, and where each part of it ends up.

It is 487 reviewed units across six surfaces, all of them JSON files committed to this repository: 120 planet-in-sign reads, 120 planet-in-house reads, 105 aspect reads, 78 sign-pair compatibility reads, 36 decan reads and 28 learn-topic reads. 47 of those are hand-authored exemplars. They are not extra — each one is a member of the 487 that a person wrote directly, and it does double duty as the voice reference for its surface and as the shipped text for that slot.

The 487 do not all travel the same road, and the split is a deliberate size decision rather than an editorial one.

Where each corpus surface ends up
SurfaceUnitsBundled intoReaches you as
Planet in sign120The Worker moduleA paid report, rendered server-side
Planet in house120The Worker moduleA paid report, rendered server-side
Aspect105The Worker moduleA paid report, rendered server-side
Sign-pair compatibility78Read at build timeStatic HTML on the 78 compatibility pages
Decan36Read at build timeStatic HTML on the 36 decan pages
Learn topic28Read at build time, then discardedNone — the editorial library owns all 32 /learn/ URLs, and the builder drops every corpus slug the library covers, which is all 28

The three report surfaces — 345 units — are bundled into a single ES module the Worker imports, because a paid report is assembled on request and needs them in memory. The other 142 are read by the page builder at build time and never enter the Worker bundle at all, which keeps the edge deployment small. The build is fail-closed on this: with the corpus files missing it emits no pages and no sitemap entries rather than shipping empty ones.

The part people most want stated plainly: 47 units were written by a person, and the remaining 440 were drafted by a language model at build time against those exemplars and a fixed brief, then mechanically linted, judged by a different and stricter model, checked for near-duplicates, and signed off by a person before entering the reviewed files. The lint and the judge are code you can read — the banned-phrase list rejects the stars, the universe, cosmic energy, manifest, divine and fixed-fate constructions like you will meet — and the judge scores voice, specificity, thinness and safety independently and defaults to failing. Editorial standards and corrections is where that brief, that pipeline and the human gate are set out in full, including what machine assistance does and does not extend to.

One thing is true of all 487 regardless of who drafted them: none of it runs at read time. There is no model call when you load a page and none when you run a chart. The text is static by the time it reaches you, which is what keeps the site free, fast, and able to work with the network gone.

What Zodiux does not use

The absences are part of the answer, so here they are.

Sources that are not in the stack

Update cadence, and what breaks when a refresh fails

The sources here change on very different clocks, and conflating them would hide the one that actually goes wrong.

The ephemeris and the city list are pinned files. They change when a person deliberately updates them and at no other time — no automatic upgrade, no background fetch, no version that can shift under you between two visits. The time-zone rules are the opposite: they live in your browser and update on your operating system's schedule, entirely outside our control. The sky data is the part on a timer, and it is the part that has failed.

What refreshes, on what trigger, and what a failure looks like
WhatTriggerCadenceWhat you see if it fails
Ephemeris libraryA deliberate version bump, committedNo scheduleNothing. The pinned copy keeps computing
City and time-zone listRe-running the generator against a new GeoNames dumpNo scheduleA recently-grown town may be missing from the typeahead
Sky strip on the 44 baked pagesA scheduled rebuild and deploy, plus the client-side almanacDaily at 13:17 UTC, with a 150-day client-side bufferThe strip self-corrects for up to 150 days, then relabels itself a snapshot
The live sky pageRecomputed in your browser on load; the baked copy is the fallbackEvery visitFalls back to the last deploy's positions, with a visible date showing how stale they are

Here is the failure, stated plainly, because a transparency page that lists only successes is marketing. The scheduled refresh job failed on every run from 6 July 2026 onward, because the deploy credential it needed had never been set. It failed quietly. The live sky froze at 5 July and was still frozen six weeks later, on 17 August, with the credential still unset — while the homepage, which computes the sky in the browser, carried on showing the correct one. Anyone comparing the two pages would have caught it in seconds; nothing in the system was watching, which is the actual defect. The bug was never in the astronomy.

Three things changed as a result, in August 2026. The job now fails loudly with a named cause instead of an authentication stack trace. The cadence moved from weekly to daily, because the strip reports the Moon's phase and sign and those change every day, so a weekly rebuild was wrong six days in seven by construction. And the almanac described above now lets 44 baked pages self-correct in the browser, so a missed deploy degrades gracefully instead of freezing.

The live sky page used to be the exception, and this page said so for as long as it was true. It is now the opposite: /sky/ ships the full browser build of the ephemeris and a script that recomputes the ten-body table, the orrery, the retrograde list and the timestamp in your browser on load, so what you read there is current even when a deploy is not. The baked copy is the fallback rather than the product, and the page still prints a date so a failure of the live path is visible rather than silent. The last-reviewed date at the foot of this page is derived differently again, from a content hash rather than a build timestamp; editorial standards sets out that derivation.

How this page is made

Method. Every figure on this page was read out of the shipped source rather than estimated. City, zone, country and region counts come from evaluating the dataset file the browser downloads and counting its rows; the selection rule and the rival thresholds come from the generator script that wrote it. The three planetary models, the Pluto state table's span and the time-scale correction were read out of the vendored library. File sizes were measured on the shipped files, uncompressed and then gzipped and brotli-compressed. The almanac's horizon, row shape and fallback behaviour come from the build module and the client script that consumes it. The list of which pages carry the sky strip was produced by searching the built output, not assumed from the templates. The retrograde station errors and the load-time effect were measured by replaying the tracker's own loop against stations located by bisection. Corpus counts come from counting the arrays in the reviewed corpus files, and the bundling split from the build script that writes the Worker module. The refresh cadence, the failure window and its cause come from the scheduled job's own configuration.

Limits. This page says where the numbers come from, not what they mean. It cannot tell you whether an interpretation is true, because interpretations are not the kind of claim that has a source you can check — only the astronomy is. It describes the free tools; a paid report is rendered on the server and is covered by the privacy policy. And the counts here are true of the code as shipped on the date at the foot of this page. If a dataset is regenerated the figures move, and this page is meant to move with them. If you find a number here that no longer matches the site, that is a mistake and we want to hear about it at hello@zodiux.io.

Sources.

Written and reviewed by the Zodiux editorial team · Last reviewed · Editorial standards and corrections · Astrology is for reflection and entertainment, not advice.

See the sources produce something

A chart is the shortest way to check this page. It runs the vendored ephemeris in your browser, against the city list described above, and your birth details never leave the device — though pressing the button does send a one-line counter ping saying a chart was run.

Common questions
Does Zodiux use a third-party astrology API?

No. There is no chart service, no ephemeris API and no licensed data feed anywhere in the stack. Positions are computed by an open-source library copied into the site's own repository and served from zodiux.io, both in your browser and in the static build. Nothing about your chart depends on another company staying online or keeping its numbers the same.

Where does the city list come from, and why is my town missing?

It is filtered from the GeoNames cities5000 export: every place in the world of 20,000 people or more, plus every place of 5,000 or more in the US, Canada, the UK, Australia, New Zealand and Ireland. That leaves 35,968 cities, so smaller towns and villages are genuinely absent. Pick the nearest listed city in the same time zone — the coordinates only affect your rising sign, and they affect it weakly, while the time zone affects how every hour you typed is read.

How often does the sky data update?

The site rebuilds and redeploys on a daily schedule at 13:17 UTC, which recomputes the sky baked into every page. On top of that, the 12 sign pages and 32 learn pages carry a 150-day almanac and correct their own Today's sky strip in the browser, so they stay right even if a deploy is missed. The live sky page is the exception: its ten-body table is baked with no client-side fallback, and it prints the date it was built so you can see how fresh it is.

Are the retrograde dates on the tracker exact?

They are accurate to about a day, not to the hour, because the scan samples Mercury's position once every twenty-four hours rather than solving for the exact station. Measured against true stations, the printed dates landed within eleven hours in every case we checked, and on the correct calendar date. The scan is anchored to the moment you load the page, so a station falling near the edge of your day can print one day earlier or later than a visit at a different hour would show.

Which parts of the writing were drafted by a machine?

Of the 487 interpretation units, 47 were written by a person and the remaining 440 were drafted by a language model at build time against those exemplars and a fixed brief, then linted, judged by a different and stricter model, de-duplicated and signed off by a person before publication. No model runs when you load a page, and no number on the site comes from one — positions come from the ephemeris and scores from a published formula. Editorial standards and corrections covers the full process.

Does my birth data go into any of these datasets?

No. The corpus is written against enumerated placements — ten planets across twelve signs and twelve houses — and never against anything a visitor typed. Nothing you enter is added to any file described on this page, used to train anything, or kept as a source. What does happen to your birth details, and what a shared chart link carries, is covered on data, privacy and saved chart links.

Can I check any of these numbers myself?

Yes, and that is the point of naming the sources. The ephemeris is open source, so any figure it produces can be reproduced in a different implementation of the same algorithms. The compatibility formula is published table by table. The counts on this page came from counting rows in the files the site actually ships. If you get a different answer from ours, email hello@zodiux.io — corrections get made and dated.

Keep reading

All astrology guides How Zodiux works