AstroWay/api v2.204.2 · de
alle Systeme in Ordnung

X-Cache header: sichtbarer Cache-Status zur Optimierung von Client-Integrationen

Jede API-Response trägt jetzt X-Cache: MISS | HIT | BYPASS – der Client sieht sofort, ob die Anfrage neu berechnet oder aus dem Cache gezogen wurde. Das eröffnet die Spalte cache hit % im /dashboard/usage und ermöglicht die Optimierung der Integration ohne Guesswork.

Der serverseitige Cache funktionierte bei uns schon lange – eine deterministische Chart-Berechnung für dieselbe date/time/lat/lon wird aus dem Cache zurückgegeben, statt neu berechnet zu werden. Aber der Client sah das nicht. Im Dashboard zeigte die Spalte „cache hit %“ – an, weil das Backend das Cache-Ergebnis in eine interne Metrik und nicht in die Antwort protokollierte.

Jetzt enthält jede Response einen von drei Headern:

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

Das ist eine kleine Änderung – ein Header plus eine Spalte in api_request_log – aber sie eröffnet eine ganze Klasse von Optimierungen, die zuvor ein blinder Fleck waren.

Terminal-Fenster
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

Führe es ein zweites Mal mit demselben Request-Body aus:

Terminal-Fenster
# X-Cache: HIT

Für Endpoints wie /v1/transits/now (dynamische Zeit) – X-Cache: BYPASS, da das Ergebnis vom aktuellen Date.now() abhängt und Caching keinen Sinn macht.

