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-redis package 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:

  1. Drag any redis node onto your canvas
  2. Double-click the node to open its configuration
  3. Click the pencil icon next to "Server" to add a new Redis server configuration
  4. 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
  5. Click Add to save the configuration
  6. 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

  1. Drag an inject node onto the canvas and clear the Inject node so it has no msg.payload or msg.topic set.
  2. Drag a redis-command node next to it
  3. 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)
  4. Add a debug node and connect it to the output of the redis-command node
  5. Connect the inject node to the redis-command node, then connect the redis-command node to the debug node
  6. Click Deploy
  7. 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:

  1. Add another cleared inject node to the canvas
  2. Add a redis-command node and configure:
    • Command: get
    • Server: Your Redis configuration
    • Topic/Key: mykey
  3. Add a debug node
  4. Connect the inject node to the redis-command node, then connect the redis-command node to the debug node
  5. Click Deploy
  6. 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

  1. Drag an inject node onto the canvas.

  2. Drag a change node onto the canvas and configure it to:

    • Set msg.topic to sensor:data
    • Set msg.payload to the following JSONata expression:
{
"temperature": 22.5,
"humidity": 65,
"timestamp": $now()
}
  1. Drag a JSON node, This will stringify the JSON object so it can be stored in Redis.
  2. Drag a redis-command node and set the command to set.
  3. 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.
  4. Click Deploy, then click the inject button to store the JSON in Redis.

Reading JSON Back

  1. Drag an inject node onto the canvas
  2. Drag a change node and configure it to:
    • Set msg.topic to string sensor:data
    • Set msg.payload to JSON []
  3. Drag a redis-command node and set command to get
  4. Drag a json node (this converts between JSON string and object)
  5. Drag a debug node
  6. 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
  7. 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:

  1. Drag an inject node onto the canvas
  2. Drag a change node and set msg.payload to string "ALERT: Temperature critical in Zone A: 85°C - Equipment shutdown initiated"
  3. Drag a redis-out node and configure:
    • Method: PUBLISH
    • Topic: alerts:temperature
    • Server: Your Redis configuration
  4. Connect the inject node to the change node, then connect the change node to the redis-out node
  5. 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):

  1. 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
  2. Drag a debug node

  3. Connect the redis-in node to the debug node

  4. 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:

  1. Drag an inject node onto the canvas
  2. 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;
  1. Drag a redis-lua-script node and configure:
    • Keys: 1
    • Script:
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
  1. 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;
  1. Drag a debug node
  2. 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
  3. 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

  1. 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)
  2. 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:

  1. Drag an inject node onto the canvas
  2. 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);
});
  1. Drag a debug node
  2. Connect the inject node to the function node, then connect the function node to the debug node
  3. 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:

  1. Drag an inject node onto the canvas
  2. 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();
  1. Drag a debug node
  2. Connect the inject node to the function node, then connect the function node to the debug node
  3. 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.