redcon: a Redis server framework, written in about a hundred lines of Go
Redis compatible server framework for Go
At a glance
- What is it?
- A minimal Go library that handles the RESP protocol and connection handling so you can write a Redis-compatible service without writing a network server first.
- Who is it for?
- redcon is small in a way that is worth being precise about. The library itself is two files of real code, redcon.go and resp.go, with a test file each, and everything it provides is the RESP parser plus connection handling.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 82 days ago.
- What is it written in?
- Mainly Go, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 28, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The entire API is one function and two types
The features list states the interface plainly: one function, `ListenAndServe`, and two types, `Conn` and `Command`. That is an unusually small surface for a network framework, and it is the reason the shipped example fits on a screen.
You pass a handler that receives a connection and a parsed command, and you write replies back through the connection:
err := redcon.ListenAndServe(addr,
func(conn redcon.Conn, cmd redcon.Command) {
switch strings.ToLower(string(cmd.Args[0])) {
default:
conn.WriteError("ERR unknown command '" + string(cmd.Args[0]) + "'")
case "ping":
conn.WriteString("PONG")
}
},
...
)`ListenAndServe` takes three callbacks. The first handles commands. The second accepts or denies the connection, returning a bool, which is where you would put authentication or an address allowlist. The third is a close callback receiving the connection and any error.
Because arguments arrive as raw bytes rather than parsed values, the example lowercases the command name with `strings.ToLower` and compares strings, and every handler checks `len(cmd.Args)` before indexing. Redis commands are positional and variable arity, so that discipline is not optional.
The clone example is a teaching artifact, not a Redis replacement
The README is upfront that the example is a full Redis clone accepting a specific list: SET, GET, SETNX, DEL, PING, QUIT, PUBLISH, SUBSCRIBE and PSUBSCRIBE. You can run it with `go run example/clone.go` and it listens on port 6380.
The storage is a map and a mutex:
var mu sync.RWMutex
var items = make(map[string][]byte)
var ps redcon.PubSubEverything else follows from that. The SETNX handler is a slightly awkward demonstration of the locking discipline, taking a read lock to check for the key, releasing it, then taking a write lock to insert. That is correct for showing the pattern and is exactly the kind of check-then-act that would be wrong in production, where a concurrent client could win the race between the two locks.
It is worth being clear about what the example is not. There is no persistence, so a restart loses everything. There is no eviction, no key expiry, no transactions, no Lua, no replication, no cluster support, and no data structures beyond flat strings. It also does not validate argument types, so a client sending a wrong-typed command gets whatever the handler does rather than a proper error.
The benchmark tables in the README run the example under redis-benchmark, which is the same client real Redis gets, so those numbers reflect protocol handling cost rather than anything about data structure performance.
Benchmarks that show protocol handling cost, not Redis performance
The README compares against Redis directly, and the numbers are large enough to be misleading if read carelessly:
Redis, single-threaded with no disk persistence, is reported at 941,265 requests per second for SET and 1,189,909 for GET. The redcon example single-threaded is reported at 2,018,570 for SET and 2,403,846 for GET. With GOMAXPROCS=0 for multithreading, SET is 1,944,390 and GET is 3,993,610.
Those figures come from a MacBook Pro with a 2.8 GHz Intel Core i7 running Go 1.7, which dates the measurement considerably. More importantly, they measure two different amounts of work. Real Redis parses the request and then executes a command against a real data structure with real semantics. The example parses the request and performs a map assignment. There is no reason a map write should cost more than Redis's internal work, and the result reflects that.
What the comparison does establish is that the RESP parsing and connection layer is not the bottleneck. That is the useful takeaway, and it is a real one: it means a service built on redcon will spend its time in your handler rather than in the protocol.
The fact that the example handles multiple cores without any explicit threading code is the other interesting data point, since the features list simply says multithreaded. Go's scheduler and the per-connection goroutine model give you that without writing any of it yourself.
Client compatibility, pipelining, and TLS
The claim that matters most in practice is interoperability, and the README names the clients it works with: redigo, redis-py, node_redis and jedis. That covers the major language ecosystems, so an existing client can talk to a service built on this library without modification.
Pipelining is supported, along with telnet commands, so you can exercise a server from a terminal without a Redis client installed. Pipelining is the feature most likely to matter if your handler does anything slow, because it lets a client send many commands without waiting for a reply to each one, and a handler that processes them in order on one goroutine will block that client's subsequent commands behind the slow one.
TLS is supported through a separate function, `ListenAndServeTLS`, and the README notes that the same clone example is provided for serving over TLS at `example/tls/clone.go`. Being able to terminate TLS in the library, rather than in a reverse proxy, is convenient for services that need to expose Redis protocol over the public internet.
Pub/sub support is handled by the redcon.PubSub type rather than by the handler. The example calls `ps.Publish` for PUBLISH and hands the connection itself to `ps.Subscribe` or `ps.Psubscribe`, which is the design that makes subscription state work across connections. Note the type name: Publish is the verb for sending, Subscribe and Psubscribe the methods for receiving.
An older library, written in three languages, with no releases
The repository layout says a lot. There are exactly two source files, redcon.go and resp.go, with redcon_test.go and resp_test.go beside them, plus an `example/` directory and a go.mod and go.sum. There is no cmd directory, no internal package split, and no configuration file. This is a library, not a server product.
The README also notes that the library is available for Rust and C, pointing to separate redcon.rs and redcon.c repositories. A three-language implementation of the same protocol framework is a good sign about the stability of the protocol layer, and a reasonable way to decide whether the Go version is the right binding for your stack.
On activity, the numbers deserve a plain reading. The repository is not archived and the last push recorded is 2026-07-22, so commits are still arriving. But no releases are attached, and the README's contact section points at a Twitter account, which dates the document. With 172 forks and only 14 open issues, this is a library that got used widely, reached a stable shape, and then settled into maintenance.
That profile is fine for a protocol library. The RESP format does not change often, and the tests cover both files. It does mean you should read the source rather than expect a maintained release cadence, particularly if you need to add a reply type or a command with unusual argument shapes.
Editorial conclusion
redcon is small in a way that is worth being precise about. The library itself is two files of real code, redcon.go and resp.go, with a test file each, and everything it provides is the RESP parser plus connection handling. What that buys you is the ability to write a command handler without first solving sockets, timeouts, pipelining and the reply encoding rules, which is genuinely the tedious part of writing a Redis server from scratch. What it does not give you is a Redis implementation: the shipped example stores keys in a Go map under a mutex and has no persistence, no eviction, no replication and no scripting, so treating the benchmark numbers as a Redis comparison would be a mistake. It is also an older library with no releases attached, so read the source before depending on new APIs. Use it when you are writing a purpose-built service that speaks the Redis protocol, not when you want Redis.
Frequently asked questions
What does REDCON mean here?
REDCON is the name of the library, a Redis compatible server framework for Go maintained by tidwall. It is unrelated to REDCON the energy drink, and to REDCON1, which refers to the military readiness condition system. In this repository the name refers to the Go package you import as github.com/tidwall/redcon.
How do I build a Redis server with redcon?
Call ListenAndServe with a command handler and call conn.WriteString, WriteBulk, WriteInt, WriteNull or WriteError to reply. The shipped example at example/clone.go implements SET, GET, SETNX, DEL, PING, QUIT, PUBLISH and SUBSCRIBE over an in-memory map, and runs with go run example/clone.go on port 6380.
Does redcon work with existing Redis clients?
Yes. The README names redigo, redis-py, node_redis and jedis as supported, covering the main language ecosystems. The features list also includes pipelining and telnet command support, so you can exercise a server from a terminal without installing a Redis client. TLS is available through ListenAndServeTLS.
Is redcon faster than Redis?
The README's benchmarks report the example ahead of Redis, at roughly 2.0 million SET requests per second against Redis at about 941,000, but those figures measure different work. Real Redis executes commands against real data structures, while the example performs a map assignment. They were also measured on Go 1.7 and old hardware. The fair reading is that RESP parsing is not the bottleneck.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/tidwall-redcon)