# Caching Opportunities Analysis

> Analysis of where caching can improve performance and reduce costs

**Generated:** Jan 19, 2026
**Status:** Reference Document

---

## Current Caching (Already Implemented)

| What | TTL | Location |
|------|-----|----------|
| Intel briefs | 2hr | Lead record (`ai_intel_brief`) |
| Company research | 30 days | `company_intel` table |
| Person research | 30 days | `lead_intel` table |
| Frontend queries | 30s-5min | React Query |
| CallPrepPage intel | 4hr | localStorage |

---

## High-Impact Opportunities

### 1. Similar Wins Query (30 min cache)
**Impact:** HIGH - Called 3-5x per lead session
**Savings:** 40% reduction in AI service load
**Downside:** Patterns only update on new conversions (acceptable)

### 2. Dashboard Stats (60 sec cache)
**Impact:** HIGH - 15 Supabase queries per refresh
**Savings:** 90% fewer dashboard queries
**Downside:** Data up to 60 sec stale (acceptable for UI)

### 3. Script Recommendations (24hr cache)
**Impact:** MEDIUM - GPT-4o called for same lead repeatedly
**Savings:** Significant OpenAI cost reduction
**Downside:** Needs invalidation on lead score change

### 4. Objection Responses by Type (30 min)
**Impact:** MEDIUM - Live copilot faster
**Savings:** 150ms per repeated objection type
**Downside:** Minor stale risk

---

## Critical Bugs Found

### N+1 Query in `findSimilarLeads()`
```
Current:  10 similar leads = 11 queries (1 select + 10 fetches)
Should be: 1 batch query with array of lead IDs
```
**Location:** `src/services/ai.js` lines 2085-2175

### Duplicate Query in Dashboard
```
Line 137: Queries today's wins
Line 286: Queries same data again
```
**Location:** `src/routes/dashboard.js`

---

## Consequences Summary

| Adding Cache | Benefit | Downside |
|--------------|---------|----------|
| Similar wins | 40% less AI load | 30min stale patterns |
| Dashboard stats | 90% fewer queries | 60sec stale data |
| Script cache | Less OpenAI cost | Need invalidation logic |
| Communications | Faster lead opens | Need realtime invalidation |

---

## Estimated Gains

| Opportunity | Time Saved | Frequency |
|-------------|------------|-----------|
| Similar wins cache | 200ms × 5 calls/session | Every lead |
| Dashboard stats cache | 800ms × 1 call | Every refresh |
| N+1 fix | 2s × bulk sends | 2-3×/week |
| Communications batch | 300ms × 3 fetches | Per lead open |

**Total:** 500-1500ms faster responses, 40-50% fewer queries

---

## Implementation Priority

1. **Dashboard stats cache (60 sec)** - Simple in-memory TTL
2. **Remove duplicate today's wins query** - 1 line fix
3. **Fix N+1 in findSimilarLeads** - Batch query
4. **Similar wins cache (30 min)** - Map with TTL

---

## Technical Notes

- No Redis currently - would need to add or use Node's Map with TTL
- React Query already handles frontend well
- Perplexity caching works well (30 day TTL)
- Main gap is backend in-memory caching layer
