Skip to content

v0.35.0

Choose a tag to compare

@KIvanow KIvanow released this 06 Aug 13:15
· 4 commits to master since this release
bc65c11

Five new cluster/topology anomaly detectors for engine hazards that can't be fixed upstream, plus a real bug fix for a health metric that has been silently wrong since day one.

This release adds five advisory anomaly detectors targeting known-but-unfixable Valkey engine hazards (config drift across a replication group, stale hostname gossip, uncoordinated lagging promotion, ghost cluster membership, and large-reply COMMANDLOG throughput regression), fixes keyspaceSize always reporting 0 in the health summary and MCP get_health tool, and improves the update-check UX with install-aware upgrade commands.

🐛 Bug fixes

  • Health summary keyspaceSize always 0 - MetricsParser.parseInfoToTyped was an identity cast, so INFO keyspace/commandstats/errorstats sections stayed raw "k=v,k=v" strings at runtime even though their types promised parsed objects. getHealthSummary only counted a db entry when it was a typed object, so keyspaceSize structurally could never be anything but 0 - on every instance, in every deployment. This is the first field the MCP get_health tool description recommends checking, so it read as "empty database" when it never was. Now genuinely parsed; keyspaceSize is null when the keyspace section is absent so "no data" stays distinguishable from "empty database" (0). (#360)
  • Create-instance form 500s on names with spaces - the Add Connection → BetterDB Valkey instance form crashed provisioning with an opaque 500 if the name contained a space. The Name field now pre-fills with my-cache, sanitizes spaces to hyphens live as you type, and normalizes to a DNS-style label on submit; whitespace-only names show an inline error instead of firing a request.
  • Valkey provisioning failed for 1GB/2GB tiers - the tenant ResourceQuota hardcoded limits.memory: 2Gi, but the chart renders pods at 2× maxmemory, so the pod + sidecar exceeded quota and provisioning timed out with FailedCreate: exceeded quota. Since 1GB is the pre-selected first-run tier, this broke first-instance creation for new users. Quota now sizes off the same valkeyMemoryLimitMi() helper the chart uses.

✨ New anomaly detectors

  • Cross-node config drift (CONFIG_DRIFT) - CONFIG SET only ever applies to the node it's sent to, so nodes in the same replication group (cluster shard, or primary+replicas) can silently drift on critical settings (eviction policy, persistence, etc.) - a real source of incidents. Records a curated config subset per replication-group key and alerts on divergence. (upstream valkey#1193)
  • Hostname staleness / endpoint inconsistency (HOSTNAME_STALENESS) - in cluster mode, hostname gossip converges eventually rather than atomically, so CLUSTER NODES and CLUSTER SHARDS can disagree about a node's hostname, or a node can advertise a bare IP while peers already see a hostname. Either state can break TLS-SNI verification. Upstream has indicated this is likely won't-fix, so this is now a durable, engine-independent advisory. (upstream valkey#304)
  • Lagging uncoordinated promotion (LAGGING_PROMOTION) - in standalone (cluster-mode-disabled) setups, REPLICAOF NO ONE promotes a replica to primary with zero coordination. If the promoted replica was lagging, its unreplicated writes are lost and a more up-to-date sibling is forced into a full resync. Detects the transition and compares replication offsets against co-replica siblings. (upstream valkey#2587)
  • Ghost cluster membership (GHOST_MEMBERSHIP) - CLUSTER RESET or a restart makes a node forget its peers, but peers never forget it: the old node-id lingers as a ghost (fail/fail?/noaddr) next to the live id on the same ip:port. Surfaces the ghost and advises CLUSTER FORGET <ghost-id>. (upstream valkey#1757)
  • Large-reply COMMANDLOG throughput regression (LARGE_REPLY_PRESSURE) - Valkey's COMMANDLOG LARGE-REPLY facility, once a hot command's reply crosses commandlog-reply-larger-than, repeatedly takes a large-reply logging/copy path observed to cost up to ~25% GET throughput. The upstream fix is still open (a prior PR only raised the default threshold, masking rather than fixing it), so this adds a threshold-crossing advisory in the meantime. (upstream valkey#2926)

🖥️ Web / UX

  • Install-aware update banner - the update banner now detects how the instance was launched (Docker/Podman/npm/pnpm/yarn/npx) server-side and shows the matching one-click copy upgrade command, plus a link to a new step-by-step docs/updating.md upgrade guide.

📡 Telemetry / Licensing

  • telemetryEnabled sent on live license checks - license entitlement checks now report whether telemetry is enabled, alongside the existing check payload.

📚 Docs

  • Documented 5 previously-missing betterdb_* Prometheus metrics.

⬆️ Upgrade notes

  • Fully backwards compatible for the detectors and web changes - the five new detectors are additive and emit over the existing webhook, OTLP, and dashboard channels automatically; no config or schema migrations required.
  • API shape change (visible to external API consumers only): GET /metrics/info and GET /mcp/instance/:id/info now serialize keyspace, commandstats, and errorstats as parsed objects instead of raw "k=v,k=v" strings; keyspaceSize in the health payload is now number | null instead of always number. No in-repo consumer (web app, MCP tools, Prometheus exporter) relied on the old string shape.
  • Docker: betterdb/monitor:0.35.0

What's Changed

  • fix(metrics): parse keyspace/commandstats/errorstats in parseInfoToTyped in #362
  • feat(anomaly): ghost-membership detector for CLUSTER RESET stale ids (#1757) in #352
  • feat(anomaly): detect lagging uncoordinated promotion (REPLICAOF NO ONE) (#2587) in #356
  • feat(anomaly): hostname-staleness / endpoint-inconsistency detector (#304) in #357
  • feat(anomaly): cross-node config-drift detector (#1193) in #358
  • feat(anomaly): large-reply commandlog pressure advisory (#2926) in #359
  • feat(web): install-aware update banner with copy-paste upgrade command in #361
  • fix(web): pre-fill Valkey instance name and stop spaces from 500ing create in #355
  • fix(entitlement): size tenant ResourceQuota to the Valkey pod in #353
  • fix: Include telemetryEnabled on license checks in #363
  • docs(prometheus): document 5 missing betterdb_ metrics

Full Changelog: v0.34.0...v0.35.0

What's Changed

  • fix(entitlement): size tenant ResourceQuota to the Valkey pod by @KIvanow in #353
  • chore(deps): bump aiohttp from 3.14.1 to 3.14.3 in /packages/cache-benchmark by @dependabot[bot] in #354
  • feat(anomaly): ghost-membership detector for CLUSTER RESET stale ids (#1757) by @KIvanow in #352
  • fix(web): pre-fill Valkey instance name and stop spaces from 500ing create by @KIvanow in #355
  • feat(anomaly): detect lagging uncoordinated promotion (REPLICAOF NO ONE) (#2587) by @KIvanow in #356
  • feat(anomaly): hostname-staleness / endpoint-inconsistency detector (#304) by @KIvanow in #357
  • feat(anomaly): cross-node config-drift detector (#1193) by @KIvanow in #358
  • feat(anomaly): large-reply commandlog pressure advisory (#2926) by @KIvanow in #359
  • feat(web): install-aware update banner with copy-paste upgrade command by @KIvanow in #361
  • Include telemetryEnabled on license checks by @KIvanow in #363
  • fix(metrics): parse keyspace/commandstats/errorstats in parseInfoToTyped by @KIvanow in #362

Full Changelog: 0.34.0...v0.35.0