If you have ever created a local Node.js / Express application that uses session variables for data persistence (i.e.
req.session), then you have probably used the
express-session library that comes along with most boilerplate Express server configurations.
You may have also noticed that the
express-session docs explicitly state the following:
Warning The default server-side session storage,
MemoryStore, is purposely not designed for a production environment. It will leak memory under most conditions, does not scale past a single process, and is meant for debugging and developing.
If you have never been exposed to production application architecture, then this information might confuse you a bit. It is assuming that we probably have multiple instances of our application running (and perhaps on multiple boxes) under a load balancer like NGINX that is taking some kind of round-robin approach to fulfilling client requests.
With a setup like this, a typical user journey may comprise of the following:
- User A goes to your site and logs in (their request is processed by box One), establishing their user session data.
- They click on the “My Profile” section of your site to go look at their private profile (this request is round-robined and sent to box Two). Access to this feature requires a user to be logged in, and requires the user’s session data for processing.
Whoops! How does box Two know about the session data established on box One so that it can proceed with the request? This is where Redis comes to the rescue.
What Is Redis
Here it is, straight from the horse’s mouth:
Redis is an open source (BSD licensed), in-memory data structure store, used as a database, cache and message broker.
In simple terms, it is an open source database technology that uses key-value pairs which are stored in memory. It has the ability to store complex data structures like lists and sets, among others. And since it runs from memory, it is very fast. In other words, it is perfect for storing and retrieving application session data.
This is the perfect solution for solving the previous scenario, where user A needs access to their session data for their request on box Two (that was previously established while on box One). Below is an example of how this works.
How Does It Work
For our previous example, user A made a request on box Two that required their session data for further processing (which was established while on box One). In this case, the entire user journey could have followed this flow:
- User A goes to the homepage on box One. A session cookie & ID is generated by our Express middleware (more on that later) when the request is made. The cookie & session ID is saved in our Redis database, and the cookie is sent back to and saved by the user A’s browser (identified by the session ID).
- User A goes to the login link and then logs in (the request is sent to box Two). On this request, user A’s existing browser cookie is sent to our server and it’s ID (same as the session ID) is read by our Express middleware, which reaches out to Redis and finds the matching ID. On successful login processing, we establish a couple of session variables via
req.session.userEmail. As soon as we state these, they are also saved in the Redis database under the same ID as key-value pairs (i.e.
After the above login processing has completed, User A’s requests now all have access to the
userEmail session variables wherever they might be needed, via our saved Redis entry. On every subsequent request, our Express middleware reaches out to Redis and grabs User A’s saved session data via the originally established session ID from step one.
How To Use It With Express
Finally, let’s get down to actually using Redis locally. We will have a running Express server, and we will have a separate instance of Redis running. For Redis installation instructions, please see the installation docs.
- Add the required libraries to your main Express server file and initialize the Redis store:
2) Initialize Redis from the command line prompt (make sure it’s installed). Per the Redis documentation, we don’t have to provide a configuration file as the second argument, but it is recommended to do so. Redis provides a configuration file on their site, which you should use:
Upon successful initialization, you should see a nice little welcome screen in your terminal:
redis-cli, ping Redis in your terminal so that you know it’s listening (see the cli docs). You should get something similar to below. Next, execute the
monitor instruction at the cli prompt so that any session setting/getting can be viewed after you make a client request:
4) Start your express server and initialize a browser client request to your app. You should immediately see activity at your Redis monitor prompt, which shows the session ID and cookie information generated.
refreshToken keys? Those were set in an Express route in my app after login via
req.session.refreshToken, which means we are successfully storing and getting session vars from Redis!
5) Inspect your browser to view the cookie (in the Chrome inspector, that’s under “Cookies” in the Application tab). You should see the cookie name “_redisPractice” listed under the Name column. Check out the
Value item as well. Ignoring the serialization, it matches the session ID in Redis!
This confirms that we are successfully saving and retrieving session data between our client requests and our completely independent Redis data store which is completely separate from our application instance! 😋 === YUM
A Few Useful redis-cli Commands
It’s important to go over a few of the terminal commands that may help you while you are debugging and testing your new external session storage. Note that all of these must be executed at the
redis-cli prompt, which you can initialize by typing
redis-cli into your terminal. You can see a more comprehensive list of commands here.
monitor will show real-time output as any activity occurs
KEYS * will show a numbered list of all existing data keys
GET [put the key here] will show you the contents of a specific key
ttl [put the key here] will show the remaining time till expiration
flushdb removes all keys from the currently selected database
In this article, you learned how and why to use Redis as your application’s session store over express-session’s
MemoryStore. You also saw actual output and verification that it works! I hope you enjoyed the article and that it helps you become a better developer. Please click the clap icon if you learned something 😄