It’s been now at least 12 (!) years that I’ve been using Redis. I still love it today as much as I loved it back then.
I find this remarkable. Precious few things, particularly *software* things, are able to hold one’s love. As much as I love nodejs, or javascript itself for that matter, I’m kinda looking forward to not having to use them in a few years. But Redis? Even if I were to use a *completely* new system, I’d need something exactly like what Redis provides.
What is so special about Redis? That’s what I want to explore here. And, as a maker of tools, what I want to understand, so I can get the tools that I make to be a bit more like Redis.
OK, things to love, in no particular order:
- Quite easy to set up: it was never difficult to install Redis. On the few times that I needed to change its configuration, it was also a trivial thing to do.
- Once you set it up, it runs forever. The only times I experienced a Redis failure were when my server ran out of RAM. My working assumption, validated by 12 years of continuous (and sometimes very heavy) use is that Redis will run well unless it runs out of memory. And it runs out of memory not because of memory leaks or “aging” of its runtime, but rather because one has put too much stuff in it. So that’s completely under your control.
- A solid node.js client: the node.js client *just works*. In all these years, I only got tripped by a subtle bug (or unexpected behavior). That’s just excellent, particularly given the brittleness over time of most javascript tooling.
- It is *so* easy to understand: a few data types (string, set, list, hash, zset, plus a few others that are there if you need them). A few operations for each data type, but the ones you want and need. Transactions, and if you want, a scripting language to run commands within a transaction within Redis. Thanks to Redis, I learned to structure the core parts of my programs with fundamental data structures. Most of the things I did at tagaway would have been somewhere between hard and impossible if I had used relational databases.
- It is single threaded: this means that you *know* that Redis is doing one thing at a time, so it’s easier to reason about what you’re doing.
- It is *so* fast: tens of thousands of operations per second is par for the course for Redis. If you’re lucky enough to run it in the same server as your runtime/backend, the thing just blazes. Small operations involving the database take less than 5ms. Involved operations take usually well under 50ms, even if you do multiple back and forths between your backend and Redis. What makes this even better is that Redis even tells you what’s the approximate performance cost of each operation, which makes performance tuning even more flowing.
- No initialization speed bumps: to create a hash, you don’t need to use a CREATE command. Rather, you just set one (or several) fields on a key using a hash operation, and your hash gets initialized. It’s the same on the way out: once you remove the last key of a hash, the entire hash is removed completely. This goes for all the other data types as well. It’s hard to overstate how much this simplifies one’s logic, the amount of conditionals (with potential back and forths) that you save by having this property of auto-initializing and auto-deleting.
- Safe strings: you NEVER have to worry about sanitizing the inputs you put into Redis to avoid injection. You can put anything in a Redis string and it won’t be able to “escape” to a higher level where it can run commands. Yet another speed bump you don’t have.
- Upgrading is painless: perhaps because I’ve always used a subset of what it has to offer; but I’ve never encountered a single issue jumping to a new major version.
- Easy to backup: just be constantly backing up the RDB file (and/or AOF file) generated by Redis, and you should be good.
- Nice CLI: the CLI is quite nice to work with. Also its INFO command is very informative.
- Easy to run a replica: just set it and forget it.
Now, there’s things I don’t like so much about Redis, some inherent to it, some that perhaps could have been avoided:
- [AVOIDABLE] Redis Cluster picks availability over consistency, and that makes it harder to understand. I wish they had gone with a simpler, consistency-first approach to replication.
- [UNAVOIDABLE] You have to make your own indexes if you’re storing relational-like data.
If I had to summarize what makes Redis so great:
- A brilliant idea: an in-memory server that provides access to fundamental data structures.
- Simplicity of design: simple data types, simple operations against each of them. The fact that it is single-threaded.
- Reliable and blazing performance: because everything is in memory and the data structures are well implemented, the performance is reliably stellar.
- Sheer ruggedness: very very few systems are able to run for years without falling over, especially under load. But Redis surely can.
Thank you again, antirez, for having built Redis; as well as to the community, for contributing to it and keeping it alive.