← All work

Shubh Bhagya

Gives away what other astrology sites charge for: kundli, matching, dashas, numerology, muhurat and dosha calculators, and unlimited questions answered — computed properly, cited, and free with no signup.

free · no signupAI product engineering

Python · FastAPI · Swiss Ephemeris · Cloud Run · Firebase Hosting · GCS · LLM readings

₹0
For everything, no signup
76
Cited explainers
13s→1s
Homepage, 32 storage ops → 0

The problem

Indian astrology sites monetise the same way: a free chart, then a paywall in front of everything a person actually came for. The reading is truncated, the matching report costs money, asking a question costs more, and the muhurat calculator is behind a subscription. What is free is usually not computed — generic text keyed off a sun sign.

So the reader gets the worst of both: the accurate part is paid, and the free part is not accurate.

What it does

Shubh Bhagya gives the whole thing away. Janma Kundli, Vimshottari Dasha periods, daily and yearly readings, Ashtakoot matching for marriage, a muhurat finder, Manglik and Sade Sati and other dosha checks, numerology, a festival calendar and a daily Panchang. All of it free, no signup, no upsell at the end.

It also answers questions. A reader can ask about their own chart in plain language and get a real answer grounded in their computed positions — the feature most platforms meter by the question, because it is the one people will pay for.

The 76 explainers exist because a claim without an explanation is a fortune cookie. Someone told they have Manglik dosha needs to know what that rests on, cited to the classical tradition rather than asserted.

Computed, not generated

Giving it away only means anything if it is right. Most free astrology is wrong in ways a practitioner spots instantly — tropical maths presented as sidereal, ayanamsa applied inconsistently, dasha periods that do not add up.

So the order is inverted from the usual: get the astronomy right first, then let a model write about what the chart actually says. Positions come from Swiss Ephemeris at sidereal Lahiri ayanamsa; houses, aspects, dashas and doshas are computed in code. The model never calculates anything — it receives structured chart data and writes prose about it, drawing on a knowledge base built from seven classical source texts.

Making free sustainable

The economics only work because most of the product costs nothing to serve. Chart maths, panchang, muhurat, dosha checks and numerology are pure computation — no model call, no marginal cost, and identical for everyone asking the same question, so they cache hard.

Model calls are reserved for the parts that genuinely need language: the written reading, and answering a reader's own question. Even there the cost is squeezed — a lower reasoning setting cut completion tokens by roughly a factor of ten while increasing the useful output, and an empty completion now raises instead of silently returning nothing, because a blank reading once got cached and served for a full day.

Everything runs on free tiers, and the constraint shapes the design rather than being worked around.

The hard part: knowing when the model is wrong

This is the section I would want a client to read, because it is the part nobody writes about honestly.

A festival table shipped with 9 of 17 dates wrong — by up to 21 days — under a header claiming a provenance it did not have. A transit-favourability panel was keyed from the wrong reference point and 62.5% of its verdicts were inverted. A retrograde-combustion rule shipped with invented degree values before it was traced to a 1948 source and corrected.

None of those were caught by reading the code, and none announced themselves. They were caught by checking output against sources — which is now the discipline rather than an afterthought. Every astrological claim must trace to the knowledge base, and any almanac or muhurat date must be checked against a real source with that source recorded beside it.

The failure pattern is always the same: write the justification down, then treat the writing as the fact. It produced a fabricated spec and a fabricated citation in this codebase before it was named. Whenever the justification for something is a sentence you authored, that is the signal to stop.

A guard that does not guard is worse than none

The test suite's docstring claimed it needed no network and no API key. Nothing enforced that claim, and over time nine tests drifted into making real network calls while five more came to depend on a live key.

The result was that a clean checkout produced 14 failures that were not defects — so every person and every agent touching the repo had to diagnose a red suite before being told to work around it.

The fix was two fixtures that make the claim true by construction, cut deliberately narrow: the real astronomical computation still runs so the assertions still mean something, and only the single outbound call is stubbed. One detail worth copying — the fixture overrides a real API key rather than supplying one when absent, so a developer with live credentials cannot have a forgotten stub quietly spend paid quota.

A rule that lives only in prose is not a rule. If it matters, something has to enforce it; otherwise it decays into a false assurance, which is worse than no assurance at all.

Tests that are all real defects

The behaviour suite is small on purpose: every test in it is a defect that actually shipped. Eleven landed across four QA rounds while a dozen data-validation gates saw nothing, because they were checking data and the bugs were in request paths — cache lifecycle, degraded pages, error reporting.

A mutation harness re-breaks each of those defects and asserts the suite goes red. It immediately caught two tests that reimplemented the logic inside the test body and would therefore have passed forever. A test that cannot fail is worse than no test, because it is counted as coverage.

Free tier as a design constraint

The GCS bucket sits in the US because that is where the free tier is; Cloud Run runs in Mumbai because that is where the readers are. Every bucket round-trip therefore pays cross-continent latency, and the constraint cannot be designed away — only designed around.

It bit hard once: the homepage took roughly 13 seconds because it made about 30 sequential bucket round-trips per render. The fix took it under one second by removing them — 32 storage operations to zero — not by moving anything or adding a cache in front. Six cache layers now sit between a reader and anything remote, and negative results are cached briefly rather than permanently, because caching a failure for a day pins a reader to a wrong answer.

Scheduled work targets Cloud Run directly rather than going through Firebase Hosting, whose 60-second rewrite ceiling silently killed longer jobs. The daily rashifal generation was one 399-second request; splitting it into a warm phase and a send phase brought it to 83 seconds plus 130.

From birth data to a reading

  1. Ephemeris

    Deterministic

    Sidereal Lahiri positions from Swiss Ephemeris

  2. Chart rules

    Testable

    Houses, aspects, dashas, doshas computed in code

  3. Knowledge

    ~88k lines

    Classical rules retrieved from seven source texts

  4. Reading

    LLM

    Prose written about a chart already computed

  5. QA loop

    Findings → issues

    Golden charts checked against panels and rules

The model never computes anything. It writes about output that deterministic code produced — and a QA loop checks the prose against the panels beside it, because a reading that contradicts its own chart destroys trust faster than being wrong outright.

Building something in this shape?