Real-World Redis Tips

Redis might sound like it’s just a key/value store, but its versatility makes it a valuable Swiss Army knife for your application. Caching, queueing, geolocation, and more: Redis does it all. We’ve built (and helped our customers build) a lot of apps around Redis over the years, so we wanted to share a few tips that will ensure you get the most out of Redis, whether you’re running it on your own box or using the Heroku Redis add-on.

Use a Connection Pooler

By using a connection pooler, you'll reduce the connection overhead and therefore speed up operations while reducing the number of connections you use.

Most Redis libraries will provide you with a specific connection pooler implementation; you just have to make sure you use them. Measure, compare, and adapt the size of your Redis connection pool so that you get the best performance out of it.

You'll probably maintain a connection per dyno, so make sure your that the total amount of connections for each pool doesn’t exceed your add-on plan’s maximum connections.

Give a Name to Your Client

Redis allows you to list connected clients using CLIENT LIST. This command will give you lots of useful information about them too:

CLIENT LIST
id=2 addr=127.0.0.1:49743 fd=5 name=web.1 age=11 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=32768 obl=0 oll=0 omem=0 events=r cmd=client

One very simple way to make that view even more useful is to set a name to all of your connections. In order to do that you can use CLIENT SETNAME. I would recommend setting them to your dyno name, using the DYNO environment variable, so that Redis receives a command like this:

CLIENT SETNAME web.1

Now, you will be able to track and scan your connections at a quick glance.

Set an Appropriate Key Eviction Policy

Redis by default will never evict keys, which means that once your Redis memory limit is reached, it will start returning errors if you try to create or update keys.

To save yourself from those errors, you should make sure you have an appropriate key eviction policy. Here’s a quick rundown of where you might use each one:

  • Caching only use cases: using allkeys-lru will remove the least recently used keys first, whether they are set to expire or not.
  • Mixed usage: volatile will remove the least recently used keys first, but only for keys with an expiry set.
  • Non-caching usage: the default noeviction policy will make sure you don't lose keys or reach a Redis limit unknowingly (in which case it will return an error).

At the end of the day, these are just guidelines. As always, review your application usage and review all the policies available to you before making a decision.

Avoid using KEYS

KEYS is a useful command during development or debugging, but it can result in decreased performance if used when you are in production. KEYS is an O(N) operation, which means that its performance is directly related to the number of keys that you’re looking for. If it’s absolutely necessary for you to go through a list of keys, consider using SCAN.

Set an Appropriate Connection Timeout

By default, Redis will never close idle connections, which means that if you don't close your Redis connections explicitly, you will lock yourself out of your instance.

To ensure this doesn't happen, Heroku Redis sets a default connection timeout of 300 seconds. This timeout doesn’t apply to non-publish/subscribe clients, and other blocking operations.

Ensuring that your clients close connections properly, and that your timeout value is appropriate for your application will mean you never run out of connections.

Use MULTI

MULTI is a very useful command. It allows for a set of operations to be executed with some atomic guarantees. You can think of it as a basic transaction-like semantic, here is an example of how to use it:

MULTI
HMSET atomic name "Project Manhattan" location "Los Alamos" created 1942
ZADD history 1942 "atomic"
EXEC

This provides us with some atomic guarantees, but not full ACID compliance. If your application require stronger guarantees, you should consider using Postgres, which provides you a wide set of isolation levels, plus the ability to rollback.

What are your tips?

Redis is powerful and versatile, and though we see a lot of useful patterns from our customers and in our own apps, we can’t possibly see them all. Share what you’ve learned on the #redistips hashtag, and spread the good word.

Browse the blog archives, subscribe to the full-text feed, or visit the engineering blog.