Micro-Cache Multi-Tenant Architecture

Intelligent localStorage micro-cache with multi-tenant support and global clearing

๐Ÿ”„ Micro-Cache Multi-Tenant Architecture

Lightning-fast localStorage caching with complete multi-tenant isolation and nuclear reset capabilities


๐ŸŽฏ Overview

The Micro-Cache system provides ultra-fast localStorage caching with:


๐Ÿ—๏ธ Architecture

Namespace-Based Isolation

localStorage Key Structure:
  gg:mc:{namespace}:{key}
  โ””โ”€โ”ฌโ”€โ”˜ โ””โ”€โ”€โ”ฌโ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”˜ โ””โ”ฌโ”˜
    โ”‚     โ”‚        โ”‚       โ””โ”€ User's key
    โ”‚     โ”‚        โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ Namespace (tenant/space/module)
    โ”‚     โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ Micro-cache prefix
    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ GoGrab system prefix

Examples:


โšก Core Features

1. Namespace Clearing

Clear cache for a specific namespace (tenant):

// Clear current namespace only
microCache.clear();

// Result: Clears only 'gograb-space' namespace
// Other namespaces untouched

2. User-Specific Clearing

Clear cache for a specific user across all namespaces:

// Clear all cache entries for user-123
MicroCache.clearForUser('user-123');

// Clears:
// - gg:mc:gograb-space:space_user-123
// - gg:mc:any-namespace:*user-123*
// - All entries containing 'user-123'

3. Global Nuclear Reset

Clear ALL micro-cache entries across ALL namespaces:

// Nuclear reset - clear everything
MicroCache.clearAllNamespaces();

// Clears ALL entries starting with 'gg:mc:'
// Use only for complete system resets

4. Boot Manifest Clearing

Clear boot manifests for fast hydration:

// Clear all boot manifests
BootManifestManager.clearAllNamespaces();

// Clears ALL entries starting with 'gg:boot:'

๐Ÿš€ Usage Examples

Basic Usage (Single Namespace)

import { MicroCache } from '@storage-system';

// Create instance for a namespace
const cache = new MicroCache('my-app', {
  budget: 100 * 1024,      // 100KB total
  maxEntrySize: 8 * 1024,  // 8KB per entry
  allowLargeEntries: false
});

// Store data
cache.set('user-preferences', userPrefs);

// Retrieve data
const prefs = cache.get('user-preferences');

// Clear this namespace
cache.clear();

Multi-Tenant Usage

// Tenant A's cache
const tenantACache = new MicroCache('tenant-a');
tenantACache.set('config', { theme: 'dark' });

// Tenant B's cache
const tenantBCache = new MicroCache('tenant-b');
tenantBCache.set('config', { theme: 'light' });

// Clear only Tenant A
tenantACache.clear(); // Tenant B unaffected

// Clear specific user across all tenants
MicroCache.clearForUser('user-123'); // Clears user data everywhere

Nuclear Reset (Complete System Clear)

import { GgStorage } from '@storage-system';

// Method 1: Using GgStorage static method
GgStorage.nuclearCacheReset();
// Clears: ALL micro-cache + ALL boot manifests

// Method 2: Individual clearing
MicroCache.clearAllNamespaces();      // Clear all micro-cache
BootManifestManager.clearAllNamespaces(); // Clear all boot manifests

// Method 3: User-specific clearing
GgStorage.clearMicroCacheForUser('user-123');

๐Ÿงช Integration with Offline-First Architecture

SyncEngine Integration

The micro-cache works seamlessly with the SyncEngine:

// SyncEngine writes to IndexedDB
await syncEngine.write('space_user-123', spaceData, 'space');

// GgStorage automatically populates micro-cache
// Next read is < 1ms from micro-cache

// On nuclear reset, micro-cache is cleared
GgStorage.nuclearCacheReset();

Flash Persistence Integration

Perfect for autoFlashState:

// autoFlashState uses storage system
const theme = autoFlashState('theme', 'dark');

// Storage system uses micro-cache for hot data
// Result: < 1ms access to persistent signals

// On nuclear reset, Flash Persistence cleared
GgStorage.nuclearCacheReset();

โ˜ข๏ธ Nuclear Reset Workflow

Complete system reset procedure:

async function nuclearReset() {
  // 1. Clear user context
  userContextService.clearUserContext();
  
  // 2. Clear guest sessions
  await guestAuthService.clearSessions();
  
  // 3. Clear Flash Persistence
  await flashStateService.clearAllData();
  
  // 4. Clear space data
  await spaceService.clearAllData();
  
  // 5. Clear sync queue
  syncEngine.clearQueue();
  
  // 6. Clear localStorage (preserve theme, language)
  const preserve = ['theme', 'language'];
  Object.keys(localStorage).forEach(key => {
    if (!preserve.includes(key)) {
      localStorage.removeItem(key);
    }
  });
  
  // 7. Clear sessionStorage
  sessionStorage.clear();
  
  // 8. โ˜ข๏ธ NUCLEAR CACHE RESET
  GgStorage.nuclearCacheReset();
  // Clears ALL micro-cache + boot manifests
  
  // 9. Clear ALL IndexedDB databases
  const dbs = await indexedDB.databases();
  for (const db of dbs) {
    if (db.name) {
      indexedDB.deleteDatabase(db.name);
    }
  }
  
  // 10. Wait for cleanup
  await new Promise(resolve => setTimeout(resolve, 2000));
  
  // 11. Hard reload
  window.location.href = '/landing';
}

