MicroCache Large Entry Fix - Storage System Intelligence Enhancement
Fix for MicroCache 'Entry too large' warning spam when storing large NGXS state data
🧠 MicroCache Large Entry Fix
Session: gspace-2.1
Date: January 7, 2026
Status: ✅ Complete
Confidence: 98%
📋 Problem Statement
The console was being spammed with warnings:
micro-cache.ts:124 MicroCache: Entry too large for key pages: 227484 bytes (max: 102400 bytes)
This warning appeared frequently because:
- Large NGXS state data (pages, widgets, editor) was ~227KB
- MicroCache is designed for tiny data (< 8KB by default)
- A code path was ignoring the policy engine's decision entirely
🔍 Root Cause Analysis
The Policy Engine Already Does Size Checks!
In policy-engine.ts, the policy engine checks:
const isSmall = size < 8 * 1024; // 8KB
const useMicroCache = strategy === 'speed' &&
isSmall && // ← ALREADY CHECKED!
(isCritical || isUserPref) &&
capabilities.localStorage;
const redundancy = {
localStorage: (isCritical || isUserPref) && isSmall && capabilities.localStorage
// ↑ ALREADY CHECKED!
};
The Actual Bug
The problem was at lines 465-471 in gg-storage.ts:
// THE BUG - This code was ignoring the policy decision!
const shouldUpdateMicroCache = !key.toString().startsWith('flash:');
if (primarySuccess && shouldUpdateMicroCache) {
this.microCache.set(key, value, decision.ttlMs); // WROTE ALL DATA!
}
This was writing ALL successful non-flash writes to MicroCache, regardless of:
- Data size (227KB vs 8KB limit)
- Key type (not critical/user-preference)
- Policy engine's decision (ignored entirely)
✅ Proper Solution (Refactored)
Trust the Policy Engine
Instead of adding duplicate size checks, we trust the policy engine which already validates everything:
// 2. Micro-cache (localStorage) for fast access
// Trust the policy engine - it already checked size, key type, and strategy
const shouldUseMicroCache = decision.target.localStorage === 'micro' &&
!key.toString().startsWith('flash:');
if (shouldUseMicroCache) {
this.microCache.set(key, value, decision.ttlMs);
}
// 6. Redundancy writes for critical data
// Only write if policy decided AND we didn't already write above
if (primarySuccess && decision.redundancy.localStorage && !shouldUseMicroCache && !key.toString().startsWith('flash:')) {
this.microCache.set(key, value, decision.ttlMs);
}
What Was Removed
- ❌ Deleted the buggy "cache update after write" block that ignored policy
- ❌ Removed the
shouldUseMicroCacheForData()helper (duplicate of policy engine logic) - ✅ Added
!shouldUseMicroCachecheck to redundancy path to prevent double writes
MicroCache Warning (Kept)
Made the warning conditional on debug flag (this part is still valid):
if (entrySize > this.maxEntrySize) {
if (typeof window !== 'undefined' && (window as any).__STORAGE_DEBUG__) {
console.debug(`MicroCache: Skipping large entry "${key}": ${Math.round(entrySize / 1024)}KB`);
}
return false;
}
📊 Before vs After
Before (My Initial Fix - Band-Aid)
Policy Engine → makes decision → gg-storage ignores it → adds helper to re-check
↑ REDUNDANT
After (Proper Fix)
Policy Engine → makes decision → gg-storage trusts it
↑ ALREADY VALIDATES SIZE, KEY TYPE, STRATEGY
📁 Files Modified
| File | Changes |
|---|---|
gg-storage.ts |
Removed buggy cache-update block, trust policy engine |
micro-cache.ts |
Made warning conditional on __STORAGE_DEBUG__ flag |
🎯 Result
- ✅ No more warning spam in console
- ✅ ~30 lines removed (simpler code)
- ✅ No duplicate size estimation (performance improvement)
- ✅ Single source of truth (policy engine)
- ✅ No double micro-cache writes
📚 Lesson Learned
Don't add layers on top of layers. Find the root cause.
The policy engine was doing its job correctly. The bug was code that bypassed it entirely. The fix is to remove the bypass, not to add another layer of validation.
📚 Related Documentation
Decision Logged: dev_1767824909021_g8khy4x (initial), refactored after self-review
MCP Confidence: 98%
Total Time: ~45 minutes (including self-critique and refactor)