Grouped key expiry with redis

Giles Williams
Urban Massage Product
2 min readDec 7, 2014

As I’ll be covering in a later article, our booking process is like no other in the industry — upon entering a postcode on our system, we parallel process a huge combination of travel permutations in order to make sure that every therapist gets to each appointment on time, whilst at the same time maximising their time working with us by not blocking off more time than necessary.

Calculating this diary overview for a certain therapist takes a fair amount of computing power and external API requests, and we were looking for a way to minimise the amount of processing required for a particular route to booking (assuming the customer clicks around a few therapists, maybe changes treatment type etc).

So, we came up with a caching mechanism that satisfies the following constraints:

  • Each cache entry can only be for a certain postcode
  • Each cache entry can only be for a certain date
  • Each cache entry can only be for a certain therapist
  • All caches for a certain therapist on a certain date (at all postcodes) can be expired at once (e.g. when a booking is placed for that therapist, or when they update their diary with us)

To do this, we quickly realised we’d need to use a cache key that looks like the below:

therapist_id::date::postcode

In order to expire a group of keys at once, we ended up storing an additional key per therapist — an incrementer.

This incrementer is then used as part of the cache key as below:

therapist_id::incrementer::date::postcode

This does of course require two hits on redis each time you want to check the cache — you first need to find the latest incrementer for the therapist you’re calculating the diary for, then check the cache.

We tested this method alongside a combination of hset and storing a set of keys against a therapist ID, and found that the incrementer method wasn’t just faster, it was cleaner in terms of stale keys left over.

Our final solution ended up looking something like this (forgive my pseudo code!):

function checkCache(therapistID, date, postcode) {
var incrementer = redis.get("incrementer::"+therapistID);
var key = "search::"+therapistID+"::"+incrementer;
key += "::"+date+"::"+postcode;
return redis.get(key);
}

--

--