Why capacity and latency collide
The expensive part of a mature cache is often its long tail: product variants, rendered fragments, tenant-specific responses, and objects that are read infrequently but costly to reconstruct. Shortening TTLs or evicting more aggressively frees memory by sending work back to the origin.
An SSD-backed cache only solves that problem if disk-resident reads still fit the application budget. A warm-cache average hides broad key access, cache churn, and the origin traffic that follows timeouts. Compare useful responses delivered before the deadline, rather than stored bytes alone.
DESIGN FOR THIS DATA PATH
Where Lavik fits
Use Lavik as the cache between your application and its origin database or object store. Keep existing cache-aside and invalidation patterns, and move retained values onto NVMe SSD. A larger retained working set gives expensive-to-rebuild objects more room; track hit rate and origin traffic to put a value on that additional coverage.
Best for: Large, rebuildable values; an expensive miss path; and enough retained data for capacity economics to matter.
Design decisions that determine the outcome
Keep cache semantics explicit
Define cache-aside reads, expiry, invalidation, and the stale-value policy in the application. Use versioned keys when a schema or rendering revision changes. Coalesce concurrent misses and bound origin retries so a flush or expiry wave cannot amplify an outage.
Budget fan-out and response size
A page that performs multiple serial lookups has less time available per lookup. Compare bounded MGET batches with your current client behavior, including missing-key handling. Cap response sizes and keep origin time separate from store service time.
Size keys as well as values
Track key count, average key length, value-size percentiles, TTL distribution, memory reservations, and usable SSD headroom. Tiny objects can remain dominated by index and runtime memory; increasing the number of keys is not free.
Try this command pattern
Redis-compatible commandsStart Lavik 0.2.0 with the quick start, then use these example keys to try the basic operations. Each command links to its options and return values.
Show example commands
redis-cli SET catalog:v3:sku42 "{\"name\":\"Trail shoe\",\"version\":3}" EX 300
redis-cli GET catalog:v3:sku42
redis-cli MGET catalog:v3:sku42 catalog:v3:missing
redis-cli DEL catalog:v3:sku42
redis-cli GET catalog:v3:sku42What should decide the migration?
Write down the application budgets before replaying traffic. Validate these criteria in your own system; published benchmarks are a starting point.
Long-tail reads
Replay the same key trace at the retained dataset size; include low-locality and post-restart access.
Application p99/p99.9, timeout rate, and origin QPS stay within the agreed budgets.
Expiry and refill waves
Exercise your real TTL mix, invalidation bursts, and concurrent refill traffic.
Hit rate recovers without saturating the origin or exhausting client retry budgets.
Capacity at target load
Measure resident memory, device occupancy, write traffic, and cost while growing retained objects.
Compare complete deployments at the same latency target and retained dataset, with recovery headroom.
Roll out one cache namespace first. Compare hit rate, origin requests and application p99 at the same TTLs, then extend retention with the capacity you have freed up.
Translate business scale into capacity
Value payload ≈ retained objects × average serialized bytes × live cache versions
lower value-capacity cost
At a 20:1 DRAM/NVMe SSD price per GiB, the same value capacity costs 95% less in media. Plan the complete budget with your actual prices, index memory and replicas.
Calculate your capacity cost →