Server-side कैश हमारे पास बहुत समय से काम कर रहा था - निर्धारित चार्ट-गणना के लिए वही date/time/lat/lon कैश से लौटता है, दोबारा गणना नहीं होती। लेकिन क्लाइंट इसे नहीं देख रहा था। डैशबोर्ड में कॉलम “cache hit %” – दिखा रहा था क्योंकि बैकएंड cache-outcome को आंतरिक मीट्रिक में लॉग कर रहा था, न कि प्रतिक्रिया में।
अब हर response एक में से तीन हेडर ले जाता है:
X-Cache: HIT # обслужено з кешуX-Cache: MISS # обчислено з нуля, результат збереженоX-Cache: BYPASS # не кешується за дизайномयह एक छोटी सी बदलाव है - हेडर प्लस api_request_log में एक कॉलम - लेकिन यह कई ऑप्टिमाइज़ेशन क्लास खोलता है, जो पहले अंधेरे धब्बे थे।
कैसे काम करता है: उदाहरण
Section titled “कैसे काम करता है: उदाहरण”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वही अनुरोध बॉडी के साथ दूसरा बार चलाएँ:
# X-Cache: HIT/v1/transits/now जैसे एंडपॉइंट्स के लिए (डायनामिक टाइम) - X-Cache: BYPASS, क्योंकि परिणाम वर्तमान Date.now() पर निर्भर करता है और कैश करना मतलब नहीं रखता।
कौन से एंडपॉइंट्स क्या लौटाते हैं
Section titled “कौन से एंडपॉइंट्स क्या लौटाते हैं”सभी एंडपॉइंट्स कैश नहीं होते - और यह जानबूझकर है। विभाजन:
- निर्धारित चार्ट-गणनाएँ (
/v1/chart,/v1/houses,/v1/aspects,/v1/synastry,/v1/dasha/*,/v1/vargas/*) - पूरी तरह से कैश होते हैं। अपेक्षित MISS → HIT पैटर्न। - समय-निर्भर (
/v1/transits/now,/v1/horoscope/today,/v1/moon/phase-now) -BYPASS. कैश केवल एक मिनट तक सही हो सकता है, इसलिए पूरी तरह से न कैश करना आसान है। - AI-जनित कंटेंट (
/v1/horoscope/personal,/v1/interpret/*):BYPASS. LLM उत्तर भी समान प्रॉम्प्ट पर निर्धारित नहीं होते, कैश करना = यादृच्छिकता को फिक्स करना। - रेंडर एंडपॉइंट्स (
/v1/render/*): कुछ के लिएMISS/HIT, उन के लिएBYPASSजो बड़े payload (जैसे 500 बिंदुओं वाला eclipse-path) लेते हैं।
एक विशिष्ट एंडपॉइंट का मार्कर response से ही दिखता है - समझने के लिए डॉक्यूमेंटेशन पढ़ने की जरूरत नहीं कि कैश है या नहीं।
प्राइसिंग प्रभाव: कैश किए गए अनुरोध फिर भी लागत हैं
Section titled “प्राइसिंग प्रभाव: कैश किए गए अनुरोध फिर भी लागत हैं”यह समझने के लिए सबसे महत्वपूर्ण बात है - कैश किए गए अनुरोध भी उसी tier पर credits deduct करते हैं जैसे MISS। क्यों:
- हमारी प्राइसिंग endpoint के business value पर calibrated है, CPU-cost पर नहीं।
/v1/chartकी कीमत वही रहती है, चाहे चार्ट दोबारा गणना किया गया हो या कैश से आया हो - क्लाइंट को वही चार्ट मिलता है। - पारदर्शिता। हम नहीं चाहते कि एक user-base MISS के लिए भुगतान करे, और दूसरा HIT के लिए (सैद्धांतिक रूप से “कैश से भाग्यशाली” होने के कारण)। प्राइसिंग पूर्वानुमेय है।
- कैश इन्फ्रास्ट्रक्चर: यह इन्फ्रा है, value-add नहीं। हम इसे tier में सबसिडी देते हैं।
लेकिन इसका मतलब यह नहीं कि X-Cache प्राइसिंग संदर्भ में बेकार है - यह स्पष्ट रूप से क्लाइंट के लिए आर्किटेक्चरल संभावनाएँ दिखाता है (अगले सेक्शन देखें)।
क्लाइंट साइड पर इसे क्या करें
Section titled “क्लाइंट साइड पर इसे क्या करें”चार व्यावहारिक पैटर्न:
1. MISS के लिए क्लाइंट-साइड कैश लेयर
Section titled “1. MISS के लिए क्लाइंट-साइड कैश लेयर”अगर तुम X-Cache: MISS देखते हो किसी ऐसे अनुरोध के लिए जो दोहराया जा सकता है (उसी व्यक्ति का नेटल चार्ट), तो इसे स्थानीय रूप से Redis/Memcached/IndexedDB में कैश करो। Server-side कैश का TTL और evict policy है - तुम्हारा क्लाइंट लेयर नियंत्रित TTL के साथ अतिरिक्त credit-deduct से बचेगा।
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. बैकएंड पर बैच + डेडुप
Section titled “2. बैकएंड पर बैच + डेडुप”अगर तुम्हारा सर्विस समान birth-data पर बड़े पैमाने पर अनुरोध लेता है (ऑनबोर्डिंग कैंपेन जहाँ सहयोगी समान डेमो डेटा से टेस्ट करते हैं), तो प्रॉमिस-आधारित डेडुप उपयोग करो:
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;}यह credits बचाएगा नहीं (हर कॉल फिर भी गिना जाता है), लेकिन concurrency स्पाइक के दौरान जाम हटाता है।
3. महत्वपूर्ण पाथ्स को प्री-वॉर्म करें
Section titled “3. महत्वपूर्ण पाथ्स को प्री-वॉर्म करें”अगर प्रोडक्ट में रिचुअल चार्ट्स हैं (लोकप्रिय daily-horoscope साइन), तो उन्हें scheduled cron से प्री-वॉर्म करो। दिन की पहली कॉल - MISS, evict होने तक सभी अगले - HIT। यूज़र को subsecond response मिलता है।
4. डैशबोर्ड इनसाइट: जहाँ तुम अधिक भुगतान कर रहे हो
Section titled “4. डैशबोर्ड इनसाइट: जहाँ तुम अधिक भुगतान कर रहे हो”/dashboard/usage में नई कॉलम cache hit % प्रत्येक endpoint के लिए दिखाता है:
- HIT% = 90+ - endpoint अच्छी तरह से कैश हो रहा है, संभवतः वही चार्ट कई बार भेजा जा रहा है। client-side डेडुप (#2) पर विचार करो।
- HIT% = 0 और BYPASS: endpoint डिजाइन द्वारा कैश नहीं होता (transits/now, AI)। यह सामान्य है।
- HIT% = 50% और MISS: आधे अनुरोधों में यूनिक पैरामीटर हैं, आधे दोहराव हैं। क्लाइंट-साइड कैश उपयोगी है।
- HIT% कम और endpoint निर्धारित: संदेहजनक। जांचो कि तुम्हारा क्लाइंट payload में रैंडम फील्ड (timestamps, request-id) नहीं जोड़ रहा है, जो कैश-की को भर देते हैं।
तकनीकी इम्प्लीमेंटेशन: जिज्ञासु लोगों के लिए
Section titled “तकनीकी इम्प्लीमेंटेशन: जिज्ञासु लोगों के लिए”Tracking api_request_log.cache_status में एक कॉलम जोड़ता है (enum: MISS|HIT|BYPASS, migration 030). कॉलम उसी हैंडलर से populate होता है जो कैश-lookup का निर्णय लेता है - DB में अतिरिक्त क्वेरी नहीं की जाती।
GET /v1/me/usage/endpoints अब प्रत्येक endpoint के लिए null की बजाय वास्तविक cache_hit_pct लौटाता है। SDK मेथड client.me.usage.endpoints() यह फ़ील्ड ऑटोमैटिकली प्राप्त करेगा (अगले codegen रिलीज़ में टाइप्स)।
आगे क्या
Section titled “आगे क्या”कैश इंस्ट्रूमेंटेशन “no caching” और “full edge cache” के बीच मध्यवर्ती ऑप्टिमाइज़ेशन लेयर खोलता है। रोडमैप में अगले कदम:
Cache-Controlरिस्पॉन्स हेडर वास्तविक TTL के साथ कैश किए गए endpoint-ों के लिए - क्लाइंट साइड पर CDN/proxy-कैश की अनुमति देगाIf-None-MatchETags: पूर्ण payload के बिना दोहराए गए MISS चेक- डैशबोर्ड में Per-user कैश स्टैटिस्टिक्स के साथ invalidate करने की सुविधा (उदाहरण के लिए, birth-time सुधारने के बाद किसी विशेष चार्ट को मजबूरन री-कैल्कुलेट करना)
डॉक्यूमेंटेशन - /docs/api/ → Performance & Caching. विशिष्ट X-Cache रेफ़रेंस - प्रत्येक endpoint के headers सेक्शन में।
वही Swiss Ephemeris जो Solar Fire में है - बस 4 लाइनों के कोड में।
कार्ड के बिना मुफ्त कुंजी। पहले भुगतान तक 5,000 कॉल प्रति माह।