Nicht alle Endpoints werden gecacht – und das ist Absicht. Die Aufschlüsselung:

  • Deterministische Chart-Berechnungen (/v1/chart, /v1/houses, /v1/aspects, /v1/synastry, /v1/dasha/*, /v1/vargas/*) – werden vollständig gecacht. Erwartetes MISS → HIT Muster.
  • Zeitabhängige (/v1/transits/now, /v1/horoscope/today, /v1/moon/phase-now) – BYPASS. Der Cache wäre nur bis zum Ende der Minute korrekt, daher ist es einfacher, überhaupt nicht zu cachen.
  • KI-generierte Inhalte (/v1/horoscope/personal, /v1/interpret/*): BYPASS. LLM-Antworten sind selbst bei identischem Prompt nicht deterministisch, Caching würde Zufälligkeit fixieren.
  • Render-Endpoints (/v1/render/*): MISS/HIT für einige, BYPASS für diejenigen, die große Payloads akzeptieren (Eclipse-Pfad mit 500 Punkten).

Der Marker für einen spezifischen Endpoint ist direkt in der Response sichtbar – du musst die Dokumentation nicht lesen, um zu verstehen, ob er gecacht wird oder nicht.

Pricing-Auswirkungen: gecachte Anfragen kosten trotzdem

Abschnitt betitelt „Pricing-Auswirkungen: gecachte Anfragen kosten trotzdem“

Das ist das Wichtigste zu verstehen – gecachte Anfragen ziehen weiterhin Credits ab auf demselben Tier wie MISS. Warum:

  1. Unser Pricing ist auf den Business Value des Endpoints kalibriert, nicht auf die CPU-Kosten. /v1/chart kostet dasselbe, egal ob der Chart neu berechnet wurde oder aus dem Cache kam – der Client hat denselben Chart erhalten.
  2. Transparenz. Wir wollen keine Situation, in der eine Benutzerbasis für MISS bezahlt und eine andere für HIT (theoretisch durch „Glück mit dem Cache“). Pricing ist vorhersehbar.
  3. Cache-Infrastruktur: Das ist Infrastruktur, kein Mehrwert. Wir subventionieren sie im Tier.

Das bedeutet aber nicht, dass X-Cache im Pricing-Kontext bedeutungslos ist – er zeigt sichtbar architektonische Möglichkeiten für den Client auf (siehe nächster Abschnitt).

Vier praktische Muster:

Wenn du X-Cache: MISS für eine Anfrage siehst, die sich im Szenario wiederholen könnte (Geburtskarte derselben Person), cache sie lokal in Redis/Memcached/IndexedDB. Unser serverseitiger Cache hat eine TTL und Evict-Policy – dein clientseitiger Layer mit kontrollierter TTL vermeidet unnötige Credit-Abzüge.

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;
}

Wenn dein Dienst Massenanfragen für dieselben Geburtsdaten empfängt (Onboarding-Kampagne, bei der Kollegen mit denselben Demodaten testen), verwende eine Promise-basierte Deduplizierung:

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;
}

Das spart keine Credits (jeder Aufruf zählt trotzdem), aber es beseitigt Engpässe bei Concurrency-Spitzen.

Wenn es im Produkt rituelle Charts gibt (beliebte Tageshoroskop-Zeichen), wärme sie mit einem geplanten Cron-Job vor. Der erste Aufruf des Tages ist MISS, alle folgenden bis zur Eviction sind HIT. Der Benutzer erhält eine Subsekunden-Antwort.

Die neue Spalte „cache hit %“ in /dashboard/usage pro Endpoint zeigt:

  • HIT% = 90+ – der Endpoint wird gut gecacht, wahrscheinlich wird derselbe Chart mehrmals gesendet. Erwäge clientseitige Deduplizierung (#2).
  • HIT% = 0 und BYPASS: der Endpoint wird designbedingt nicht gecacht (transits/now, AI). Das ist normal.
  • HIT% = 50% und MISS: die Hälfte der Anfragen enthält einzigartige Parameter, die andere Hälfte: Wiederholungen. Ein clientseitiger Cache ist lohnenswert.
  • HIT% niedrig + Endpoint deterministisch: verdächtig. Überprüfe, ob dein Client keine zufälligen Felder in den Payload einfügt (Timestamps, request-id), die den Cache-Schlüssel verstopfen.

Das Tracking kostet eine Spalte in api_request_log.cache_status (Enum: MISS|HIT|BYPASS, Migration 030). Die Spalte wird vom selben Handler gefüllt, der die Cache-Lookup-Entscheidung trifft – es wird keine zusätzliche DB-Anfrage gestellt.

GET /v1/me/usage/endpoints gibt jetzt das tatsächliche cache_hit_pct anstelle von null für jeden Endpoint in deiner Historie zurück. Die SDK-Methode client.me.usage.endpoints() erhält das Feld automatisch (Typen im nächsten Codegen-Release).

Die Cache-Instrumentierung eröffnet eine Zwischenebene von Optimierungen zwischen „kein Caching“ und „vollständigem Edge-Cache“. Die nächsten Punkte auf der Roadmap:

  • Cache-Control-Response-Header mit realer TTL für gecachte Endpoints – ermöglicht CDN/Proxy-Cache auf Clientseite
  • If-None-Match ETags: wiederholte MISS-Prüfungen ohne vollständigen Payload in der Antwort
  • Pro-Benutzer-Cache-Statistiken im Dashboard mit Invalidate-Möglichkeit (z.B. erzwungenes Neuberechnen eines bestimmten Charts nach Korrektur der Geburtszeit)

Dokumentation – /docs/api/ → Performance & Caching. Die spezifische X-Cache-Referenz findest du im Header-Bereich jedes Endpoints.

MakSeong · AstroWay

Ich entwickle das AstroWay API: packe Swiss Ephemeris in reines REST und schreibe über langweilige Details, die eigentlich wichtig sind.

// darauf aufbauen

Derselbe Swiss Ephemeris wie in Solar Fire - in 4 Zeilen Code.

Kostenloser Schlüssel ohne Kreditkarte. 5.000 Aufrufe pro Monat vor der ersten Zahlung.

Mehr aus dem Blog alle Beiträge →

Ephemeris 2026-07-19

Wie wir die Genauigkeit unter Kontrolle halten: CI gegen swetest und NASA

Die Genauigkeit in der Astro-API verfällt leicht nach einem Refaktorings der Ephemeriden. Wir analysieren den Schutz: ein Swiss-Ephemeris-Kern für App und API, hunderte gefrorene Snapshots auf Referenzkarten und die Dreiecksverbindung jedes PR gegen swetest CGI, Kerykeion, Prokerala und das NASA-Schattenkatalog.

Engineering 2026-07-15

Drei offizielle SDK: TypeScript, Python, PHP anstelle des rauen curl

Der räudige HTTP funktioniert, aber der typisierte Client spart Stunden: Autocomplete für Routen, Typen für Anfragen und Antworten, eingebauter retry für 408/409/429/5xx und eine Stahlschicht-Struktur für Fehler. Wir zerlegen die drei offiziellen SDK - @astroway/sdk (npm), astroway (PyPI), astroway/sdk (Packagist) - und aus welchem OpenAPI-Kontrakt sie generiert wurden.

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.