DynamicWhere.ex
DynamicWhere.exv2.1.0·docs

Cache Warmup

Warmup pre-populates the reflection cache at application startup so that the first user request doesn't pay the per-property reflection cost. Without warmup, the cache fills lazily — every previously-unseen type or path triggers a single reflection pass before the cached result is available.

Why warm up?

  • First-request latency — the very first dynamic query against a type performs reflection inline. For complex types or deep property paths, that adds tens of milliseconds.
  • Cold-start consistency — after a process restart or scale-out event, the new instance starts with an empty cache. Warmup makes every instance behave identically from request #1.
  • Predictable timings in load tests — eliminates the "first request is mysteriously slower" anomaly.

Generic warmup

Use the generic overload when you know the entity type at compile time. Pass one or more property paths — dotted paths are supported.

// Generic warmup
CacheExpose.WarmupCache<Product>("Name", "Category.Name", "Price");
CacheExpose.WarmupCache<Order>("Customer.Name", "OrderItems.Product.Name");

Non-generic warmup

Use the non-generic overload when the type is only known at runtime — for example, when warming up types discovered via assembly scanning or configuration files.

// Non-generic warmup
CacheExpose.WarmupCache(typeof(Customer), "Name", "Email", "Address.City");
Note
Warmup is idempotent. Calling it multiple times with the same arguments is safe — entries already in the cache are simply touched (which refreshes LRU timestamps and increments LFU counters).

When to warm up

Warm up at process startup, after configuring the cache and before accepting requests. In ASP.NET Core, a hosted service or a one-shot call right before app.Run() works well:

var app = builder.Build();

CacheExpose.Configure(CacheOptions.ForHighFrequencyAccess());

// Warm the entity types this service queries the most
CacheExpose.WarmupCache<Customer>("Name", "Email", "Address.City");
CacheExpose.WarmupCache<Order>("OrderDate", "Customer.Name", "OrderItems.Product.Name");
CacheExpose.WarmupCache<Product>("Name", "Price", "Category.Name");

app.Run();

What warmup populates

For each (Type, path) pair, warmup touches all three stores it might end up using:

  • TypeProperties — for every type along the path.
  • PropertyPath — the validated and normalized path string.
  • CollectionElementType — for any collection segment in the path (e.g. OrderItems).