Skip to content

v0.52.0

Choose a tag to compare

@KIvanow KIvanow released this 28 Oct 08:53
3922bc3

This release adds three new pages for AI and caching workloads. KV Cache monitors the LMCache KV cache that vLLM and SGLang keep in Valkey: its footprint, its eviction risk, and the hit rate reported by the linked inference engines. Cache Size Simulator measures what is in an instance today and projects when it will reach maxmemory, and which node sizes would fit. Session Explorer lets you browse agent and chat session history stored by LangChain, LlamaIndex and @betterdb/agent-cache, read-only. The migration tool gains per-shard replication lag and an explicit cutover action for redis_shake_sync, and anomaly detector thresholds can now be edited in Settings.

Upgrades are drop-in. The new storage tables are created on startup and existing data is untouched. One behaviour change to know about: webhook URLs are validated against a stricter blocklist, and deliveries no longer follow redirects (see Security).

Highlights

KV Cache monitoring for vLLM / SGLang (#528, #529, #530, #533)

When LMCache stores KV cache chunks in Valkey, the new KV Cache page shows how much of the instance they use, and whether the cache is earning its keep.

  • Detection and footprint: the page detects LMCache keys written by the redis://, valkey:// and resp:// connectors, and also recognises LMCache GLIDE clients. A budgeted SCAN with sampled MEMORY USAGE covers every cluster primary and reports:
    • chunk count, bytes and share of used memory;
    • a per-model breakdown;
    • TTL coverage;
    • a footprint history chart.
  • Advisories: they flag:
    • chunks that can never be evicted under the current policy (for example volatile-* with no TTLs);
    • orphaned kv_bytes keys with no metadata companion;
    • LMCache keys in other logical databases;
    • active eviction.
  • Hit rate: Valkey can't see cache lookups, so the hit rate (hit tokens / requested tokens) comes from the engine's own lmcache:* counters. Link an engine by Prometheus scrape URL, with an optional auth header and a test scrape, or by OTLP engine id (the betterdb.lmcache.engine resource attribute). The page includes a ready-to-paste OpenTelemetry Collector snippet. Counter resets are handled.
  • Alerts: two new webhook events, kv_cache.hit_rate_low and kv_cache.eviction_risk. They use hysteresis and a minimum token floor, and can be switched per connection. Disabled engines never alert.
  • Metrics: hit rate and footprint are re-exported as betterdb_kv_cache_* to Prometheus and OTLP.
  • Validation: scripts/kv-cache-validate runs an end-to-end check with a real LMCache connector at a known hit ratio.

New configuration (all optional):

  • Footprint scan: KV_CACHE_FOOTPRINT_INTERVAL_MS (at least 60 s), KV_CACHE_SCAN_MAX_KEYS, KV_CACHE_MATCH_MAX_KEYS, KV_CACHE_SAMPLE_KEYS.
  • Engine scrapes: KV_CACHE_SCRAPE_INTERVAL_MS, and KV_CACHE_SCRAPE_BLOCK_PRIVATE to refuse private and loopback scrape targets. Cloud mode always refuses them.
  • Docs: see docs/kv-cache-monitoring.md.

Cache Size Simulator (#536, #537)

The new Cache Size Simulator page answers "when do we run out of memory, and what should we move to?"

  • Current state: shows used memory, maxmemory, eviction policy and key count straight away. It then shows a sampled dataset size with a 95% range and a per-type breakdown.
  • Inputs: growth in keys/day, key TTL, average key size, per-key overhead and maxmemory. They are prefilled from measurements (growth is a least-squares fit over the last 30 days of stored memory history) and editable. Reset to measured restores them.
  • Projection: a 30-day, 90-day or 6-month chart with a 95% band, the maxmemory line and an 80% line. It gives the days until maxmemory and what the current eviction policy will do when it gets there.
  • Node sizing: the smallest AWS, GCP and Azure nodes that keep the 6-month projection under 80% of usable memory.
  • Clusters: every primary is sampled. Maxmemory is summed across primaries, and primaries with different policies are reported as mixed.
  • Docs: see docs/cache-size-simulator.md.

Session Explorer (#551, #552, #553)

The new Session Explorer page is a read-only view of the agent and chat session state your apps keep in Valkey.

  • Namespaces: pick a key pattern and a preset. A live preview shows a sampled key before you save. The presets are:
    • langchain-community, which also covers @langchain/redis;
    • llamaindex (RedisChatStore);
    • agent-cache, for @betterdb/agent-cache / LangGraph checkpoints;
    • raw;
    • custom: a schema form with a {session} id template such as app:{session}:*:messages.
  • Session list: sortable by last access, size or TTL, across all cluster primaries. An Oversize badge flags sessions above a per-namespace threshold.
  • Timeline: messages in conversation order, with tool calls and tool results. Each key also has structured and raw views, and a banner explains when a timeline is incomplete. Sessions can be exported as JSON.
  • Safe reads:
    • Reads are bounded per key and in total, and scans have caps.
    • Reads use a dedicated connection with CLIENT NO-TOUCH ON, so browsing doesn't reset key idle times or skew LRU/LFU eviction. The page warns when that isn't possible, for example on servers before 7.2.
    • Session contents are never logged or stored by the monitor.
  • Loading: data loads on demand. Nothing polls in the background; Refresh rereads.

Migration

  • Per-shard replication lag for redis_shake_sync (#582): the stage chip now shows Lag: <worst> behind, plus "waiting for k of N shards" until every shard has reported. Clicking it opens a per-shard breakdown that flags stale rows. The API gains replicationLag, expectedShards and fullySynced. Closes #568.
  • Explicit Complete cutover action (#584): Stop Migration no longer has to double as "cut over".
    • Complete cutover (POST /migration/execution/:id/complete) waits until every shard's lag stays at 0, then stops RedisShake and marks the job completed.
    • On timeout, the job keeps replicating and reports that it timed out.
    • Force cuts over immediately and records the lag it accepted.
    • Closes #569.
  • Docs: migrating to and from ElastiCache and other managed services (#572): a direction-by-mode table. AWS restricts PSYNC/SYNC, so redis_shake_sync only works with ElastiCache as the target.

Settings

  • Edit anomaly detector thresholds per metric (#550): Settings → Anomaly Detection → Detector thresholds has one panel per metric. Each panel sets warning and critical z-scores, optional absolute thresholds, consecutive breaches and cooldown. Every field shows its default and allowed range, and customised metrics are marked. Single-metric and reset-all buttons restore the defaults. Closes #549.

Reliability & correctness

  • The replication lag alert is released when the master link drops (#543): an alert that fired while lag was high used to stay latched for 24 hours if the link went down, so the next lag episode didn't alert. It now clears when the link is down or the node is promoted. The alert is also tracked per connection, so one replica's lag no longer holds the alert for every connection. Fixes #538.
  • FalkorDB graph keys are sized correctly in key analytics (#564): MEMORY USAGE reports about 32 B for a graph key, so large graphs never showed up among the largest keys. Graph keys now use GRAPH.MEMORY USAGE (cached for an hour) and report node plus edge count as cardinality.
  • docker stop and pod termination are fast and clean (#559): Node runs as PID 1 in the image and ignored SIGTERM, so every stop waited out the grace period and was killed with exit 137. Shutdown hooks now close storage and pollers: docker stop returns in about 160 ms with exit 0, instead of about 10 s.
  • PostgreSQL startup no longer deadlocks when two instances initialise at once (#560): this affected rolling updates and parallel workers. Schema setup and the background index builds (from v0.51.1) are serialised with a per-schema advisory lock, and close() cancels any build still running.
  • close() waits for a cancelled index build to exit (#587): this fixes a deadlock when the schema was dropped right after shutdown, mostly seen in tests.

Security

  • Stricter webhook URL validation (#529): webhooks now share the KV cache scraper's outbound URL guard.
    • Newly blocked: on create or edit, URLs pointing at carrier-grade NAT / Tailscale (100.64.0.0/10), 0.0.0.0/8, all IPv6 unique local addresses (fc00::/7) and extra cloud metadata addresses are rejected.
    • Hostname lookup: hostnames are resolved with dns.lookup, which follows /etc/hosts and the system resolver.
    • Delivery: in production, delivery checks the resolved address at connect time, so a DNS rebind to a blocked address is refused. Redirects are no longer followed.
    • Existing webhooks: they aren't re-validated, but one whose hostname now resolves to a blocked address will fail delivery. A 3xx response marks a delivery as failed.
  • KV cache scrapes pin DNS at connect time (#533): a DNS answer that changes after validation can't reach a refused address.

Known issues

  • "Not detected" on first visit: right after the monitor starts, the KV Cache page can say "No LMCache KV cache detected" until the first footprint scan runs (up to KV_CACHE_FOOTPRINT_INTERVAL_MS, 5 minutes by default). Press Rescan now to scan immediately. Tracked in #591.

Dependencies

  • @modelcontextprotocol/sdk 1.27.1 → 1.32.1 (#556), zod 4.3.6 → 4.6.6 (#580), vite 8.0.16 → 8.1.6 (#555), happy-dom 20.8.9 → 21.0.4 (#579)
  • Python packages: aiohttp 3.14.3 → 3.14.4 in packages/cache-benchmark (#548), certifi 2026.6.17 → 2026.10.19 in packages/agent-memory-py (#563)

What's Changed

  • Monitor LMCache KV cache footprint in Valkey by @jamby77 in #528
  • Track LMCache hit rate from linked vLLM/SGLang engines by @jamby77 in #529
  • Add the KV Cache page, docs and LMCache validation script by @jamby77 in #530
  • Harden KV cache cleanup, cluster evictions, sample limits and scrape DNS by @jamby77 in #533
  • Add Cache Size Simulator snapshot endpoint by @jamby77 in #536
  • Add Cache Size Simulator page by @jamby77 in #537
  • Add session fixture harness and presets by @jamby77 in #551
  • Add Session Explorer API by @jamby77 in #552
  • Add Session Explorer page by @jamby77 in #553
  • Surface per-shard replication lag for redis_shake_sync by @jamby77 in #582
  • Add explicit Complete cutover action for redis_shake_sync by @jamby77 in #584
  • docs: migration directions for ElastiCache and managed sources by @KIvanow in #572
  • Edit per-metric anomaly detector thresholds in Settings by @jamby77 in #550
  • Release the replication lag alert when the master link drops by @jamby77 in #543
  • fix(api): size FalkorDB graph keys with GRAPH.MEMORY USAGE by @KIvanow in #564
  • fix(api): handle SIGTERM so container stops do not wait out the grace period by @KIvanow in #559
  • fix(storage): serialise schema setup and background index builds by @KIvanow in #560
  • Wait for the cancelled index build to exit before close() returns by @jamby77 in #587
  • chore(deps): bump @modelcontextprotocol/sdk from 1.27.1 to 1.32.1 by @dependabot[bot] in #556
  • chore(deps-dev): bump vite from 8.0.16 to 8.1.6 by @dependabot[bot] in #555
  • chore(deps): bump aiohttp from 3.14.3 to 3.14.4 in /packages/cache-benchmark by @dependabot[bot] in #548
  • chore(deps): bump certifi from 2026.6.17 to 2026.10.19 in /packages/agent-memory-py by @dependabot[bot] in #563
  • chore(deps): bump zod from 4.3.6 to 4.6.6 by @dependabot[bot] in #580
  • chore(deps-dev): bump happy-dom from 20.8.9 to 21.0.4 by @dependabot[bot] in #579

Full Changelog: v0.51.1...v0.52.0

What's Changed

  • chore(deps): bump aiohttp from 3.14.3 to 3.14.4 in /packages/cache-benchmark by @dependabot[bot] in #548
  • chore(deps): bump @modelcontextprotocol/sdk from 1.27.1 to 1.32.1 by @dependabot[bot] in #556
  • chore(deps-dev): bump vite from 8.0.16 to 8.1.6 by @dependabot[bot] in #555
  • Monitor LMCache KV cache footprint in Valkey (Pro) by @jamby77 in #528
  • Track LMCache hit rate from linked vLLM/SGLang engines (Pro) by @jamby77 in #529
  • chore(deps): bump certifi from 2026.6.17 to 2026.10.19 in /packages/agent-memory-py by @dependabot[bot] in #563
  • Add Cache Size Simulator snapshot endpoint by @jamby77 in #536
  • Add Cache Size Simulator page by @jamby77 in #537
  • fix(api): handle SIGTERM so container stops do not wait out the grace period by @KIvanow in #559
  • fix(storage): serialise schema setup and background index builds by @KIvanow in #560
  • Edit per-metric anomaly detector thresholds in Settings by @jamby77 in #550
  • Release the replication lag alert when the master link drops by @jamby77 in #543
  • Add the KV Cache page, docs and LMCache validation script (Pro) by @jamby77 in #530
  • Harden KV cache cleanup, cluster evictions, sample limits and scrape DNS by @jamby77 in #533
  • fix(api): size FalkorDB graph keys with GRAPH.MEMORY USAGE by @KIvanow in #564
  • Add session fixture harness and presets by @jamby77 in #551
  • docs: migration directions for ElastiCache and managed sources by @KIvanow in #572
  • chore(deps): bump zod from 4.3.6 to 4.6.6 by @dependabot[bot] in #580
  • chore(deps-dev): bump happy-dom from 20.8.9 to 21.0.4 by @dependabot[bot] in #579
  • Surface per-shard replication lag for redis_shake_sync by @jamby77 in #582
  • Add explicit Complete cutover action for redis_shake_sync by @jamby77 in #584
  • Wait for the cancelled index build to exit before close() returns by @jamby77 in #587
  • Add Session Explorer API by @jamby77 in #552
  • Add Session Explorer page by @jamby77 in #553

Full Changelog: v0.51.1...v0.52.0