BetterDB vs the OTel Redis receiver

The Collector's Redis receiver sends one command, INFO, and turns the reply into metrics. That covers memory, clients and keyspace. It does not cover the slowlog, COMMANDLOG, ACL LOG, the client list or per-slot stats, because none of those are in INFO - and it has nowhere to keep them if it did. BetterDB collects and stores all of them, runs detectors and forecasts on top, and pushes the result into the same OTLP pipeline, as metrics and as events.

BetterDB is a monitoring service for Valkey and Redis: one container from Docker, Helm or npx, or BetterDB Cloud. It connects as an ordinary client, keeps history, runs detectors and forecasts, and serves a UI, REST API and Prometheus endpoint on port 3001.

Which one do you need?

Stay on the receiver when…

  • You already run otelcol-contrib and want Redis metrics in the same pipeline with no extra service
  • INFO-level metrics are enough: memory, clients, keyspace and replication offsets
  • You want one agent config for Redis, Postgres, hosts and containers
  • A stateless collector with nothing to store is a requirement

Run both when…

  • OpenTelemetry is your standard and you want Valkey history flowing through it - BetterDB pushes its metrics and events to your Collector over OTLP
  • You keep the receiver for baseline vitals and add BetterDB for slowlog patterns, COMMANDLOG, ACL audit, anomalies and forecasts
  • You have instances BetterDB cannot dial: a Collector can push redisreceiver metrics into BetterDB instead

Use BetterDB instead when…

  • You need slowlog, COMMANDLOG, ACL or per-client data - the receiver only runs INFO
  • You run a cluster or Sentinel and want every node discovered, labeled and tracked through failovers - the receiver takes one endpoint per block
  • You want detection, forecasting, CVE checks, dashboards and alert rules included, not assembled downstream

Side by side

What it is

BetterDB

A monitoring application: UI, stored history, detectors, a Prometheus endpoint and OTLP export

OTel Redis receiver

A metrics receiver in otelcol-contrib. Beta stability, no storage

What it reads

BetterDB

Seven command families, not one: INFO, SLOWLOG, COMMANDLOG, CLIENT LIST, ACL LOG, LATENCY and cluster commands; the schedule is below

OTel Redis receiver

INFO only, once per collection interval (10s by default)

Metrics

BetterDB

110+ betterdb_* metrics, all on by default, every series with a connection label

OTel Redis receiver

61 redis.* metrics, 29 of them enabled by default

Per-command stats

BetterDB

Calls and average latency per command, stored

OTel Redis receiver

Calls, time and latency percentiles per command, opt-in

Slowlog

BetterDB

Collected every 30 seconds and stored with arguments, duration and client; grouped by pattern, key prefix and client

OTel Redis receiver

Not collected

COMMANDLOG (Valkey 8.1+)

BetterDB

Collected and stored; large requests and replies grouped by pattern

OTel Redis receiver

Not collected

ACL denials and client list

BetterDB

The entries and the clients, not counts: ACL LOG by reason and user; CLIENT LIST snapshots every 60 seconds, rolled up for 90 days

OTel Redis receiver

Connected and blocked client counts

Cluster

BetterDB

One seed: auto-registration (opt-in) adds every node and keeps the list in sync. Per-slot key counts populated, with a heatmap of all 16,384 slots

OTel Redis receiver

One endpoint per receiver block. Its cluster metrics are not populated as of v0.164.1; a fix is open upstream

Instance identity

BetterDB

A connection label on every series, on by default

OTel Redis receiver

server.address and server.port resource attributes are off by default

Sentinel

BetterDB

With auto-registration on, data nodes are discovered through Sentinel and a failover is picked up on the next 30-second sync with history kept. No Sentinel-level series

OTel Redis receiver

Six optional Sentinel metrics

Valkey

BetterDB

Yes. COMMANDLOG and slot stats switch on where the version has them

OTel Redis receiver

Works against Valkey. A dedicated Valkey receiver was proposed and closed as not planned in 2025

Anomaly detection and forecasting

BetterDB

Done before the data leaves: rolling five-minute baselines, more than 20 detectors correlated into named patterns, and time-to-limit forecasts, all exported as metrics and events

OTel Redis receiver

None - left to whatever backend receives the metrics

Security

BetterDB

Server and module versions matched against five CVE feeds every 6 hours; config drift and hazard checks

OTel Redis receiver

None

Traffic capture

BetterDB

Opt-in MONITOR captures: on demand, scheduled, or armed for the next recurrence of an anomaly; 30 seconds by default, capped and health-gated

OTel Redis receiver

None

Pipeline

BetterDB

OTLP out to any Collector - metrics every 15 seconds, events as logs; OTLP traces and Collector metrics in

OTel Redis receiver

Processors, fan-out to any exporter, receiver_creator for discovery

Checked against opentelemetry-collector-contrib v0.164.1 and BetterDB 0.54.0, November 2026. Spot something out of date? Tell us and we will fix it.

Sources: Redis receiver source and docs · Cluster metrics bug · Valkey receiver proposal

What the pipeline gets from BetterDB that INFO cannot give it

