AstroWay/api v2.204.2 · nl
alle systemen normaal

X-Cache header: zichtbare cache-status voor optimalisatie van client-integraties

Elke API-response draagt nu X-Cache: MISS | HIT | BYPASS - de client ziet direct of het verzoek vanaf nul is berekend of uit de cache is opgehaald. Dit opent een cache hit % kolom in /dashboard/usage en maakt het mogelijk om de integratie te optimaliseren zonder gokwerk.

Server-side cache bij ons werkte al lang - een deterministische chart-berekening voor dezelfde date/time/lat/lon wordt uit de cache gehaald, in plaats van opnieuw berekend te worden. Maar de client zag dit niet. In het dashboard toonde de kolom ‘cache hit %’ een streepje (–) omdat de backend de cache-outcome logde naar een interne metric, niet naar het antwoord.

Nu bevat elke reactie één van drie headers:

X-Cache: HIT # обслужено з кешу
X-Cache: MISS # обчислено з нуля, результат збережено
X-Cache: BYPASS # не кешується за дизайном

Dit is een kleine wijziging - de header plus één kolom in api_request_log - maar het opent een hele klasse optimalisaties die eerder een blinde vlek waren.

Terminal window
curl -I -X POST https://api.astroway.info/v1/chart \
-H "X-Api-Key: aw_live_..." \
-H "Content-Type: application/json" \
-d '{
"date": "1990-05-15",
"time": "14:30:00",
"timezoneOffset": 3,
"latitude": 50.45,
"longitude": 30.52
}' | grep -i x-cache
# X-Cache: MISS

Voer een tweede keer uit met hetzelfde aanvraagbody:

Terminal window
# X-Cache: HIT

Voor endpoints van het type /v1/transits/now (dynamische tijd) - X-Cache: BYPASS, omdat het resultaat afhangt van de huidige Date.now() en cachen geen zin heeft.

