| Layer | TTL | Notes |
|---|---|---|
| localStorage | full day | Per-device, keyed by date only. Picks don't change mid-day; score strip refreshes independently. |
| picks.json | all day | Disk. Auto-picks keyed as sports:['auto'] per date. Archive guard skips write if all pick keys already seen. Writing invalidates historyCache. |
| autoPicksGenerating | in-flight | In-memory flag. Prevents duplicate Claude calls if two users hit the cold-start at the same time. |
| fixtureSeasonCache | midnight ET / 6h | In-memory, full season per league. MLB 6h for rainouts; NBA/NHL/NFL expire at midnight ET. |
| scheduleCache | 4h | In-memory ESPN fallback, keyed by date+sports |
| oddsCache | 4h | In-memory |
| odds.json | 4h | Disk, keyed by sport:date |
| historyCache | session | In-memory. Only set when today has picks and no past-day picks are pending. Cleared whenever new picks are archived. |
| outcomes.json | 10min / permanent | Disk. Today's picks re-checked every 10 min via __checkedAt__ timestamp. Past days cached indefinitely. |