Redis is one of the wonders of the software world. Its versatility, lightning-fast performance, and ease of use as an in-memory data structure store, cache, and message broker have made it a cornerstone of so many applications.
Managing Redis without a GUI, though, can be more challenging for non-technical teams. Knowing what data is stored, how it's structured, and how to manipulate it efficiently often requires specialized tools and a deep understanding of Redis commands. This means it's off-limits to the end users who might need it most: sales teams that need up-to-date dashboards, customer support reps who need real-time user session information, or product managers tracking feature usage metrics live.
Building easy-to-use GUIs for Redis data is an excellent way for developers to empower their non-technical colleagues and abstract away the complexities of Redis commands.
Let’s get started with this guide to building a Redis GUI in Retool.
For this tutorial, we’ll use a cloud-hosted Redis instance from Redis.io. If you’re interested in a Redis GUI, you likely already have a Redis instance up and running somewhere. If not, this is a good option.
You’ll just need four parameters to connect:
- The endpoint URL. Here, that is “redis-11337.c323.us-east-1-2.ec2.redns.redis-cloud.com”
- The port. Here, that is “11337”
- Your username. Here, that is “default”
- Your password. Here, that is “wh@tD0y0uTh!nkWe'r3$tup1d?”
Log into Retool, then within your dashboard, we first want to set up a new resource:
![](/blog/_next/image?url=https%3A%2F%2Fcdn.sanity.io%2Fimages%2Fbclf52sw%2Fproduction%2F5c1628959aa60d07296cef00b6c32bf282145cad-654x368.png&w=3840&q=75)
Scroll down to “Databases,” and choose Redis:
![](/blog/_next/image?url=https%3A%2F%2Fcdn.sanity.io%2Fimages%2Fbclf52sw%2Fproduction%2Fa993bd8c833a6feeaea37630279fd01e2d3f8295-1756x744.png&w=3840&q=75)
This is where we’re going to need the parameters above. First, name your Redis resource, then add the host, port, username, and password:
![](/blog/_next/image?url=https%3A%2F%2Fcdn.sanity.io%2Fimages%2Fbclf52sw%2Fproduction%2F644fdb72f593c8eec099e90691b3bd9e7c9fe12b-1836x1232.png&w=3840&q=75)
With those, we can then hit “Test connection” to test everything is working correctly:
![](/blog/_next/image?url=https%3A%2F%2Fcdn.sanity.io%2Fimages%2Fbclf52sw%2Fproduction%2Fc30836c656f1854ccc10fb0c496ccce823bbdbf2-1782x1272.png&w=3840&q=75)
It is! Then hit “Create resource,” and we’re ready to rock.
What are we going to create? In our SQL GUI tutorial, we created an interface for a customer table that gives us more information about each customer. We could do the same thing here, but this data type isn’t Redis’ forte.
The point of in-memory stores is to store data that needs to be accessed quickly and frequently. For our Redis GUI, we will focus on creating an interface that showcases Redis' strengths. We will create that staple of SaaS sales teams everywhere—the sales leaderboard. Here’s our GUI:
![](/blog/_next/image?url=https%3A%2F%2Fcdn.sanity.io%2Fimages%2Fbclf52sw%2Fproduction%2Fa9571e844e6ca5347d0de35f03761fbc0f0339c6-1632x818.png&w=3840&q=75)
We’ve prepopulated Redis with some sales data for each of our reps. Basically, within Redis, we have:
Sales Leaderboard (Sorted Set):
- Key:
sales:leaderboard
- Members: Sales representative names
- Scores: Total sales amount for each rep
- Purpose: Quickly retrieve top performers and total sales per rep
Individual Sale Records (Hashes):
- Key pattern:
sale:{id}
- Fields:
rep:
Name of the sales representative,amount:
Sale amount,timestamp:
Time of the sale - Purpose: Store detailed information about each sale
Sales Counter (String):
- Key:
sales:next_id
- Value: An incrementing integer
- Purpose: Generate unique IDs for new sales
Recent Sales (Sorted Set):
- Key:
sales:recent
- Members: Sale IDs (in the format
sale:{id}
) - Scores: Timestamp of the sale
- Purpose: Maintain an ordered list of recent sales for quick access
We’re looking to update this information (individual sales records) or show this data (leaderboard, counter, recent sales) within our GUI. To create our GUI, we’ve used a few Retool components:
- A Key-Value component to show the top 3 sales representatives with their names, and total sales.
- There's a Select component for choosing a sales representative.
- The "Sale Amount" field is a currency input component.
- There's a New Sale button component.
- The "Number of sales" and "Latest Sale" sections use statistic components to display large numbers with labels.
In our case, we need to use some of the more specialized commands to get the data we need. For instance, we’re going to:
- Retrieve the top-performing sales reps using ZREVRANGE on
sales:leaderboard
- Add new sales and update rep totals atomically using ZINCRBY on
sales:leaderboard
- Fetch recent sales efficiently using ZREVRANGE on
sales:recent
- Access detailed information about any specific sale using HGETALL on
sale:{id}
Let’s start with populating our Key-Value components with the top performers. Here’s what this is going to look like within the Retool Code interface:
![](/blog/_next/image?url=https%3A%2F%2Fcdn.sanity.io%2Fimages%2Fbclf52sw%2Fproduction%2F05dd2bf8a4176c2ba51060d57555aa6b2127b234-1068x1254.png&w=3840&q=75)
The Redis command we are using is:
1ZREVRANGE sales:leaderboard 0 -1 WITHSCORES
This retrieves all members of the leaderboard, sorted from highest score (sales amount) to lowest. The -1 means "to the end of the set". WITHSCORES includes the scores (total sales amounts) alongside the members (sales reps).
If this was SQL, we could use this output to quickly create a table. But Redis doesn’t respond with easy-to-manipulate tabular data. Instead, we have to do some JS-fu to get it in the correct format for our component. Here’s our JavaScript transformer:
1return _.chunk(data, 2).map(([name, val]) => ({name, val}))
All this does is extract the name and total sales for the person at the top of the list. We can then use this data in one of our Key-Value components using:
1{{ leader.data[i] }}
Where i is the index for the rep we want. For instance, if we want the first person in the list, we use:
1{{ leader.data[0] }}
For the number of sales, we use this command:
1ZCARD sales:recent
This returns the number of members in the sorted set, corresponding to the total sales recorded. This then becomes the value of one of our statistic components using:
1{{ number_sales.data.result }}
Getting the most recent sales data is a little more interesting. We need two different Redis commands to get this information. First, we want to get the key for the most recent sale. We do this by using:
1ZRANGE sales:recent -1 -1
This command returns the ID of the most recent sale (e.g., "sale:123"). We can then use this as the input to another command:
1HGETALL {{ recent_sale_key.data }}
HGETALL returns all fields and values of the hash stored at that key. In this case, we get the rep name and value for the most recent sale that we can then add to our other statistic component. We make the value:
1{{ recent_sale.data.amount }}
And we can make the caption the name of the rep for completeness:
1Rep: {{ recent_sale.data.rep }}
The only other data we need to initialize our GUI is a list of reps for our selected component. We can get that using the same command for our leaderboard:
1ZREVRANGE sales:leaderboard 0 -1 WITHSCORES
Along with our transformer:
1return _.chunk(data, 2).map(([name, val]) => ({name, val}))
This creates a list of names that we add to our select using:
1{{ item[0] }}
Great! With this, our leaderboard will load our prepopulated data from Redis. But obviously, we want a way to add sales to the database and update the leaderboard. To do that, we will take the rep selected in our dropdown and the amount in the currency field and add them to Redis when the “New Sale 🎉” button is pressed.
This is going to require some daisy-chaining of queries. Luckily, in Retool, we can trigger one query by clicking the button and then have each subsequent query triggered by the previous queries. Let’s first create an incr_sales query
:
1INCR sales:next_id
This will create an ID for our new sales. With that ID, we can then set the sales information in Redis. We’ll create an add_sale query that incr_sales will trigger:
1HMSET sale:{{sales:next_id}} rep "{{select1.value}}" amount {{numberInput1.value}} timestamp "{{moment().format()}}"
Here, we use HMSET to create a new hash in Redis representing a single sale. The key for this hash is 'sale:' followed by the new ID we just generated. We set multiple fields in this hash: the rep's name, the sale amount, and the timestamp of the sale. The values for the rep and amount come from our components, while the timestamp is generated using Moment.js built into Retool.
We then set this as the query within the incr_sales event handler -> success:
![](/blog/_next/image?url=https%3A%2F%2Fcdn.sanity.io%2Fimages%2Fbclf52sw%2Fproduction%2F79382dc93082dfdaa169a7b20979cdecb9018310-886x562.png&w=3840&q=75)
This will then trigger an add_recent_sale
query:
1ZADD sales:recent {{moment()}} sale:{{sales:next_id}}
Here, we add the new sale to our 'sales:recent' sorted set. The ZADD command adds a new member to a sorted set. In this case, the score is the current timestamp from Moment, which allows us to keep the sales ordered by time. The member we're adding is the key to the sale hash we created.
Finally, we use that to trigger update_leaderboard
:
1ZINCRBY sales:leaderboard {{numberInput1.value}} "{{select1.value}}"
Here, we update the sales leaderboard by incrementing the score of the sales rep who made the sale. ZINCRBY increases the score of a member in a sorted set by the specified amount. In this case, we're increasing the rep's score (total sales) by the amount of the new sale.
Let’s use it. Emma is crushing it and just made a $20k sale. Baller:
![](/blog/_next/image?url=https%3A%2F%2Fcdn.sanity.io%2Fimages%2Fbclf52sw%2Fproduction%2Fc3d1f9a697e02a0594a02bc2347b3f136cb8a58d-1628x814.png&w=3840&q=75)
Then, we can see the updated leaderboard with the new sale:
![](/blog/_next/image?url=https%3A%2F%2Fcdn.sanity.io%2Fimages%2Fbclf52sw%2Fproduction%2F74c6a8759da5eb4300f645102ddf2f3a17dbe4cb-1626x818.png&w=3840&q=75)
Now Emma can show her team how much she's closed in her new Redis GUI.
That's it. We've created a GUI for underlying Redis data using Retool. You can reuse this pattern whether your Redis data is sales, user activity logs, real-time analytics, caching, session management, gaming, inventory, or any other use case requiring fast, frequent data access. Now, your internal teams can have easy-to-use data at their fingertips.
Sign up for free to start building your own Redis GUI in Retool now.
Reader