[Back to blogs]

Learn Redis and backend-caching in 10 minutes.

DEV BLOG · Redis · 22/03/25


[NOTE] This section might be edited in the future to add how to use redis as a vector DB for machine learning.


[SECTION] Installation

sudo apt-get install redis
# then run
redis-server
# make a new bash instance and
redis-cli


[SECTION] Introduction

Redis is not a database but a caching solution for faster data access using key value pairs, not like sql or mongodb, the keywords can be both capital and normal


[SECTION] Basic Functions

  • Quit: quit
  • Set: set key_name value (always converts value to string)
  • Get: get key_name (nil if value doesn't exist)
  • Delete: del key_name
  • Does key exists?: exists key_name
  • Get all keys: keys *
  • Clear all keys: flushall
  • Time-to-live: ttl key_name (-1 if key will exist for infinity, else in seconds, -2 if key doesn't exist)
  • Set an expiration time: expire key_name seconds_count (the ttl will reduce by 1 sec every time until the key is removed)
  • Set with exp time: setex key_name seconds_count value

[SECTION] Arrays

  • Left-push in an array: lpush array_name value
  • Access array members: lrange array_name start_index end_index (end_index can be -1 to show all the elements)
  • Right-push: rpush array_name value
  • Left-pop: lpop array_name (returns the popped value and removes it from the array, from the left side, or the beginning)
  • Right-pop: rpop array_name

[SECTION] Sets

Very similar to a list, but each value is always different, for fast access like a hash-map, but only a values array.

  • Add in a set: sadd set_name "value" (we use string with double quotes here, returns one if successfully added, else return 0 for error or duplicate value already exists)
  • Get all elements: smembers set_name
  • Remove from set: sremove set_name "value" (returns 1 or 0 again)

[SECTION] Hashes

One set of unique keys and value pairs

  • Set: hset hash_name key_name value
  • Get: hget hash_name key_name
  • Get all: hgetall hash_name (prints key then value, then next key then value)
  • Delete a key: hdel hash_name key_name
  • Check key exists: hexists hash_name key_name (return 1 if it gets deleted, 0 elsewhere)

[SECTION] Node.js example

// import in your express app
const Redis = requiire('redis');

const redisClient = Redis.createClient();
// or use const client = Redis.createClient({url: your_production_url}); for production

// THIS CODE CAN BE USED IN .get or .patch express functions, from now on, these redisClient functions are similar to all the functions above, lets take an example
redisClient.setexp("key_name", int_time, JSON.stringify(json_data)) // to store json_data as a string from int_time seconds

// .get function's proper utilization, inside the get /path function
redisClient.get("key_name", async (redisError, redisResponse) => { // key_name is generally the url passes into the app.get function of express
	if (redisError) console.error(err)
	if (redisResponse) return res.json(JSON.parse(redisResponse)) // cache hit case
	else { // cache miss case
		let json_data = {}; // get from your real database, i.e, supabase or sql or mongodb and return it

		redisClient.setex("key_name", int_time, JSON.stringify(json_data))
	}
})

// using url query params, not really a redis thing though, naming like this is conventional, inside the get /path function with queries in format of ?param_name=value
redisClient.get(`key_name?param_name=${req.query.param_name}`, async (redisError, redisResponse) => {
	if (redisError) console.error(err)
	if (redisResponse) return res.json(JSON.parse(redisResponse)) // cache hit case
	else { // cache miss case
		let json_data = {}; // get from your real database, i.e, supabase or sql or mongodb and return it

		redisClient.setex(`key_name?param_name=${req.query.param_name}`, int_time, JSON.stringify(json_data))
	}
})


[SECTION] A better JS usage

function getOrSetCache(key, callback) {
	return net Promise((resolve, reject) => {
		redisClient.get(key, async (error, data) => {
		 if (error) return reject(error)
		 if (data != null) return resolve(JSON.parse(data))
		 const freshData = await callback()
		 redisClient.setex(key, int_time, JSON.stringify(freshData))
		 resolve(freshData)
	  })
	})
}

// now inside app.get we just do
const responseData = await getOrSetCache(`key_name?param_name=${req.query.param_name}`, async () => {
	let json_data = {}; // get from your real database, i.e, supabase or sql or mongodb and return it
	return json_data
})
res.json(responseData)