sunnysahijwani/redis-health-digest

Zero-dependency Redis health & cache-performance digest for Laravel — thresholded OK/WARN/CRITICAL status, hit-rate, memory and keyspace metrics, ready for a daily cron email.

Maintainers

Package info

github.com/sunnysahijwani/redis-health-digest

pkg:composer/sunnysahijwani/redis-health-digest

Transparency log

Statistics

Installs: 0

Dependents: 0

Suggesters: 0

Stars: 4

Open Issues: 0

v1.1.0 2026-08-12 11:30 UTC

This package is auto-updated.

Last update: 2026-08-12 11:35:25 UTC


README

tests Latest Version License: MIT

A tiny, dependency-light Laravel package that samples a Redis instance with a single read-only INFO command, evaluates the result against configurable thresholds, and emits a thresholded OK / WARN / CRITICAL digest — as an email, as JSON, or as a console table.

Point it at a cron once a day and you get a health report in your inbox. Wire the same command into your alerting and it exits non-zero when Redis is unhealthy.

Runs one INFO call per sample. No keys are written, no SELECT is issued, nothing is flushed — safe to run against production.

Why

Most teams discover Redis problems — a collapsing hit rate, creeping memory, a failed background save, connections being rejected — only when something downstream breaks. This package turns those signals into a boring daily email and a non-zero exit code, so a human (or an alert) notices first.

It reports the metrics that actually predict trouble:

  • Cache performance — lifetime hits/misses and hit rate
  • Memory — used vs. maxmemory, fragmentation ratio, evicted keys (Δ since last check)
  • Persistence — last RDB bgsave / AOF write status
  • Clients & throughput — connected/blocked clients, rejected connections (Δ), ops/sec
  • Keyspace — key count for the DB you care about
  • Your own metrics — add custom gauges with a closure

Installation

composer require sunnysahijwani/redis-health-digest

Publish the config (thresholds, recipients, connection):

php artisan vendor:publish --tag=redis-health-digest-config

Requires PHP 8.2+ and Laravel 10, 11, 12, or 13. The service provider is auto-discovered.

Usage

# Send the digest email (the "real" run — updates delta baselines)
php artisan redis:health-digest

# Pretty table in your terminal (great for a quick look or a screenshot)
php artisan redis:health-digest --console

# Machine-readable JSON to stdout (pipe into other tooling)
php artisan redis:health-digest --json

# Collect + evaluate, skip the email
php artisan redis:health-digest --no-mail

# Override the connection / DB index ad-hoc
php artisan redis:health-digest --console --connection=cache --db=5

Schedule it

// app/Console/Kernel.php  (Laravel 10)  ·  routes/console.php (Laravel 11)
$schedule->command('redis:health-digest')->dailyAt('09:00');

Sample console output

  OK  Redis Health Digest — production

  +---------------------+----------------------------------+
  | Metric              | Value                            |
  +---------------------+----------------------------------+
  | Sampled at          | 2026-08-12T09:01:55+02:00        |
  | Redis               | 7.2.4 (master)                   |
  | DB 5 keys           | 104                              |
  | Used memory         | 147.74 MB                        |
  | Fragmentation       | 1.12                             |
  | Hits / Misses       | 1,043,712 / 408,168              |
  | Hit rate            | 71.89 %                          |
  | Evicted (Δ)         | 0 (0)                            |
  | Rejected conns (Δ)  | 0 (0)                            |
  | Clients             | 12 connected, 0 blocked          |
  | Ops/sec             | 35                               |
  | Persistence         | RDB ok / AOF ok                  |
  +---------------------+----------------------------------+

  • All thresholds within limits

Sample JSON

{
    "status": "OK",
    "environment": "production",
    "sampled_at": "2026-08-12T09:01:55+02:00",
    "memory": { "used_mb": 147.74, "fragmentation_ratio": 1.12, "evicted_keys_delta": 0 },
    "cache": { "hits": 1043712, "misses": 408168, "hit_rate": 71.89 },
    "persistence": { "rdb_last_bgsave_status": "ok", "aof_last_write_status": "ok" },
    "reasons": ["All thresholds within limits"]
}

Configuration

Everything lives in config/redis-health-digest.php and every value has an env override. The status is the worst of every breached check.

'thresholds' => [
    'min_hit_rate'            => 50.0,  // WARN below this %
    'max_used_memory_mb'      => 512,   // WARN above this
    'max_fragmentation_ratio' => 1.5,   // WARN above this
    'max_evicted_keys_delta'  => 0,     // WARN if keys evicted since last check
    'max_rejected_conn_delta' => 0,     // WARN if connections rejected since last check
    'require_persistence_ok'  => true,  // CRITICAL if RDB/AOF status != ok
],
Env var Default Purpose
REDIS_HEALTH_CONNECTION default Redis connection to sample
REDIS_HEALTH_DB 0 Logical DB index to report key count for
REDIS_HEALTH_MAIL_TO Comma-separated recipients
REDIS_HEALTH_MAIL_ONLY_ALERTS false Only email on WARN/CRITICAL (quiet when healthy)
REDIS_HEALTH_MIN_HIT_RATE 50 Minimum acceptable hit rate (%)
REDIS_HEALTH_MAX_MEMORY_MB 512 Memory ceiling (MB)

Deltas (evicted_keys, rejected_connections) are cumulative counters, so the digest stores a snapshot on each email run and reports the change since the previous run. --json / --console inspections never disturb that baseline.

Custom gauges

Add your own metric to every digest:

'custom_gauges' => [
    'Default queue length' => fn (array $info) => (int) Redis::llen('queues:default'),
],

The closure receives the parsed INFO map and returns a scalar.

Alert-only, non-zero exit

A CRITICAL status makes the command exit non-zero, so cron/CI can alert on it:

php artisan redis:health-digest --no-mail --console || notify-my-pager "Redis unhealthy"

Testing

composer install
composer test

The suite runs entirely against fixture INFO payloads — no live Redis, no database, nothing sent — via a fakeable RedisInfoProvider.

How it works

INFO (read-only) ──▶ InfoParser ──▶ MetricsCollector ──▶ DigestReport
                                                             │
                              ThresholdEvaluator ◀───────────┘
                                     │
                 ┌───────────────────┼───────────────────┐
              Mailable            JSON (stdout)      Console table

Metric collection is decoupled from Redis behind a RedisInfoProvider contract, which keeps it client-agnostic (phpredis / predis) and trivially testable.

License

MIT © Sunny Sahijwani