The receiver is a faithful INFO-to-metrics converter. Three things that need other commands, stored state, or both - and what each looks like once it reaches your Collector.

Stored entries, not counters

SLOWLOG GET and COMMANDLOG GET every 30 seconds, every entry kept with its arguments, duration and client, fingerprinted into patterns. The pattern metrics flow out over OTLP every 15 seconds; the entries stay searchable in BetterDB.

Example

betterdb_slowlog_pattern_count{pattern="HGETALL session:*",connection="cache-eu-1"} 24
betterdb_slowlog_pattern_avg_duration_us{pattern="HGETALL session:*",connection="cache-eu-1"} 1250000

Events in the same pipeline

Anomalies, forecasts crossing their threshold, failovers, CVE findings and config changes go out as OTLP log records under the betterdb-events logger - the same events the webhooks carry - so your Collector routes them like any other signal.

Example

logger=betterdb-events  event=anomaly.detected  severity=critical
connection=cache-eu-1  pattern=REPLICATION_DIVERGENCE

Forecasts as metrics

A time-to-limit per instance from a rolling 6-hour regression: the same math as predict_linear(), computed per instance without a query to write, exported as a metric, with a default alert when the limit is under two hours away.

Example

betterdb_metric_forecast_time_to_limit_seconds{metric_kind="usedMemory",connection="cache-eu-1"} 5400

INFO is the whole input

Everything the receiver reports comes from one INFO reply per interval. Anything Valkey does not put in INFO is out of reach: slowlog entries, COMMANDLOG, ACL LOG, the client list and per-slot stats.

Two details matter on clusters. Each receiver block takes a single endpoint, so a six-node cluster means six blocks or a receiver_creator rule. And the redis.cluster.* metrics added in 2025 are defined but not populated as of v0.164.1 - the fix is an open pull request.

receivers:
  redis/node-1:
    endpoint: valkey-1:6379
  redis/node-2:
    endpoint: valkey-2:6379
  # ...one block per node

BetterDB works the other way round. It does the collecting, the storing and the detecting, then pushes the result into your pipeline. Set one variable and every betterdb_* metric, and every monitoring event, lands in the Collector you already run:

OTEL_EXPORTER_OTLP_ENDPOINT=http://otel-collector:4318

One wrinkle to know: cumulative values such as betterdb_commands_processed_total are published as gauges. In PromQL rate() works on them unchanged; over OTLP they arrive as gauges, so use a delta or rate function in your backend rather than a counter function. A semantic-convention export mode maps 34 of the series to receiver-style valkey.* names with one resource per node; the rest keep betterdb.* names. Dashboards built on redis.* need only the prefix changed for those 34.

It also works in reverse: a Collector that can reach an instance BetterDB cannot dial pushes its redisreceiver metrics to BetterDB, which lists the sender as a discovered instance (up to 200, kept 24 hours) and charts it next to the rest.

How BetterDB runs

The operational facts behind every row above, taken from BetterDB 0.54.0.

What it is

One Node.js service in one container (310 MB image) from Docker, Helm or npx, or hosted as BetterDB Cloud. It serves the web UI, the REST API and the Prometheus endpoint on port 3001, and can push metrics and events over OTLP. The Helm chart requests 100m CPU and 256 MiB with a 1 CPU, 1 GiB limit, and runs one replica: the process holds the anomaly baselines and capture sessions, and the chart notes that more replicas only make sense with Postgres and are not load-balanced work.

How it connects

As an ordinary client. Every poller shares one long-lived connection per monitored instance, named BetterDB-Monitor in CLIENT LIST, plus a few helpers: a discovery connection on clusters and Sentinels, a scratch connection for key sampling on databases other than 0, and a dedicated socket for each MONITOR capture. TLS is per connection. For instances with no inbound path, such as ElastiCache or Memorystore, the BetterDB agent runs inside your network and connects outbound over WebSocket to BetterDB Cloud or to your self-hosted BetterDB. Nothing is installed on the Valkey nodes.

Storage and retention

History is in memory by default and lost on restart. Set STORAGE_TYPE to sqlite or postgres and everything it stores - slowlog and COMMANDLOG entries, client snapshots, anomaly events, captures - is kept until you set a retention window in Settings or LOCAL_RETENTION_DAYS. Client-list snapshots are also rolled into 5-minute buckets kept 90 days. SQLite means one replica on a volume, and the -no-ai image variant ships without it; Postgres is the choice when the history must outlive the pod.

When BetterDB is down

Polling, detectors, forecasts and webhooks stop, and if BetterDB is your only Prometheus source, so do your Valkey metrics. Alert on up for the betterdb scrape job, and on betterdb_poll_stale, which is 1 when a connection has had no successful poll within the staleness bound (15 seconds by default). Self-hosted installs send usage telemetry to PostHog EU - version, deployment mode and events such as app start and page views - unless BETTERDB_TELEMETRY=false; an offline license forces it off, and CVE_ENABLED=false removes the only other outbound call.

What it needs from your database

Read-only. The base user below covers monitoring; it has no CONFIG SET, no KEYS, no FLUSH and no RESET commands. Key sampling adds a read-only key pattern with SCAN and MEMORY USAGE, and capture sessions add +monitor, both opt-in.

