Server-side cache di kami sudah berjalan lama - perhitungan chart yang deterministik untuk date/time/lat/lon yang sama dikembalikan dari cache, bukan dihitung ulang. Tapi klien ini tidak melihatnya. Di dashboard kolom “cache hit %” menampilkan – karena backend mencatat cache-outcome ke metrik internal, bukan ke respons.
Sekarang setiap respons membawa salah satu dari tiga header:
X-Cache: HIT # обслужено з кешуX-Cache: MISS # обчислено з нуля, результат збереженоX-Cache: BYPASS # не кешується за дизайномIni adalah perubahan kecil - header ditambah satu kolom di api_request_log - tetapi ini membuka seluruh kelas optimisasi yang sebelumnya menjadi buta.
Bagaimana cara kerjanya: contoh
Section titled “Bagaimana cara kerjanya: contoh”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: MISSJalankan lagi dengan body permintaan yang sama:
# X-Cache: HITUntuk endpoint typu /v1/transits/now (waktu dinamis) - X-Cache: BYPASS, karena hasilnya bergantung pada Date.now() saat ini dan tidak ada gunanya untuk melakukan caching.
Endpoint mana yang mengembalikan
Section titled “Endpoint mana yang mengembalikan”Tidak semua endpoint di-cache - dan ini sengaja. Pembagian:
- Perhitungan chart deterministik (
/v1/chart,/v1/houses,/v1/aspects,/v1/synastry,/v1/dasha/*,/v1/vargas/*) - di-cache sepenuhnya. Diharapkan pola MISS → HIT. - Bergantung pada waktu (
/v1/transits/now,/v1/horoscope/today,/v1/moon/phase-now) -BYPASS. Cache bisa saja benar hanya sampai akhir menit, sehingga lebih mudah tidak melakukan caching sama sekali. - Konten yang dihasilkan AI (
/v1/horoscope/personal,/v1/interpret/*):BYPASS. Respons LLM tidak deterministik bahkan dengan prompt yang sama, caching = mengunci keacakan. - Endpoint render (
/v1/render/*):MISS/HITuntuk beberapa,BYPASSuntuk yang menerima payload besar (eclipse-path dengan 500 titik).
Marker untuk endpoint spesifik terlihat langsung dari respons - tidak perlu membaca dokumentasi untuk mengetahui apakah di-cache atau tidak.
Dampak harga: permintaan yang di-cache masih tetap membebani biaya
Section titled “Dampak harga: permintaan yang di-cache masih tetap membebani biaya”Ini adalah hal terpenting untuk dipahami - permintaan yang di-cache terus mengurangi credits pada tier yang sama seperti MISS. Mengapa:
- Pricing kami dikalibrasi berdasarkan nilai bisnis endpoint, bukan biaya CPU.
/v1/chartbiayanya sama, entah chart dihitung ulang atau diambil dari cache - klien menerima chart yang sama. - Transparansi. Kami tidak ingin situasi di mana satu basis pengguna membayar untuk MISS, sementara yang lain membayar untuk HIT (teoretis melalui “beruntung dengan cache”). Harga menjadi dapat diprediksi.
- Infrastrukture cache: ini infrastruktur, bukan nilai tambah. Kami menyubsidikannya dalam tier.
Tapi ini tidak berarti X-Cache tidak berarti dalam konteks pricing - ia jelas menunjukkan kemampuan arsitektur untuk klien (lihat bagian berikutnya).
Apa yang harus dilakukan dengan ini di sisi klien
Section titled “Apa yang harus dilakukan dengan ini di sisi klien”Empat pola praktis:
1. Lapisan cache sisi klien untuk MISS
Section titled “1. Lapisan cache sisi klien untuk MISS”Jika kamu melihat X-Cache: MISS untuk permintaan yang bisa berulang (peta natal orang yang sama), simpan secara lokal di Redis/Memcached/IndexedDB. Server-side cache kami memiliki TTL dan kebijakan evict - lapisan cache sisi klien kamu dengan TTL yang terkontrolasi akan menghindari pengurangan kredit yang berlebihan.
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;}2. Batch + dedupe di backend
Section titled “2. Batch + dedupe di backend”Jika layanan kamu menerima permintaan massal dengan data lahir yang sama (kampanye onboarding, tempat rekan-rekan menguji dengan data demo yang sama), gunakan dedupe berbasis promise:
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;}Ini tidak menghemat credits (setiap pemanggilan masih dihitung), tetapi menghilangkan bottleneck saat lonjakan concurrency.
3. Pre-warm jalur kritis
Section titled “3. Pre-warm jalur kritis”Jika di produk ada chart ritual (tanda horoscope harian yang populer), lakukan pre-warm dengan cron yang dijadwalkan. Pemanggilan pertama hari - MISS, semua berikutnya hingga evict - HIT. Pengguna mendapatkan respons subdetik.
4. Wawasan dashboard: di mana kamu membayar lebih
Section titled “4. Wawasan dashboard: di mana kamu membayar lebih”Kolom baru cache hit % di /dashboard/usage per endpoint menampilkan:
- HIT% = 90+ - endpoint sudah di-cache dengan baik, kemungkinan chart yang sama dikirim beberapa kali. Pertimbangkan client-side dedupe (#2).
- HIT% = 0 dan BYPASS: endpoint tidak di-cache oleh desain (transits/now, AI). Ini normal.
- HIT% = 50% dan MISS: setengah permintaan membawa parameter unik, setengah: ulangan. Layak dilakukan client-side cache.
- HIT% rendah + endpoint deterministik: mencurigakan. Periksa apakah klien kamu tidak menambahkan field acak ke payload (timestamps, request-id) yang mengisi kunci cache.
Implementasi teknis: untuk yang penasaran
Section titled “Implementasi teknis: untuk yang penasaran”Tracking membutuhkan satu kolom di api_request_log.cache_status (enum: MISS|HIT|BYPASS, migrasi 030). Kolom diisi oleh handler yang sama yang mengambil keputusan tentang cache-lookup - tidak ada query tambahan ke DB.
GET /v1/me/usage/endpoints sekarang mengembalikan nilai nyata cache_hit_pct alih-alih null untuk setiap endpoint dalam riwayat kamu. Metode SDK client.me.usage.endpoints() akan mendapatkan field secara otomatis (tipe dalam rilisan codegen berikutnya).
Apa selanjutnya
Section titled “Apa selanjutnya”Instrumentasi cache membuka tingkat optimisasi antara “no caching” dan “full edge cache”. Langkah selanjutnya dalam roadmap:
Cache-Controlheader respons dengan TTL nyata untuk endpoint yang di-cache - akan mengizinkan CDN/proxy cache di sisi klien.If-None-MatchETags: pemeriksaan MISS berulang tanpa payload lengkap dalam respons.- Statistik cache per pengguna di dashboard dengan kemampuan invalidate (misalnya, paksa menghitung ulang chart tertentu setelah memperbaiki waktu lahir).
Dokumentasi - /docs/api/ → Performance & Caching. Referensi spesifik X-Cache - di bagian headers tiap endpoint.
Swiss Ephemeris yang sama dengan Solar Fire - dalam 4 baris kode.
Kunci gratis tanpa kartu. 5.000 panggilan per bulan sebelum pembayaran pertama.