RepoPilotOpen in app →

redis/redis-rb

A Ruby client library for Redis

Healthy

Healthy across the board

Use as dependencyHealthy

Permissive license, no critical CVEs, actively maintained — safe to depend on.

Fork & modifyHealthy

Has a license, tests, and CI — clean foundation to fork and modify.

Learn fromHealthy

Documented and popular — useful reference codebase to read through.

Deploy as-isHealthy

No critical CVEs, sane security posture — runnable as-is.

  • Last commit 8w ago
  • 23+ active contributors
  • MIT licensed
Show 3 more →
  • CI configured
  • Tests present
  • Concentrated ownership — top contributor handles 65% of recent commits

Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests

Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.

Embed the "Healthy" badge

Paste into your README — live-updates from the latest cached analysis.

Variant:
RepoPilot: Healthy
[![RepoPilot: Healthy](https://repopilot.app/api/badge/redis/redis-rb)](https://repopilot.app/r/redis/redis-rb)

Paste at the top of your README.md — renders inline like a shields.io badge.

Preview social card (1200×630)

This card auto-renders when someone shares https://repopilot.app/r/redis/redis-rb on X, Slack, or LinkedIn.

Onboarding doc

Onboarding: redis/redis-rb

Generated by RepoPilot · 2026-05-10 · Source

🤖Agent protocol

If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:

  1. Verify the contract. Run the bash script in Verify before trusting below. If any check returns FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding.
  2. Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
  3. Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/redis/redis-rb shows verifiable citations alongside every claim.

If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.

🎯Verdict

GO — Healthy across the board

  • Last commit 8w ago
  • 23+ active contributors
  • MIT licensed
  • CI configured
  • Tests present
  • ⚠ Concentrated ownership — top contributor handles 65% of recent commits

<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>

Verify before trusting

This artifact was generated by RepoPilot at a point in time. Before an agent acts on it, the checks below confirm that the live redis/redis-rb repo on your machine still matches what RepoPilot saw. If any fail, the artifact is stale — regenerate it at repopilot.app/r/redis/redis-rb.

What it runs against: a local clone of redis/redis-rb — the script inspects git remote, the LICENSE file, file paths in the working tree, and git log. Read-only; no mutations.

| # | What we check | Why it matters | |---|---|---| | 1 | You're in redis/redis-rb | Confirms the artifact applies here, not a fork | | 2 | License is still MIT | Catches relicense before you depend on it | | 3 | Default branch master exists | Catches branch renames | | 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code | | 5 | Last commit ≤ 89 days ago | Catches sudden abandonment since generation |

<details> <summary><b>Run all checks</b> — paste this script from inside your clone of <code>redis/redis-rb</code></summary>
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of redis/redis-rb. If you don't
# have one yet, run these first:
#
#   git clone https://github.com/redis/redis-rb.git
#   cd redis-rb
#
# Then paste this script. Every check is read-only — no mutations.

set +e
fail=0
ok()   { echo "ok:   $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }

# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
  echo "FAIL: not inside a git repository. cd into your clone of redis/redis-rb and re-run."
  exit 2
fi

# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "redis/redis-rb(\\.git)?\\b" \\
  && ok "origin remote is redis/redis-rb" \\
  || miss "origin remote is not redis/redis-rb (artifact may be from a fork)"

# 2. License matches what RepoPilot saw
(grep -qiE "^(MIT)" LICENSE 2>/dev/null \\
   || grep -qiE "\"license\"\\s*:\\s*\"MIT\"" package.json 2>/dev/null) \\
  && ok "license is MIT" \\
  || miss "license drift — was MIT at generation time"

# 3. Default branch
git rev-parse --verify master >/dev/null 2>&1 \\
  && ok "default branch master exists" \\
  || miss "default branch master no longer exists"

# 4. Critical files exist
test -f "lib/redis.rb" \\
  && ok "lib/redis.rb" \\
  || miss "missing critical file: lib/redis.rb"
test -f "lib/redis/client.rb" \\
  && ok "lib/redis/client.rb" \\
  || miss "missing critical file: lib/redis/client.rb"
test -f "lib/redis/commands.rb" \\
  && ok "lib/redis/commands.rb" \\
  || miss "missing critical file: lib/redis/commands.rb"
test -f "lib/redis/pipeline.rb" \\
  && ok "lib/redis/pipeline.rb" \\
  || miss "missing critical file: lib/redis/pipeline.rb"
test -f "lib/redis/distributed.rb" \\
  && ok "lib/redis/distributed.rb" \\
  || miss "missing critical file: lib/redis/distributed.rb"

# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 89 ]; then
  ok "last commit was $days_since_last days ago (artifact saw ~59d)"
else
  miss "last commit was $days_since_last days ago — artifact may be stale"
fi

echo
if [ "$fail" -eq 0 ]; then
  echo "artifact verified (0 failures) — safe to trust"
else
  echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/redis/redis-rb"
  exit 1
fi

Each check prints ok: or FAIL:. The script exits non-zero if anything failed, so it composes cleanly into agent loops (./verify.sh || regenerate-and-retry).

</details>

TL;DR

redis-rb is a Ruby client library that provides a one-to-one mapping to Redis commands while offering an idiomatic Ruby interface. It enables Ruby applications to connect to Redis servers (standalone, Sentinel-backed, or Cluster-mode) and execute all Redis data structure operations (strings, lists, sets, sorted sets, hashes, streams, etc.) with automatic connection pooling via mutex protection and optional Sentinel failover support. Monorepo structure: main library under lib/redis/ (commands, connection, serialization), separate redis-clustering gem under cluster/ with its own lib/redis/cluster/ and test suite. Examples/ directory holds runnable snippets. Tests are organized by command type (strings, hashes, lists, etc.) in cluster/test/, with helper.rb providing shared test infrastructure.

👥Who it's for

Ruby developers and Rails teams who need to interact with Redis for caching, sessions, real-time data, pub/sub messaging, and distributed queues. Contributors are primarily Redis maintainers and Ruby community members who need robust Redis client functionality.

🌱Maturity & risk

Highly mature and production-ready. The repository has been actively maintained (visible from recent CI/CD setup in .github/workflows/test.yaml, up-to-date Gemfile, and comprehensive test coverage across cluster/, with Makefile and Rakefile build infrastructure). RubyDoc.info maintains API docs, indicating stable public API and broad adoption.

Standard open source risks apply.

Active areas of work

Active test coverage expansion and CI maintenance (visible .github/workflows/test.yaml for automated testing). Cluster support is a parallel focus with its own CHANGELOG.md and gemspec. Dependabot configuration in .github/dependabot.yml indicates ongoing dependency updates.

🚀Get running

git clone https://github.com/redis/redis-rb && cd redis-rb && bundle install && ruby -Ilib -e "require 'redis'; r = Redis.new; puts r.ping"

Daily commands: For REPL: bundle exec bin/console. For cluster testing: bundle exec rake cluster:test (inferred from Rakefile pattern). For basic connectivity: ruby -Ilib -e "require 'redis'; Redis.new.ping"

🗺️Map of the codebase

  • lib/redis.rb — Main entry point and public API surface; all users instantiate Redis client here and all methods are exposed via this file.
  • lib/redis/client.rb — Core connection management and command execution; handles socket I/O, protocol parsing, and request/response serialization.
  • lib/redis/commands.rb — Command module loader that includes all Redis command implementations; defines the interface every command module must satisfy.
  • lib/redis/pipeline.rb — Pipelining abstraction for batching multiple commands; critical for performance-sensitive operations.
  • lib/redis/distributed.rb — Distributed client using consistent hashing; required for understanding multi-node deployments and key distribution.
  • lib/redis/hash_ring.rb — Consistent hash ring implementation for distributed key routing; foundational for distributed client operations.
  • redis.gemspec — Gem metadata and dependency declarations; critical for understanding compatibility and external dependencies.

🛠️How to make changes

Add a new Redis command

  1. Identify the command category (strings, lists, hashes, etc.) and determine the appropriate module file in lib/redis/commands/ (lib/redis/commands/*.rb)
  2. Add a method to the relevant command module (e.g., def get(key) in strings.rb) with proper documentation and argument handling (lib/redis/commands/strings.rb)
  3. The method should call send_command(:COMMAND_NAME, args) which is inherited from the Client base; Redis class automatically includes all command modules via lib/redis/commands.rb (lib/redis/client.rb)
  4. Write tests for the new command in the appropriate test file (test/distributed/ or cluster/test/) ensuring it works in both standalone and clustered modes if applicable (test/distributed/commands_on_strings_test.rb)

Extend the distributed client for a new use case

  1. Review the current distributed client implementation to understand how it routes commands via consistent hashing (lib/redis/distributed.rb)
  2. If you need custom routing logic, override the method in a subclass or add a new routing strategy by modifying hash_ring.rb to adjust slot assignment or key distribution (lib/redis/hash_ring.rb)
  3. Implement your feature by adding methods that call send_command_to_node() or send_command_to_all_nodes() as appropriate (lib/redis/distributed.rb)
  4. Add tests in test/distributed/ to verify behavior across multiple nodes, including edge cases like node failures (test/distributed/distributed_test.rb)

Implement a custom connection/authentication strategy

  1. Review Redis.new() instantiation and the Client constructor to understand supported connection options (host, port, password, path, url, etc.) (lib/redis.rb)
  2. Extend or subclass Redis::Client to add custom connection logic such as SSL/TLS, proxy handling, or custom authentication (lib/redis/client.rb)
  3. Override the connect() method or initialize() to inject your custom connection behavior before sending commands (lib/redis/client.rb)
  4. Write integration tests to verify your authentication strategy works with both normal and Pub/Sub modes (test/distributed/connection_handling_test.rb)

Add a new data type command module

  1. Create a new file in lib/redis/commands/ following the naming convention (e.g., lib/redis/commands/streams.rb for stream commands) (lib/redis/commands/streams.rb)
  2. Define a module (e.g., module Streams) that includes the command methods; each method should use send_command() to invoke the Redis command (lib/redis/commands/streams.rb)
  3. The module will be automatically included in the Redis class via the require chain in lib/redis/commands.rb (lib/redis/commands.rb)
  4. Create comprehensive tests in test/distributed/commands_on_streams_test.rb covering all stream operations and edge cases (test/distributed/commands_on_streams_test.rb)

🔧Why these technologies

  • Ruby — Primary language for the client library; allows idiomatic Ruby APIs that wrap Redis RESP protocol
  • RESP (Redis Serialization Protocol) — Native Redis wire protocol; simple text-based format enables efficient command serialization and response parsing
  • Consistent Hashing (Hash Ring) — Distributes keys across multiple Redis nodes in the distributed client without requiring a proxy; minimizes key migration on node changes
  • Pipelining — Batches multiple commands in a single round-trip to reduce network latency for bulk operations
  • Pub/Sub Subscription Model — Provides non-blocking message delivery; requires separate connection state to handle subscriptions vs. normal commands

⚖️Trade-offs already made

  • Single-threaded synchronous API by default

    • Why: Simpler implementation and predictable command ordering; matches Redis's single-threaded execution model
    • Consequence: Blocks on network I/O; users must manage concurrency via threads, Fiber, or async libraries; no built-in async/await support
  • Separate redis-clustering gem instead of bundling Cluster support

    • Why: Cluster protocol adds complexity and breaking changes; keeps the core gem lightweight for users not using Cluster
    • Consequence: Users deploying Cluster must install two gems; code duplication between redis-rb and redis-clustering; separate version management
  • Distributed client uses client-

    • Why: undefined
    • Consequence: undefined

🪤Traps & gotchas

  1. Redis server must be running on localhost:6379 by default; many tests fail silently if Redis isn't available. 2. Sentinel and Cluster modes require additional infrastructure (sentinel.conf, cluster nodes); see cluster/test/support/orchestrator.rb for how tests handle this. 3. Connection string passwords must be URL-encoded via CGI.escape() if they contain special characters. 4. Thread safety is per-instance (Mutex inside each Redis object), not global; sharing one Redis instance across threads is safe, but creating separate instances per thread defeats the purpose. 5. Unix socket connections require explicit path: parameter and bypass host/port.

🏗️Architecture

💡Concepts to learn

  • RESP (Redis Serialization Protocol) — redis-rb parses and encodes RESP to communicate with Redis; understanding protocol layering is critical for debugging connection issues and protocol-level optimizations
  • Hash Slot Distribution (Cluster routing) — The redis-clustering gem uses CKEY (cluster key) hashing to determine which node handles each command in Redis Cluster; multi-key operations must target same slot
  • Sentinel Master/Slave Failover — redis-rb's Sentinel support automatically discovers and fails over to replica nodes on master outage; requires understanding Sentinel discovery protocol and role detection
  • Pipelining & Command Batching — redis-rb supports pipelining multiple commands before reading responses to reduce round-trip latency; critical for bulk operations
  • Pub/Sub Topic Subscriptions — redis-rb implements Redis Pub/Sub messaging via SUBSCRIBE/PUBLISH commands with blocking receiver loops; understanding subscription model is essential for real-time features
  • ACL (Access Control Lists) — Redis 6+ ACL support allows per-user command restrictions; redis-rb supports username/password auth distinct from legacy password-only mode
  • Lua Scripting (EVAL/EVALSHA) — redis-rb passes Lua scripts to Redis for atomic multi-command execution; script caching via EVALSHA reduces bandwidth on repeated calls
  • redis/redis — The official Redis server implementation that redis-rb connects to; understanding Redis command behavior is essential for client development
  • mperham/connection_pool — Explicitly recommended in redis-rb README for connection pooling across threads; commonly used alongside redis-rb in production Rails apps
  • resque/resque — Popular background job library that uses redis-rb to store and process job queues; key ecosystem consumer of this client
  • redis-rb/redis-rb-cluster — Precursor to the redis-clustering gem now embedded in cluster/; historical reference for cluster routing algorithms
  • ruby/redis-hashes — Companion gem providing higher-level Hash-like interface on top of redis-rb for simplified key-value patterns

🪄PR ideas

To work on one of these in Claude Code or Cursor, paste: Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.

Add comprehensive test coverage for Redis cluster transaction isolation

The cluster implementation has a TransactionAdapter (cluster/lib/redis/cluster/transaction_adapter.rb) but cluster/test/commands_on_transactions_test.rb appears minimal. The main redis-rb has transaction support but the cluster variant needs specific tests for WATCH/MULTI/EXEC behavior across slot boundaries, which is a known complexity in distributed systems.

  • [ ] Review cluster/lib/redis/cluster/transaction_adapter.rb implementation details
  • [ ] Add tests to cluster/test/commands_on_transactions_test.rb covering: WATCH across different slots, MULTI/EXEC with cluster redirects, transaction rollback scenarios
  • [ ] Test interaction between transactions and cluster topology changes
  • [ ] Verify pipelining + transactions work correctly in cluster mode (reference: cluster/test/client_pipelining_test.rb pattern)

Implement and test Redis Streams command parity for cluster mode

cluster/test/commands_on_streams_test.rb exists but the underlying Stream commands support in cluster/lib/redis/cluster/client.rb may be incomplete. Streams (XADD, XREAD, XGROUP, etc.) have specific partitioning semantics that need explicit cluster handling, especially for consumer groups.

  • [ ] Audit cluster/lib/redis/cluster/client.rb for all Stream command definitions (XADD, XREAD, XREADGROUP, XGROUP CREATE, XCLAIM, etc.)
  • [ ] Identify commands missing slot routing configuration (similar pattern to cluster/test/commands_on_strings_test.rb)
  • [ ] Add tests to cluster/test/commands_on_streams_test.rb for: XREAD across slots, consumer group operations on clustered streams, backpressure handling
  • [ ] Document any limitations in README or cluster/README.md for Stream commands

Add integration tests for Sentinel failover scenarios in test.yaml workflow

The repo has examples/sentinel/ configuration and examples/sentinel.rb but .github/workflows/test.yaml doesn't appear to run Sentinel-specific tests. The Redis Sentinel support (connection failover, replica handling) needs explicit CI validation to prevent regression.

  • [ ] Create cluster/test/sentinel_failover_test.rb (or lib/redis/test/sentinel_failover_test.rb) covering: connection pooling behavior on failover, replica promotion detection, reconnection logic
  • [ ] Add a new GitHub Actions job in .github/workflows/test.yaml that spins up a 3-node Sentinel cluster and runs the failover tests
  • [ ] Reference the sentinel setup from examples/sentinel/start to automate Sentinel cluster initialization in CI
  • [ ] Ensure test cleanup properly handles Sentinel node shutdown to avoid flaky tests

🌿Good first issues

  • Add missing docstrings to command methods in lib/redis/commands/ using YARD format to improve RubyDoc.info API coverage (many command definitions lack detailed parameter/return documentation).
  • Expand cluster/test/commands_on_scripting_test.rb to cover EVAL and EVALSHA edge cases with cluster key routing (currently test coverage for Lua scripts on Cluster is minimal).
  • Create example scripts in examples/ demonstrating real-world patterns: rate limiting with INCR/EXPIRE, session storage with HSET, pub/sub message queue (currently examples/ directory is sparse).

Top contributors

Click to expand

📝Recent commits

Click to expand
  • 1c09e43 — Note the maintainership change in the changelog (byroot)
  • 59bb945 — Merge pull request #1336 from supercaracal/fix-cluster-test (byroot)
  • 7601a01 — test: fix several test cases for cluster mode (supercaracal)
  • b6e81b2 — Default to Redis 8.4 (byroot)
  • de27281 — Add ruby 4.0 to the CI matrix (byroot)
  • 3e0dcf7 — Merge pull request #1331 from edcarvio/ecarvalho/add_hpexpire (byroot)
  • 3408a2a — Add support to HPEXPIRE and HPTTL (edcarvio)
  • 028059d — Appease rubocop (byroot)
  • 6ce5975 — Merge pull request #1329 from redis/dependabot/github_actions/actions/cache-5 (byroot)
  • 97de2dd — Bump actions/cache from 4 to 5 (dependabot[bot])

🔒Security observations

The redis-rb codebase shows a reasonable security baseline as a mature library, but has several areas requiring attention. Primary concerns include: lack of enforced password URL encoding, potential command injection risks in scripting functionality, insecure example files with hardcoded credentials, and insufficient TLS/encryption guidance for remote connections. The library lacks comprehensive security documentation and best practices guidance. No critical vulnerabilities were identified that would compromise the core library itself, but improper usage patterns by developers could lead to security issues. Recommend implementing input validation for Lua scripts, enforcing TLS for remote connections, securing example files, and adding comprehensive security documentation.

  • High · Password URL Encoding Not Enforced — README.md, lib/redis/client.rb. The README documentation states that passwords with special characters should be URL-encoded using CGI.escape(), but this is only a recommendation, not enforced at the code level. If users fail to encode passwords, special characters could be misinterpreted during connection string parsing, potentially causing authentication bypass or connection to unintended Redis instances. Fix: Implement automatic URL encoding of password parameters in the Redis client constructor. Add validation to warn or reject unencoded special characters in passwords. Update documentation with explicit examples showing proper encoding.
  • Medium · Potential Command Injection via EVAL/EVALSHA — lib/redis/commands/scripting.rb. Redis Lua scripting commands (EVAL, EVALSHA) in lib/redis/commands/scripting.rb may accept user-supplied script content. If user input is directly concatenated into scripts without proper sanitization, it could lead to unintended Lua code execution or Redis command injection. Fix: Implement strict input validation for Lua scripts. Use parameterized script arguments instead of string concatenation. Document safe scripting practices. Consider restricting script functionality through Redis ACLs if available.
  • Medium · Insecure Example Configurations — examples/sentinel/sentinel.conf, examples/unicorn/config.ru. Example files in the examples/ directory contain hardcoded credentials and configuration details (e.g., examples/sentinel/sentinel.conf, examples/unicorn/). These could be accidentally committed or copied into production environments. Fix: Replace hardcoded credentials with environment variable references or placeholder values. Add .example extensions to config files. Document secure configuration practices. Ensure examples are never used directly in production.
  • Medium · No TLS/SSL Configuration Validation — lib/redis/client.rb, README.md. The client supports Redis URLs but there's no evidence of mandatory TLS verification configuration or warnings when connecting to remote servers over non-encrypted channels. Connections to remote Redis instances (mentioned in README) could be vulnerable to MITM attacks. Fix: Implement TLS/SSL certificate verification by default for remote connections. Add warnings or errors if TLS is not enabled for non-localhost connections. Provide clear documentation on enabling and validating TLS certificates.
  • Medium · Potential Timing Attack in Authentication — lib/redis/client.rb, lib/redis/commands/connection.rb. The client-side password handling in connection authentication may be vulnerable to timing attacks if password comparison is not performed using constant-time comparison functions, especially in pipelined operations. Fix: Use constant-time comparison functions (e.g., OpenSSL or Ruby's secure_compare) for password verification. Review authentication flow to ensure timing-safe operations throughout the connection lifecycle.
  • Low · Missing Security Headers in Documentation — README.md, Documentation. The README and documentation do not provide security best practices guidance such as network isolation, firewall rules, or authentication/authorization best practices when deploying redis-rb clients. Fix: Add a security section to the README covering: network isolation, firewall configuration, password requirements, TLS setup, and monitoring/logging recommendations. Provide security checklist for production deployments.
  • Low · No Dependency Lock File Visible — Gemfile, Gemfile.lock (missing from provided structure). The Gemfile exists but no Gemfile.lock is shown in the file structure. This could indicate unrestricted transitive dependency versions, which may include vulnerable packages. Fix: Ensure Gemfile.lock is committed and version-controlled. Use 'bundle audit' to scan for known vulnerabilities in dependencies. Set up automated dependency scanning in CI/CD pipeline (appears to exist in .github/workflows/test.yaml).

LLM-derived; treat as a starting point, not a security audit.


Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.