[{"data":1,"prerenderedAt":547},["ShallowReactive",2],{"navigation_docs":3,"-essentials-caching":111,"-essentials-caching-surround":542},[4,20,30,66,82,89,96],{"title":5,"icon":6,"path":7,"stem":8,"children":9,"page":6},"Getting Started",false,"\u002Fgetting-started","1.getting-started",[10,15],{"title":11,"path":12,"stem":13,"icon":14},"Installation","\u002Fgetting-started\u002Finstallation","1.getting-started\u002F1.installation","i-lucide-download",{"title":16,"path":17,"stem":18,"icon":19},"Quick start","\u002Fgetting-started\u002Fquick-start","1.getting-started\u002F2.quick-start","i-lucide-rocket",{"title":21,"icon":22,"path":23,"stem":24,"children":25,"page":6},"Concepts","i-lucide-compass","\u002Fconcepts","2.concepts",[26],{"title":27,"path":28,"stem":29,"icon":22},"How it works","\u002Fconcepts\u002Fhow-it-works","2.concepts\u002F1.how-it-works",{"title":31,"icon":32,"path":33,"stem":34,"children":35,"page":6},"Essentials","i-lucide-book-open","\u002Fessentials","3.essentials",[36,41,46,51,56,61],{"title":37,"path":38,"stem":39,"icon":40},"Sources","\u002Fessentials\u002Fsources","3.essentials\u002F1.sources","i-lucide-layers",{"title":42,"path":43,"stem":44,"icon":45},"Filament UI","\u002Fessentials\u002Ffilament-ui","3.essentials\u002F2.filament-ui","i-lucide-layout-dashboard",{"title":47,"path":48,"stem":49,"icon":50},"Refining the timeline","\u002Fessentials\u002Frefining-the-timeline","3.essentials\u002F3.refining-the-timeline","i-lucide-filter",{"title":52,"path":53,"stem":54,"icon":55},"Customization","\u002Fessentials\u002Fcustomization","3.essentials\u002F4.customization","i-lucide-paintbrush",{"title":57,"path":58,"stem":59,"icon":60},"Caching","\u002Fessentials\u002Fcaching","3.essentials\u002F5.caching","i-lucide-database",{"title":62,"path":63,"stem":64,"icon":65},"Configuration","\u002Fessentials\u002Fconfiguration","3.essentials\u002F6.configuration","i-lucide-settings",{"title":67,"icon":68,"path":69,"stem":70,"children":71,"page":6},"Recipes","i-lucide-chef-hat","\u002Frecipes","4.recipes",[72,77],{"title":73,"path":74,"stem":75,"icon":76},"CRM person feed","\u002Frecipes\u002Fcrm-person-feed","4.recipes\u002F1.crm-person-feed","i-lucide-users",{"title":78,"path":79,"stem":80,"icon":81},"Audit log for admins","\u002Frecipes\u002Faudit-log-for-admins","4.recipes\u002F2.audit-log-for-admins","i-lucide-shield",{"title":83,"path":84,"stem":85,"children":86,"icon":88},"Testing","\u002Ftesting","5.testing\u002F1.index",[87],{"title":83,"path":84,"stem":85,"icon":88},"i-lucide-flask-conical",{"title":90,"path":91,"stem":92,"children":93,"icon":95},"Troubleshooting","\u002Ftroubleshooting","6.troubleshooting\u002F1.index",[94],{"title":90,"path":91,"stem":92,"icon":95},"i-lucide-life-buoy",{"title":97,"path":98,"stem":99,"children":100,"page":6},"Community","\u002Fcommunity","7.community",[101,106],{"title":102,"path":103,"stem":104,"icon":105},"Contributing","\u002Fcommunity\u002Fcontributing","7.community\u002F1.contributing","i-lucide-heart-handshake",{"title":107,"path":108,"stem":109,"icon":110},"License","\u002Fcommunity\u002Flicense","7.community\u002F2.license","i-lucide-scale",{"id":112,"title":57,"body":113,"description":533,"extension":534,"links":535,"meta":536,"navigation":537,"path":58,"seo":538,"stem":59,"__hash__":541},"docs\u002F3.essentials\u002F5.caching.md",{"type":114,"value":115,"toc":527},"minimark",[116,130,197,204,229,241,315,319,325,333,336,405,423,427,437,440,443,449,523],[117,118,119,120,124,125,129],"p",{},"Caching is ",[121,122,123],"strong",{},"opt-in per call"," — disabled by default. Reach for it on hot pages where the timeline doesn't change often: audit views, public profiles, dashboards rendered on every request. The simplest form wraps a ",[126,127,128],"code",{},"paginate()"," in a TTL:",[131,132,137],"pre",{"className":133,"code":134,"language":135,"meta":136,"style":136},"language-php shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","$entries = $record->timeline()->cached(ttlSeconds: 300)->paginate();\n","php","",[126,138,139],{"__ignoreMap":136},[140,141,144,148,152,155,158,161,164,168,171,174,177,181,184,188,191,194],"span",{"class":142,"line":143},"line",1,[140,145,147],{"class":146},"sMK4o","$",[140,149,151],{"class":150},"sTEyZ","entries ",[140,153,154],{"class":146},"=",[140,156,157],{"class":146}," $",[140,159,160],{"class":150},"record",[140,162,163],{"class":146},"->",[140,165,167],{"class":166},"s2Zo4","timeline",[140,169,170],{"class":146},"()->",[140,172,173],{"class":166},"cached",[140,175,176],{"class":146},"(",[140,178,180],{"class":179},"sBMFI","ttlSeconds",[140,182,183],{"class":146},":",[140,185,187],{"class":186},"sbssI"," 300",[140,189,190],{"class":146},")->",[140,192,193],{"class":166},"paginate",[140,195,196],{"class":146},"();\n",[198,199,201],"h2",{"id":200},"cachedint-ttlseconds",[126,202,203],{},"->cached(int $ttlSeconds)",[117,205,206,207,210,211,213,214,217,218,221,222,224,225,228],{},"Position in the chain: call ",[121,208,209],{},"before"," ",[126,212,128],{}," or ",[126,215,216],{},"get()",". It has no effect on ",[126,219,220],{},"count()"," (which runs through ",[126,223,216],{}," un-cached internally — see ",[226,227,48],"a",{"href":48}," for why).",[117,230,231,232,235,236,240],{},"The cache lookup uses the active store, configured via ",[126,233,234],{},"cache.store"," (see ",[226,237,239],{"href":238},"#configuration-knobs","Configuration knobs"," below).",[242,243,246,255],"callout",{"color":244,"icon":245},"info","i-lucide-lightbulb",[117,247,248,254],{},[121,249,250,253],{},[126,251,252],{},"cached(0)"," is a no-op."," The TTL=0 short-circuit is intentional — useful for conditionally enabling cache via a flag without changing the call site:",[131,256,258],{"className":133,"code":257,"language":135,"meta":136,"style":136},"$record->timeline()\n    ->cached(ttlSeconds: $cacheEnabled ? 300 : 0)\n    ->paginate();\n",[126,259,260,273,306],{"__ignoreMap":136},[140,261,262,264,266,268,270],{"class":142,"line":143},[140,263,147],{"class":146},[140,265,160],{"class":150},[140,267,163],{"class":146},[140,269,167],{"class":166},[140,271,272],{"class":146},"()\n",[140,274,276,279,281,283,285,287,289,292,295,297,300,303],{"class":142,"line":275},2,[140,277,278],{"class":146},"    ->",[140,280,173],{"class":166},[140,282,176],{"class":146},[140,284,180],{"class":179},[140,286,183],{"class":146},[140,288,157],{"class":146},[140,290,291],{"class":150},"cacheEnabled ",[140,293,294],{"class":146},"?",[140,296,187],{"class":186},[140,298,299],{"class":146}," :",[140,301,302],{"class":186}," 0",[140,304,305],{"class":146},")\n",[140,307,309,311,313],{"class":142,"line":308},3,[140,310,278],{"class":146},[140,312,193],{"class":166},[140,314,196],{"class":146},[198,316,318],{"id":317},"cache-key-composition","Cache key composition",[117,320,321,322,324],{},"Each cached ",[126,323,128],{}," call composes its key from the subject, the active filter set, and the page coordinates:",[131,326,331],{"className":327,"code":329,"language":330,"meta":136},[328],"language-text","{prefix}:{model_class}:{key}:{filter_hash}:p{page}:pp{perPage}\n","text",[126,332,329],{"__ignoreMap":136},[117,334,335],{},"Where:",[337,338,339,354,375,385,395],"ul",{},[340,341,342,345,346,349,350,353],"li",{},[126,343,344],{},"{prefix}"," — the ",[126,347,348],{},"cache.key_prefix"," config value (default ",[126,351,352],{},"'activity-log'",").",[340,355,356,359,360,363,364,367,368,371,372,353],{},[126,357,358],{},"{model_class}"," — the subject's class name with ",[126,361,362],{},"\\"," replaced by ",[126,365,366],{},"_"," (so ",[126,369,370],{},"App_Models_User"," rather than ",[126,373,374],{},"App\\Models\\User",[340,376,377,380,381,384],{},[126,378,379],{},"{key}"," — ",[126,382,383],{},"$subject->getKey()",".",[340,386,387,390,391,394],{},[126,388,389],{},"{filter_hash}"," — a stringified hash of all builder filters: ",[126,392,393],{},"between",", type allow\u002Fdeny, event allow\u002Fdeny, sort direction, source count.",[340,396,397,400,401,404],{},[126,398,399],{},"{page}"," and ",[126,402,403],{},"{perPage}"," — pagination params.",[117,406,407,408,411,412,411,415,418,419,422],{},"Changing any filter — ",[126,409,410],{},"->ofType(...)",", ",[126,413,414],{},"->between(...)",[126,416,417],{},"->sortByDateAsc()"," — produces a different key, so re-running the same builder with different chain state does ",[121,420,421],{},"not"," collide on a stale entry.",[198,424,426],{"id":425},"invalidation","Invalidation",[117,428,429,432,433,436],{},[126,430,431],{},"$record->forgetTimelineCache()"," invalidates only this subject's cached timeline pages. It tracks the keys it writes in a per-subject index entry (",[126,434,435],{},"{prefix}:{model_class}:{key}:index",") and forgets exactly those keys plus the index — sessions, queue locks, and other application caches in the same store are untouched.",[117,438,439],{},"Alternative: skip explicit invalidation and pick a TTL short enough that staleness is acceptable (e.g. 60 seconds for a high-traffic dashboard) and let entries expire naturally.",[198,441,239],{"id":442},"configuration-knobs",[117,444,445,446,384],{},"Short reference here; the full table lives on ",[226,447,448],{"href":448},"\u002Fessentials\u002Fconfiguration#cache",[450,451,452,468],"table",{},[453,454,455],"thead",{},[456,457,458,462,465],"tr",{},[459,460,461],"th",{},"Key",[459,463,464],{},"Default",[459,466,467],{},"Effect",[469,470,471,487,510],"tbody",{},[456,472,473,478,484],{},[474,475,476],"td",{},[126,477,234],{},[474,479,480,483],{},[126,481,482],{},"null"," (default cache)",[474,485,486],{},"Which Laravel cache store to use.",[456,488,489,494,499],{},[474,490,491],{},[126,492,493],{},"cache.ttl_seconds",[474,495,496],{},[126,497,498],{},"0",[474,500,501,502,505,506,509],{},"Reserved; not currently consulted by ",[126,503,504],{},"TimelineCache",". The per-call ",[126,507,508],{},"->cached($ttl)"," is the working knob.",[456,511,512,516,520],{},[474,513,514],{},[126,515,348],{},[474,517,518],{},[126,519,352],{},[474,521,522],{},"Namespace for cache keys.",[524,525,526],"style",{},"html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":136,"searchDepth":275,"depth":275,"links":528},[529,530,531,532],{"id":200,"depth":275,"text":203},{"id":317,"depth":275,"text":318},{"id":425,"depth":275,"text":426},{"id":442,"depth":275,"text":239},"Opt-in per-call caching, key composition, and invalidation caveats.","md",null,{},{"icon":60},{"description":539,"ogImage":540,"title":57},"Per-call caching, cache key composition, and per-subject invalidation in relaticle\u002Factivity-log.","\u002Fpreview.png","ZB8b5Wfu2aK3n-Rb6lJlkK99_WLcn7UpUva5uH6L5v8",[543,545],{"title":52,"path":53,"stem":54,"description":544,"icon":55,"children":-1},"Custom renderers, registration channels, and Tailwind theme integration.",{"title":62,"path":63,"stem":64,"description":546,"icon":65,"children":-1},"Full reference for config\u002Factivity-log.php.",1780504149910]