redigo

A print-like Go client for Redis and Valkey with pipelining, pub/sub, connection pooling, and Lua script helpers.

Library
Go
vv1.9.3
9,857stars
Apache License 2.0

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
52/100Fair
Development Activity0
Maintenance20
Community88
Maturity60
Momentum40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
73/100Good
Architecture75
Code Quality78
Innovation58
Learning Curve80

Redigo is a Go client library for the Redis and Valkey databases. It exposes a small, generic Do(commandName string, args ...interface{}) interface that maps directly onto the Redis command reference, so any command — including new ones the client has never seen — works without waiting for library updates. Reply values come back as interface{}, converted with a set of typed helper functions (redis.Int, redis.String, redis.Bool, redis.Values, redis.Scan) rather than a large surface of command-specific methods.

Beyond basic command execution, Redigo supports pipelining and pipelined transactions via Send/Flush/Receive, a thread-safe Pool for concurrent connection reuse, a PubSubConn wrapper for publish/subscribe workflows, and a Script type that wraps Lua scripts with optimistic EVALSHA execution and SHA1 hash caching. Because the command API stays untyped and generic, Redigo has stayed maintainable through more than a decade of Redis command additions without requiring structural rewrites, and it now documents Valkey (the Redis fork) support explicitly.

What You Get

  • A generic Do(commandName, args...) method that supports every Redis command, including ones added after the library was released, with an explicit Go-type-to-RESP argument conversion table
  • Typed reply helpers (redis.Int, redis.Bool, redis.Bytes, redis.String, redis.Strings, redis.Values, redis.Scan) that wrap (reply, err) pairs and convert raw interface{} replies into concrete Go types
  • A thread-safe Pool type with MaxIdle, IdleTimeout, custom Dial/DialContext functions, health checks via TestOnBorrow, and Stats() for exposing pool metrics to Prometheus or similar
  • Pipelining and pipelined-transaction support through Send, Flush, and Receive, letting callers batch multiple commands (including MULTI/EXEC) over a single round trip
  • A PubSubConn wrapper with Subscribe, PSubscribe, Unsubscribe, and PUnsubscribe methods, plus a typed Receive() for handling Message, Subscription, and error events in a type switch
  • A Script type that computes and caches a script’s SHA1 hash and calls EVALSHA optimistically, falling back to EVAL only when the server hasn’t cached the script yet

Common Use Cases

  • Caching layer for a Go web service — connection-pooled GET/SET/EXPIRE calls behind an HTTP handler, using redis.String/redis.Bytes to unwrap replies
  • Rate limiting and counters — atomic INCR/EXPIRE sequences pipelined through Send/Flush/Receive to minimize round trips under load
  • Pub/sub messaging between services — PubSubConn.Subscribe plus a receive loop dispatching on redis.Message and redis.Subscription types
  • Server-side scripted operations — packaging multi-step Redis logic (e.g. check-and-set patterns) as Lua via the Script type to keep them atomic and avoid extra network round trips
  • Connection pool observability — wiring Pool.Stats() into an application’s existing metrics pipeline (Prometheus gauges for active/idle connections and wait time) to monitor Redis usage in production

Under The Hood

Architecture Redigo is organized as two packages: redis, the core client, and redisx, a small set of higher-level convenience wrappers (ConnMux, db_test.go-covered helpers) built on top of it. The core redis package centers on the Conn interface, implemented concretely by an unexported conn struct in conn.go that owns a net.Conn, buffered reader/writer, and scratch buffers for RESP-protocol framing. pool.go layers a thread-safe Pool on top of Conn, returning wrapped activeConn/errorConn values that implement the same ConnWithTimeout interface so pooled and unpooled connections are interchangeable at the call site. script.go and pubsub.go are thin wrappers that compose Conn rather than reimplementing protocol handling, so the entire library’s behavior funnels through one connection abstraction — replacing that abstraction (e.g. to support cluster-aware routing) would touch conn.go, pool.go, and every wrapper that type-asserts against Conn.

Tech Stack Redigo has effectively zero runtime dependencies — go.mod declares only github.com/stretchr/testify as a test-only dependency, with the Go standard library (net, bufio, crypto/tls, crypto/sha1, context) doing all the protocol and connection work. It targets Go 1.17+ and implements the RESP wire protocol directly rather than delegating to a generated client, which keeps the binary footprint small and avoids transitive dependency churn — a deliberate design choice reflected in the module’s near-empty dependency graph.

Code Quality The redis package pairs each core source file with a corresponding _test.go file (conn_test.go, pool_test.go, script_test.go, reply_test.go, scan_test.go, pubsub_test.go, commandinfo_test.go), plus example tests (pubsub_example_test.go, zpop_example_test.go) that double as documentation and are run via go test -race ./... in CI across multiple Go and Redis/Valkey versions (GitHub Actions workflow go-test). A separate golangci-lint workflow enforces static analysis on every push and PR. Errors are returned as plain Go error values or the library’s typed redis.Error, following idiomatic Go error-handling conventions rather than panics.

What Makes It Unique Rather than generating or hand-writing a method per Redis command, Redigo exposes one generic Do/Send surface and lets the reply-helper functions handle type conversion — a print-like API modeled explicitly on fmt.Printf-style variadic calls. This means Redigo has needed no structural changes to support the hundreds of Redis commands added since the library’s 2012 origin, and the same generic surface now works unmodified against Valkey, the community Redis fork, without any Valkey-specific code path.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search