Niet alle endpoints worden gecached - en dat is opzettelijk. Overzicht:

  • Deterministische chart-berekeningen (/v1/chart, /v1/houses, /v1/aspects, /v1/synastry, /v1/dasha/*, /v1/vargas/*) - worden volledig gecached. Verwacht MISS → HIT patroon.
  • Time-dependent (/v1/transits/now, /v1/horoscope/today, /v1/moon/phase-now) - BYPASS. De cache zou slechts correct zijn tot het einde van de minuut, dus het is eenvoudiger om helemaal niet te cachen.
  • AI-generated content (/v1/horoscope/personal, /v1/interpret/*): BYPASS. LLM-antwoorden zijn niet deterministisch, zelfs niet bij dezelfde prompt, cachen = vastleggen van willekeurigheid.
  • Render endpoints (/v1/render/*): MISS/HIT voor sommige, BYPASS voor diegene die grote payloads accepteren (eclipse-path met 500 punten).

De marker voor een specifiek endpoint is direct zichtbaar in de response - je hoeft de documentatie niet te lezen om te zien of het gecached wordt.

Pricing impact: gecachte verzoeken kosten nog steeds

Section titled “Pricing impact: gecachte verzoeken kosten nog steeds”

Dit is het belangrijkste om te begrijpen - gecachte verzoeken blijven credits aftrekken op hetzelfde tier als MISS. Waarom:

  1. Onze pricing is gekalibreerd op de business value van een endpoint, niet op de CPU-kost. /v1/chart kost hetzelfde, of de chart nu opnieuw berekend wordt of uit de cache komt - de client krijgt hetzelfde chart.
  2. Transparantie. We willen geen situatie waarin één gebruikersgroep betaalt voor MISS en een andere voor HIT (theoretisch door ‘geluk met de cache’). Pricing voorspelbaar.
  3. Cache-infrastructuur: het is infra, geen toegevoegde waarde. We subsidiëren het binnen het tier.

Maar dit betekent niet dat X-Cache betekenisloos is in een pricing-context - het laat duidelijk architecturale mogelijkheden zien voor de client (zie volgende sectie).

Vier praktische patronen:

Als je X-Cache: MISS ziet voor een verzoek dat zich kan herhalen (het natal chart van dezelfde persoon), cache het lokaal in Redis/Memcached/IndexedDB. Onze server-side cache heeft een TTL en evict policy - jouw client-side laag met een beheersbare TTL voorkomt onnodige credit-aftrek.

import { Astroway } from "@astroway/sdk";
const cache = new Redis();
const client = new Astroway({
apiKey: process.env.ASTROWAY_KEY,
// optional: hook on response headers
onResponse(req, res) {
const cacheStatus = res.headers["x-cache"];
metrics.increment(`astroway.cache.${cacheStatus.toLowerCase()}`);
},
});
async function getChart(input: ChartInput) {
const cacheKey = `chart:${hashChart(input)}`;
const cached = await cache.get(cacheKey);
if (cached) return JSON.parse(cached);
const chart = await client.chart.create(input);
await cache.set(cacheKey, JSON.stringify(chart), "EX", 86400);
return chart;
}

Als je service massale verzoeken ontvangt met dezelfde geboortedata (onboarding campagne, waar collegen dezelfde demo-data testen), gebruik dan promise-based dedupe:

const inFlight = new Map<string, Promise<Chart>>();
function getChart(input: ChartInput) {
const key = hashChart(input);
if (inFlight.has(key)) return inFlight.get(key)!;
const promise = client.chart.create(input);
inFlight.set(key, promise);
promise.finally(() => inFlight.delete(key));
return promise;
}

Dit bespaart geen credits (elke aanroep wordt nog steeds meegeteld), maar het verwijdert knelpunten bij concurrentiepieken.

Als er in het product rituele charts zijn (populaire dagelijkse horoscooptekens), pre-warm ze dan met een geplande cron. De eerste aanroep van de dag is MISS, alle volgende tot de evict zijn HIT. De gebruiker krijgt een subsecond response.

4. Dashboard-inzicht: waar je te veel betaalt

Section titled “4. Dashboard-inzicht: waar je te veel betaalt”

De nieuwe kolom cache hit % in /dashboard/usage per endpoint laat zien:

  • HIT% = 90+ - de endpoint wordt goed gecached, waarschijnlijk wordt hetzelfde chart meerdere keren verzonden. Overweeg client-side dedupe (#2).
  • HIT% = 0 en BYPASS: de endpoint wordt niet gecached qua ontwerp (transits/now, AI). Dit is normaal.
  • HIT% = 50% en MISS: de helft van de verzoeken heeft unieke parameters, de helft: herhalingen. Het loont om een client-side cache te gebruiken.
  • Lage HIT% + deterministisch endpoint: verdacht. Controleer of je client geen willekeurige velden toevoegt aan de payload (timestamps, request-id) die de cache-sleutel verstoren.

Technische implementatie: voor de nieuwsgierigen

Section titled “Technische implementatie: voor de nieuwsgierigen”

Tracking kost één kolom in api_request_log.cache_status (enum: MISS|HIT|BYPASS, migratie 030). De kolom wordt gevuld vanuit dezelfde handler die het besluit neemt over de cache-lookup - er wordt geen extra DB-query uitgevoerd.

GET /v1/me/usage/endpoints retourneert nu een echt cache_hit_pct in plaats van null voor elk endpoint in jouw geschiedenis. De SDK-methode client.me.usage.endpoints() krijgt dit veld automatisch (typen in de volgende codegen-release).

Cache-instrumentatie opent een tussenliggend optimalisatieniveau tussen ‘geen caching’ en ‘volledige edge cache’. Volgende stappen op de roadmap:

  • Cache-Control response-header met echt TTL voor gecachte endpoints - stelt CDN/proxy-cache aan clientzijde in staat
  • If-None-Match ETags: herhaalde MISS-controles zonder volledig payload in het antwoord
  • Per-user cache statistics in het dashboard met mogelijkheid tot invalidatie (bijv. geforceerd opnieuw berekenen van bepaalde chart na correctie van geboortetijd)

Documentatie - /docs/api/ → Performance & Caching. Specifieke X-Cache reference - in de headers sectie van elk endpoint.

MakSeong · AstroWay

I build the AstroWay API: Swiss Ephemeris on a clean REST surface, and I write about the dull parts that turn out to matter.

// bouw hierop

Dezelfde Swiss Ephemeris als in Solar Fire - in 4 regels code.

Gratis sleutel zonder kaart. 5.000 calls per maand tot de eerste betaling.

Meer uit de blog alle berichten →

Ephemeris 2026-07-19

Hoe we de nauwkeurigheid onder controle houden: CI versus swetest en NASA

De nauwkeurigheid van onze astro-API kan gemakkelijk afnemen door één refactor van de ephemerides. We analyseren de beveiliging: één Swiss Ephemeris-kern voor de app en de API, honderden gefreezeerde snapshot's op referenties en triangulatie van elk PR tegen swetest CGI, Kerykeion, Prokerala en het catalogus van NASA-sterren.

Engineering 2026-07-15

Drie officiële SDK's: TypeScript, Python, PHP in plaats van rauwe curl

Rauwe HTTP werkt, maar een getypeerde client bespaart uren: autocompletion voor paden, request- en responstypes, ingebouwde retry voor 408/409/429/5xx en Stainless-style foutenhiërarchie. We bespreken de drie officiële SDK's - @astroway/sdk (npm), astroway (PyPI), astroway/sdk (Packagist) - en hoe ze zijn gegenereerd uit één OpenAPI-contract.

Industry 2026-06-05

Free Astrology API: Which One Has the Best Free Tier in 2026?

A side-by-side of free tiers across the major astrology APIs - credits, request caps, card requirements - and how much you can actually build for free.