ACL SETUSER betterdb reset on >CHANGE_ME -@all +ping +info +select +client|setname +client|getname +client|list +client|no-touch +config|get +slowlog|get +slowlog|len +commandlog|get +commandlog|len +latency|latest +latency|histogram +latency|history +latency|doctor +memory|stats +memory|doctor +acl|whoami +acl|log +role +cluster|info +cluster|nodes +cluster|shards +cluster|slot-stats +cluster|myid +command|info +dbsize +lastsave +time +module|list
  • Deny CONFIG GET and config drift, hazard checks and scaling readiness skip the connection.
  • Deny CLIENT LIST and client pages and client history are unavailable.
  • Deny ACL LOG and the audit trail is unavailable.
  • Deny SLOWLOG or COMMANDLOG and those pages are unavailable; everything else keeps running.
  • Deny MONITOR and capture sessions cannot start. It is not in the base line above.

What it runs, and how often

All on the one shared connection. KEYS is never used. MONITOR runs only inside a capture session you start, schedule or arm on an anomaly: 30 seconds by default, capped at 50 MB or 5 million lines, refused while memory is above 85% or a failover is in progress, with MONITOR_REDACT_VALUES to scrub values.

INFO

Every 1s for anomaly baselines, 5s for metrics. Both intervals configurable. The 5s loop also reads INFO keysizes and two cached CONFIG GET keys for persistence checks.

PING

Every 10s. Health check.

SLOWLOG GET 128; COMMANDLOG GET 128 for slow, large-request and large-reply

Every 30s. COMMANDLOG on Valkey 8.1+ only, three calls.

CLIENT LIST, ACL LOG 100, LATENCY LATEST and HISTOGRAM, INFO commandstats and latencystats

Every 60s. CLIENT LIST is unbounded; cost grows with connected clients.

CLUSTER INFO, NODES, SLOT-STATS (top 100)

Every 5s. Cluster connections only.

CLUSTER NODES or SENTINEL MASTERS for auto-registration

Every 30s. Only when auto-registration is turned on.

CONFIG GET for a short allowlist of keys, one per call; ACL LIST

Every 60 anomaly polls (about 60s). Config drift and hazard checks; skipped if denied. Never CONFIG GET *.

SCAN sample of 10,000 keys with TYPE, TTL, MEMORY USAGE and OBJECT FREQ or IDLETIME

Every 5 min. Key analytics; needs the optional read-only key rules.

CVE dataset refresh

Every 6h. Outbound to GitHub, NVD, MITRE, CISA and FIRST (EPSS); CVE_ENABLED=false turns it off.

Full references: minimum ACL · configuration and retention · capture sessions · Kubernetes guide

Keep OpenTelemetry as the pipeline

Our public Grafana demo is fed by the OTLP mirror alongside the Prometheus endpoint; the blog post walks through both directions.

FAQ

Does the OpenTelemetry Collector support Valkey?

Through the Redis receiver, yes. Valkey answers INFO the same way Redis does, and OpenTelemetry's own demo points the Redis receiver at a Valkey container. There is no Valkey-specific receiver: one was proposed and the issue was closed as not planned in July 2025.

Does the Redis receiver collect the slowlog?

No. It runs INFO and nothing else, so it has no slowlog, COMMANDLOG, ACL LOG or client-list data. It does offer per-command call counts and latency percentiles, taken from the commandstats section of INFO, if you enable them. BetterDB polls SLOWLOG and COMMANDLOG every 30 seconds and stores the entries.

How do I monitor a Valkey cluster with the Redis receiver?

With one receiver block per node, or a receiver_creator rule that starts a receiver for each discovered endpoint. Turn on the server.address and server.port resource attributes, which are off by default, or the nodes cannot be told apart. The redis.cluster.* metrics are not populated as of v0.164.1. With auto-registration on, BetterDB adds every node from one seed and labels each series with the connection.

Can BetterDB send its metrics to an OpenTelemetry Collector?

Yes. Set OTEL_EXPORTER_OTLP_ENDPOINT and BetterDB mirrors every betterdb_* metric every 15 seconds and sends its monitoring events as OTLP logs. A semantic-convention mode maps 34 series to receiver-style valkey.* names; the rest keep betterdb.* names. The same series are also available on the Prometheus endpoint if you would rather scrape.

Can a Collector send metrics to BetterDB?

Yes. BetterDB accepts OTLP metrics from a Collector redisreceiver for instances it cannot reach itself, lists the sender as a discovered instance, and charts it alongside the connections it polls directly.

Which is lighter to run?

The receiver. If the Collector is already deployed it adds no process and stores nothing. BetterDB is one extra container with its own storage, which is what keeping history and running detectors takes.

Deciding between more tools? When should you use BetterDB? →

Run it locally in one command

docker run -d -p 3001:3001 betterdb/monitor:latest

Then open http://localhost:3001 - see the Docker guide.

See it on your own data

BetterDB Cloud runs the service and its storage for you. Or self-host it next to the tools you already use.