Using Redis with Node-RED
Redis is a powerful in-memory data structure store that can be used as a database, cache, message broker, and streaming engine. When combined with Node-RED, Redis provides a fast and efficient way to store and retrieve data, manage session states, implement pub/sub messaging patterns, and share data across multiple Node-RED instances.
This documentation will walk you through integrating Redis with Node-RED, from basic setup to advanced use cases.
Getting Started
Prerequisites
Before you begin, make sure you have the following:
- Ensure you have a running Node-RED instance. The quickest and easiest way to have a manageable and scalable Node-RED instance is by signing up on FlowFuse and creating an instance.
- Install the
node-red-contrib-redispackage using the Palette Manager. - Make sure you have your Redis server details ready.
Configuring the Redis Connection
Before using Redis nodes, you need to configure the connection:
- Drag any redis node onto your canvas
- Double-click the node to open its configuration
- Click the pencil icon next to "Server" to add a new Redis server configuration
- Fill in your Redis server details:
- Name: A friendly name for this connection
- Connection Options: Can be a connection string (e.g.,
redis://localhost:6379) or a JSON object with IORedis options - Cluster: Enable if using Redis Cluster
- Click Add to save the configuration
- Click Done to close the node configuration
Example Connection Options (JSON format):
{
"host": "localhost",
"port": 6379,
"db": 0
}
Understanding the Nodes in the Package
The node-red-contrib-redis package provides five specialized nodes:
- redis-command: Executes any Redis command like SET, GET, or hash operations
- redis-in: Subscribes to pub/sub channels or blocks on list operations for building queue consumers
- redis-out: Publishes messages or pushes to lists
- redis-lua-script: Runs Lua scripts on the server for atomic operations
- redis-instance: Injects a Redis client into your context for direct API access in function nodes
Your First Redis Flow
Let's create a simple flow that stores and retrieves data from Redis.
Storing Data
- Drag an inject node onto the canvas and clear the Inject node so it has no
msg.payloadormsg.topicset. - Drag a redis-command node next to it
- Double-click the redis-command node and configure:
- Command:
set - Server: Your Redis configuration
- Topic/Key:
mykey - Params:
["Hello from Node-RED"](as a JSON array)
- Command:
- Add a debug node and connect it to the output of the redis-command node
- Connect the inject node to the redis-command node, then connect the redis-command node to the debug node
- Click Deploy
- Click the inject button
You should see "OK" in the debug panel, which means your data has been successfully stored in Redis!
Retrieving Data
Now let's retrieve the data we just stored:
- Add another cleared inject node to the canvas
- Add a redis-command node and configure:
- Command:
get - Server: Your Redis configuration
- Topic/Key:
mykey
- Command:
- Add a debug node
- Connect the inject node to the redis-command node, then connect the redis-command node to the debug node
- Click Deploy
- Click the inject button
You should now see "Hello from Node-RED" in the debug panel - the value you stored earlier!
Working with JSON Data
Redis stores values as strings, so you need to convert JSON objects before storing them. You’ll also learn how to send the topic and value dynamically.
Storing JSON
-
Drag an inject node onto the canvas.
-
Drag a change node onto the canvas and configure it to:
- Set
msg.topictosensor:data - Set
msg.payloadto the following JSONata expression:
- Set
{
"temperature": 22.5,
"humidity": 65,
"timestamp": $now()
}
- Drag a JSON node, This will stringify the JSON object so it can be stored in Redis.
- Drag a redis-command node and set the command to
set. - Connect the inject node to the change node, then the change node to the JSON node, and finally the JSON node to the redis-command node.
- Click Deploy, then click the inject button to store the JSON in Redis.
Reading JSON Back
- Drag an inject node onto the canvas
- Drag a change node and configure it to:
- Set
msg.topicto stringsensor:data - Set
msg.payloadto JSON[]
- Set
- Drag a redis-command node and set command to
get - Drag a json node (this converts between JSON string and object)
- Drag a debug node
- Connect the inject node to the change node, then connect the change node to the redis-command node, then connect the redis-command node to the json node, and finally connect the json node to the debug node
- Click Deploy and then click the inject button
Check the debug panel. You should see your JSON object with temperature, humidity, and timestamp.
If you want to explore more Redis commands beyond SET and GET, check the official Redis command reference.
Pub/Sub Messaging
Redis pub/sub allows different Node-RED flows or instances to communicate in real-time. One flow publishes a message, and any subscribed flows receive it instantly.
Publishing Temperature Alerts
Let's create a flow that publishes alerts when temperature exceeds a threshold:
- Drag an inject node onto the canvas
- Drag a change node and set
msg.payloadto string"ALERT: Temperature critical in Zone A: 85°C - Equipment shutdown initiated" - Drag a redis-out node and configure:
- Method:
PUBLISH - Topic:
alerts:temperature - Server: Your Redis configuration
- Method:
- Connect the inject node to the change node, then connect the change node to the redis-out node
- Click Deploy
Subscribing to Alert Messages
Now create another flow that listens for these alerts (this could be on the same or a different Node-RED instance monitoring the facility):
-
Drag a redis-in node onto the canvas and configure it:
- Method:
SUBSCRIBE - Topic:
alerts:temperature - Timeout: (optional) How long the node should listen for messages before automatically stopping.
- Server: Your Redis connection
- Method:
-
Drag a debug node
-
Connect the redis-in node to the debug node
-
Click Deploy
When you click the Inject button in your publisher flow, the alert message will appear in the Debug panel. The subscriber will automatically receive all alerts published to the channel until the timeout (if configured) expires.
Using Lua Scripts for Atomic Operations
Redis Lua scripts allow you to execute multiple Redis operations atomically on the server side. This ensures data consistency and reduces network overhead by bundling multiple commands into a single server-side operation.
Atomic Counter with Rollback
Let's create an inventory system that atomically checks stock and decrements it only if available:
- Drag an inject node onto the canvas
- Drag a function node to prepare the script arguments:
msg.productId = "inventory:product:SKU-12345";
msg.quantityRequested = 3;
msg.payload = [
msg.productId,
msg.quantityRequested
];
return msg;
- Drag a redis-lua-script node and configure:
- Keys:
1 - Script:
- Keys:
local key = KEYS[1]
local requested = tonumber(ARGV[1])
local current = tonumber(redis.call('GET', key) or "0")
if current >= requested then
redis.call('DECRBY', key, requested)
return {1, current - requested}
else
return {0, current}
end
- Server: Your Redis configuration
- Drag a function node to process the result:
const result = msg.payload;
const success = result[0];
const remaining = result[1];
if (success === 1) {
msg.payload = {
status: "success",
message: `Order processed. Remaining stock: ${remaining}`,
remaining: remaining
};
} else {
msg.payload = {
status: "failed",
message: `Insufficient stock. Available: ${remaining}`,
available: remaining
};
}
return msg;
- Drag a debug node
- Connect the inject node to the first function node, then to the redis-lua-script node, then to the second function node, and finally to the debug node
- Click Deploy
Before testing, set the initial inventory using a redis-command node: Command = SET, Topic/Key = inventory:product:SKU-12345, Params = 10. Then trigger the Inject node to initialize the value and process orders atomically.
Direct Redis Client Access with redis-instance
The redis-instance node provides direct access to the IORedis client API in function nodes. This is useful for advanced operations, custom commands, or when you need programmatic control over Redis operations.
Setting Up Redis Instance in Context
- Drag a redis-instance node onto the canvas and configure:
- Name:
redis - Server: Your Redis configuration
- Topic: Enter a topic name to identify the Redis instance in the chosen context (e.g.,
redis). This is the name you will use in function nodes to access the client. - Context:
flow(makes it available to all nodes in the flow)
- Name:
- Click Deploy
The Redis client is now available in the flow context for use in function nodes.
Advanced Pipeline Operations
Pipelines allow you to send multiple commands to Redis in a single network round trip, significantly improving performance for batch operations:
- Drag an inject node onto the canvas
- Drag a function node with this code:
const redis = flow.get('redis'); // Replace 'redis' with your topic if different
// Create a pipeline
const pipeline = redis.pipeline();
// Add multiple sensor readings in one batch
const sensors = [
{ id: 'temp-01', value: 23.5, unit: 'C' },
{ id: 'temp-02', value: 24.1, unit: 'C' },
{ id: 'humidity-01', value: 65, unit: '%' },
{ id: 'pressure-01', value: 1013, unit: 'hPa' }
];
sensors.forEach(sensor => {
const key = `sensor:${sensor.id}:latest`;
const data = JSON.stringify({
value: sensor.value,
unit: sensor.unit,
timestamp: Date.now()
});
pipeline.set(key, data, 'EX', 3600); // Expire in 1 hour
});
// Execute all commands at once
pipeline.exec((err, results) => {
if (err) {
node.error(err, msg);
return;
}
msg.payload = {
message: `Stored ${results.length} sensor readings`,
results: results
};
node.send(msg);
});
- Drag a debug node
- Connect the inject node to the function node, then connect the function node to the debug node
- Click Deploy and click the inject button
All sensor readings are stored in a single efficient batch operation.
Scanning Keys with Cursor
When you need to find keys matching a pattern without blocking Redis (important for production systems), use the SCAN command:
- Drag an inject node onto the canvas
- Drag a function node with this code:
const redis = flow.get('redis'); // Replace 'redis' with your topic if different
async function scanKeys() {
const matchPattern = 'sensor:*:latest';
const allKeys = [];
let cursor = '0';
try {
do {
// Scan with pattern matching
const result = await redis.scan(
cursor,
'MATCH', matchPattern,
'COUNT', 100
);
cursor = result[0];
const keys = result[1];
allKeys.push(...keys);
} while (cursor !== '0');
msg.payload = {
pattern: matchPattern,
count: allKeys.length,
keys: allKeys
};
node.send(msg);
} catch (err) {
node.error(err, msg);
}
}
scanKeys();
- Drag a debug node
- Connect the inject node to the function node, then connect the function node to the debug node
- Click Deploy and click the inject button
This safely scans all sensor keys without blocking Redis operations, making it suitable for production environments with large datasets.
For more Redis commands, patterns, and advanced capabilities, refer to the official Redis documentation.
Below is the complete example that we covered in this document.