The application has 140 master_* tables containing reference data (statuses, types, priorities, etc.). These are
queried millions of times but rarely change — some are truly static (genders, states, countries), others are
modified every few weeks (task statuses, case statuses).
Approach: Cache::flexible() (Laravel 11's stale-while-revalidate) at the model level via a shared trait.
// Trait added to all Master* models
Cache::flexible('master_smart_texts:pluck', [3600, 86400], fn () => ...);
- Fresh for 1 hour — guaranteed current data
- Stale-but-served for 24 hours — if the cache expires, users get the stale value instantly while it refreshes in the background. No one waits for a DB query.
- Event-based invalidation — when an admin modifies a master record, the cache busts immediately via model
saved/deletedevents. Doesn't rely on TTL alone.
Why not rememberForever? Some tables do get modified (task statuses was changed 5 days ago). The 1-hour fresh
window ensures changes propagate even if we miss an invalidation edge case.
Implementation:
- Create
CachesMasterDatatrait — providescachedPluck(), cachedGet()methods (~1 file) - Add trait to ~20 master models that are actually queried
- Find-and-replace call sites across ~230 files (mechanical — same patterns repeated)
- Extend existing
CachesIdByNametrait to also useCache::flexiblefor cross-request persistence - Dashboard chart widgets (11 files) — same
Cache::flexiblewrap on expensive aggregate queries
What this eliminates:
- 179 master data queries per page load across all routes
- 3.5M+ redundant queries per 2 days from Livewire interactions
- Dashboard from 2,446ms TTFB to potentially ~200ms (chart queries cached)
Production-ready: Redis is already configured as the cache store in all non-local environments. No infrastructure changes needed.