mirror of
https://github.com/duthaho/claudekit.git
synced 2026-07-17 13:15:16 +03:00
feat: improved the Claude Kit as a plugin
This commit is contained in:
@@ -0,0 +1,201 @@
|
||||
# Caching Decision Tree
|
||||
|
||||
## Primary Decision Tree
|
||||
|
||||
```
|
||||
What are you caching?
|
||||
│
|
||||
├─ PURE FUNCTION RESULT (same input = same output)
|
||||
│ │
|
||||
│ ├─ In React component?
|
||||
│ │ └─ useMemo(() => compute(data), [data])
|
||||
│ │
|
||||
│ ├─ Expensive computation called repeatedly?
|
||||
│ │ └─ Memoize the function
|
||||
│ │ Python: @functools.lru_cache or @functools.cache
|
||||
│ │ JS: hand-rolled Map cache or lodash.memoize
|
||||
│ │
|
||||
│ └─ Shared across requests/processes?
|
||||
│ └─ Use external cache (Redis) -- see below
|
||||
│
|
||||
├─ HTTP RESPONSE (browser or CDN caching)
|
||||
│ │
|
||||
│ ├─ Is it public (same for all users)?
|
||||
│ │ │
|
||||
│ │ ├─ Static asset (JS, CSS, images)?
|
||||
│ │ │ └─ Cache-Control: public, max-age=31536000, immutable
|
||||
│ │ │ (Use content hash in filename for busting)
|
||||
│ │ │
|
||||
│ │ ├─ API response that changes occasionally?
|
||||
│ │ │ └─ Cache-Control: public, max-age=60, stale-while-revalidate=300
|
||||
│ │ │ + ETag or Last-Modified for conditional requests
|
||||
│ │ │
|
||||
│ │ └─ HTML page?
|
||||
│ │ └─ Cache-Control: public, max-age=0, must-revalidate
|
||||
│ │ + ETag (let CDN/browser validate freshness)
|
||||
│ │
|
||||
│ └─ Is it private (user-specific)?
|
||||
│ └─ Cache-Control: private, max-age=60
|
||||
│ (Never cache auth tokens or sensitive data at CDN)
|
||||
│
|
||||
├─ DATABASE QUERY RESULT (shared across requests)
|
||||
│ │
|
||||
│ ├─ Read-heavy, rarely changes?
|
||||
│ │ └─ Redis/Memcached with TTL
|
||||
│ │ Pattern: Cache-aside (read-through)
|
||||
│ │
|
||||
│ ├─ Must always be fresh?
|
||||
│ │ └─ Don't cache. Optimize the query instead.
|
||||
│ │ (Add indexes, denormalize, materialized view)
|
||||
│ │
|
||||
│ └─ Needs real-time invalidation?
|
||||
│ └─ Write-through cache or event-driven invalidation
|
||||
│ (Update cache when DB changes)
|
||||
│
|
||||
├─ EXTERNAL API RESPONSE
|
||||
│ │
|
||||
│ ├─ API has rate limits?
|
||||
│ │ └─ Cache aggressively. Respect Cache-Control from API.
|
||||
│ │ Fallback: cache with reasonable TTL (5-60 min)
|
||||
│ │
|
||||
│ ├─ API is slow (>500ms)?
|
||||
│ │ └─ Cache + stale-while-revalidate pattern
|
||||
│ │ Serve stale, refresh in background
|
||||
│ │
|
||||
│ └─ API data is critical and must be fresh?
|
||||
│ └─ Short TTL (10-30s) + circuit breaker on failure
|
||||
│
|
||||
└─ EDGE/CDN CACHING
|
||||
│
|
||||
├─ Global audience, same content?
|
||||
│ └─ CDN with long TTL + purge on deploy
|
||||
│ (Cloudflare, CloudFront, Vercel Edge)
|
||||
│
|
||||
├─ Personalized at edge?
|
||||
│ └─ Edge compute (Cloudflare Workers, Vercel Edge Functions)
|
||||
│ Cache shared parts, inject personalization
|
||||
│
|
||||
└─ A/B testing at edge?
|
||||
└─ Vary by cookie or header
|
||||
Vary: Cookie (careful: reduces cache hit rate)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Cache-Aside Pattern (Most Common)
|
||||
|
||||
```
|
||||
Read:
|
||||
1. Check cache for key
|
||||
2. HIT --> return cached value
|
||||
3. MISS --> query DB, store in cache with TTL, return value
|
||||
|
||||
Write:
|
||||
1. Update DB
|
||||
2. Delete cache key (don't update -- avoids race conditions)
|
||||
3. Next read will repopulate cache
|
||||
```
|
||||
|
||||
```python
|
||||
# Python + Redis
|
||||
import redis, json
|
||||
|
||||
r = redis.Redis()
|
||||
TTL = 300 # 5 minutes
|
||||
|
||||
def get_user(user_id: str) -> dict:
|
||||
key = f"user:{user_id}"
|
||||
cached = r.get(key)
|
||||
if cached:
|
||||
return json.loads(cached)
|
||||
user = db.query("SELECT * FROM users WHERE id = %s", user_id)
|
||||
r.setex(key, TTL, json.dumps(user))
|
||||
return user
|
||||
|
||||
def update_user(user_id: str, data: dict):
|
||||
db.execute("UPDATE users SET ... WHERE id = %s", user_id)
|
||||
r.delete(f"user:{user_id}") # Invalidate, don't update
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## TTL Strategy Guide
|
||||
|
||||
| Data Type | TTL | Rationale |
|
||||
|-----------|-----|-----------|
|
||||
| User session | 15-60 min | Balance security and UX |
|
||||
| User profile | 5-15 min | Changes infrequently |
|
||||
| Product catalog | 1-5 min | Needs reasonable freshness |
|
||||
| Search results | 30s-2 min | Changes frequently |
|
||||
| Static config | 1-24 hours | Rarely changes |
|
||||
| Feature flags | 30s-1 min | Needs fast propagation |
|
||||
| API rate limit counters | Match the rate limit window | Exact timing matters |
|
||||
| Dashboard aggregations | 1-5 min | Expensive to compute |
|
||||
|
||||
### TTL Anti-Patterns
|
||||
|
||||
| Anti-Pattern | Problem | Fix |
|
||||
|-------------|---------|-----|
|
||||
| No TTL (cache forever) | Stale data, memory leak | Always set a TTL |
|
||||
| TTL too short (<1s) | Cache provides no benefit | Remove cache or increase TTL |
|
||||
| Same TTL for everything | Over/under-caching | Tune per data type |
|
||||
| Stampede on expiry | All caches expire at once, DB overload | Jitter: TTL + random(0, 60s) |
|
||||
|
||||
---
|
||||
|
||||
## Cache Invalidation Strategies
|
||||
|
||||
| Strategy | How | Best For |
|
||||
|----------|-----|----------|
|
||||
| TTL expiry | Automatic, time-based | Most cases |
|
||||
| Explicit delete | Delete key on write | Strong consistency needs |
|
||||
| Write-through | Update cache on every write | Read-heavy, write-infrequent |
|
||||
| Event-driven | Invalidate on DB change event | Microservices |
|
||||
| Version key | Append version to cache key | Bulk invalidation |
|
||||
| Tag-based | Group keys by tag, purge by tag | CDN, grouped content |
|
||||
|
||||
---
|
||||
|
||||
## Cache Headers Quick Reference
|
||||
|
||||
| Header | Example | Purpose |
|
||||
|--------|---------|---------|
|
||||
| `Cache-Control` | `max-age=3600` | Primary caching directive |
|
||||
| `ETag` | `"abc123"` | Content fingerprint for conditional requests |
|
||||
| `Last-Modified` | `Wed, 29 Jan 2025 12:00:00 GMT` | Timestamp for conditional requests |
|
||||
| `Vary` | `Accept-Encoding, Authorization` | Cache varies by these headers |
|
||||
| `CDN-Cache-Control` | `max-age=86400` | CDN-specific (Cloudflare, etc.) |
|
||||
|
||||
### Common Cache-Control Patterns
|
||||
|
||||
```
|
||||
# Immutable static asset (hashed filename)
|
||||
Cache-Control: public, max-age=31536000, immutable
|
||||
|
||||
# API data with background refresh
|
||||
Cache-Control: public, max-age=60, stale-while-revalidate=300
|
||||
|
||||
# Private user data
|
||||
Cache-Control: private, no-cache
|
||||
# (no-cache = must revalidate, NOT "don't cache")
|
||||
|
||||
# Never cache
|
||||
Cache-Control: no-store
|
||||
|
||||
# HTML pages (revalidate every time)
|
||||
Cache-Control: public, max-age=0, must-revalidate
|
||||
ETag: "content-hash-here"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## When NOT to Cache
|
||||
|
||||
| Scenario | Why |
|
||||
|----------|-----|
|
||||
| Data changes on every request | Cache hit rate ~0% |
|
||||
| Data must be real-time consistent | Stale data is unacceptable |
|
||||
| Write-heavy workload | Constant invalidation negates benefit |
|
||||
| Data is cheap to compute/fetch | Cache overhead exceeds savings |
|
||||
| Sensitive data (PII, financial) | Risk of serving wrong user's data |
|
||||
| Early in development | Premature optimization; adds complexity |
|
||||
Reference in New Issue
Block a user