๐Ÿ“Š Monitoring & Debugging

Check Cache Status

// Get cache stats
const stats = microCache.getStats();

console.log({
  totalSize: stats.totalSize,        // Current size in bytes
  entryCount: stats.entryCount,      // Number of entries
  hitRate: stats.hitRate,            // Cache hit rate (0-1)
  budgetUsed: stats.budgetUsed,      // Percentage of budget used
  evictions: stats.evictions         // Number of evictions
});

Debug Global State

// Get all micro-cache keys across all namespaces
const allKeys = MicroCache.getAllNamespaceKeys();
console.log('All micro-cache keys:', allKeys);

// Check if cache is leaking between tenants
allKeys.forEach(key => {
  console.log(key);
  // Should see clear namespace separation:
  // gg:mc:tenant-a:...
  // gg:mc:tenant-b:...
});

๐ŸŽฏ Best Practices

1. Namespace Naming

// โœ… GOOD: Clear namespace hierarchy
'gograb-space'              // Main app
'tenant-acme'               // Specific tenant
'user-123'                  // Specific user
'module-singularity'        // Specific module

// โŒ BAD: Ambiguous namespaces
'app'                       // Too generic
'cache'                     // Not descriptive
'data'                      // No context

2. Budget Management

// โœ… GOOD: Conservative budgets per namespace
new MicroCache('my-app', {
  budget: 100 * 1024,       // 100KB - reasonable
  maxEntrySize: 8 * 1024,   // 8KB - prevents single large entry
});

// โŒ BAD: Excessive budgets
new MicroCache('my-app', {
  budget: 10 * 1024 * 1024, // 10MB - too large for localStorage!
  maxEntrySize: 5 * 1024 * 1024, // 5MB entry - kills performance
});

3. Multi-Tenant Isolation

// โœ… GOOD: Separate instances per tenant
const getTenantCache = (tenantId: string) => {
  return new MicroCache(`tenant-${tenantId}`);
};

// Each tenant gets isolated cache
const acmeCache = getTenantCache('acme');
const betaCache = getTenantCache('beta');

// โŒ BAD: Shared cache with manual key prefixing
const cache = new MicroCache('shared');
cache.set(`tenant-acme-data`, data); // Manual isolation = error-prone

4. Nuclear Reset Safety

// โœ… GOOD: Confirm before nuclear reset
if (confirm('โ˜ข๏ธ Nuclear reset? ALL data will be deleted!')) {
  if (confirm('FINAL WARNING: This cannot be undone!')) {
    await nuclearReset();
  }
}

// โŒ BAD: No confirmation
await nuclearReset(); // User data lost without warning!

๐Ÿ”ง Configuration

Standard Configuration

const cache = new MicroCache('namespace', {
  budget: 100 * 1024,           // 100KB total budget
  maxEntrySize: 8 * 1024,       // 8KB max per entry
  allowLargeEntries: false      // Strict 8KB limit
});

Large Entry Support

const cache = new MicroCache('namespace', {
  budget: 200 * 1024,           // 200KB total budget
  maxEntrySize: undefined,      // Auto-calculated
  allowLargeEntries: true       // Allow up to 25% of budget (50KB)
});

Legacy Number Configuration

// Still supported for backwards compatibility
const cache = new MicroCache('namespace', 100 * 1024);
// Equivalent to:
// { budget: 100 * 1024, maxEntrySize: 8 * 1024 }

๐Ÿšจ Troubleshooting

Issue: Cache Persists After Nuclear Reset

Symptoms: Data still visible after nuclear reset

Solution:

// Ensure using GgStorage.nuclearCacheReset()
GgStorage.nuclearCacheReset();

// Verify all cache cleared
const remaining = MicroCache.getAllNamespaceKeys();
console.log('Remaining keys:', remaining); // Should be []

Issue: Cross-Tenant Data Leakage

Symptoms: Tenant A sees Tenant B's data

Solution:

// Always use unique namespaces
const tenantACache = new MicroCache(`tenant-${tenantA.id}`);
const tenantBCache = new MicroCache(`tenant-${tenantB.id}`);

// Never share instances
// โŒ BAD: const cache = new MicroCache('shared');

Issue: localStorage Quota Exceeded

Symptoms: QuotaExceededError

Solution:

// Reduce budgets
const cache = new MicroCache('namespace', {
  budget: 50 * 1024,  // Reduce from 100KB to 50KB
});

// Or enable aggressive eviction
cache.pruneExpired(); // Remove expired entries first

๐Ÿ“ˆ Performance Characteristics

Operation Time Notes
get() < 1ms localStorage read + JSON.parse
set() < 2ms JSON.stringify + localStorage write
clear() < 5ms Remove all namespace entries
clearAllNamespaces() < 50ms Global scan + removal
pruneExpired() < 10ms Scan + remove expired

๐ŸŽ“ Advanced Topics

Custom Eviction Strategy

The micro-cache uses LFU-LRU hybrid eviction:

Score = (accessCount * 0.3) + (recency * 0.7)

TTL Management

// Set with TTL
cache.set('session-token', token, 60 * 60 * 1000); // 1 hour TTL

// Auto-removed after 1 hour
// Or on next pruneExpired() call
cache.pruneExpired();

๐Ÿ“š Related Documentation


Built: November 3, 2025
Status: โœ… Production Ready
Performance: Sub-1ms cache access
Impact: Critical for offline-first architecture


The foundation for lightning-fast data access in the platform builder. โšก