Worker Function Node
Overview
The Worker Function node allows you to execute JavaScript code in a separate worker thread, enabling non-blocking operations that won't freeze the Node-RED runtime. This is particularly useful for CPU-intensive tasks or operations that might take a significant amount of time to complete.
Key Features
- Non-blocking execution: Runs code in a separate worker thread using Node.js Worker Threads API
- Queue management: Automatically queues incoming messages when the worker is busy
- Buffer handling: Efficiently handles binary data using SharedArrayBuffer
- Lifecycle hooks: Provides initialization and finalization code sections
- Module support: Can require and use external npm modules
Configuration
Properties
Name
- Type: String
- Optional: Yes
- Description: A custom name for the node instance
Number of Outputs
- Type: Number
- Default: 1
- Range: 1-10
- Description: Number of output ports for the node
Delay (ms)
- Type: Number
- Default: 0
- Description: Time delay in milliseconds before processing each message. Useful for rate limiting or throttling operations.
Code Sections
The node provides three separate code editors accessible via tabs:
On Start (Init)
Code that executes once when the node is deployed or started. Useful for:
- Initializing variables
- Setting up connections
- Loading resources
// Example: Initialize a counter
var processedCount = 0;On Message (Function)
The main processing function that executes for each incoming message. This code runs in the worker thread.
Available objects:
msg: The incoming message objectnode: Object with methods:node.send(msg): Send a message to the outputnode.error(err): Report an error
Return value:
- Returning a message object will automatically send it to the output
- Use
node.send()for more control or to send multiple messages
// Example: Process image data
const processedData = heavyImageProcessing(msg.payload);
msg.payload = processedData;
return msg;On Close (Final)
Code that executes when the node is stopped or re-deployed. Useful for:
- Cleanup operations
- Closing connections
- Releasing resources
// Example: Log statistics
console.log('Total messages processed:', processedCount);Input
The node accepts any message object. Special handling for binary data:
Bufferobjects are automatically converted toSharedArrayBufferfor efficient transfer to the worker thread- The worker thread automatically converts them back to
Bufferfor processing
Output
The node outputs the message returned by the function code or sent via node.send().
Usage Examples
Example 1: CPU-Intensive Calculation
// Function code
function fibonacci(n) {
if (n <= 1) return n;
return fibonacci(n - 1) + fibonacci(n - 2);
}
const result = fibonacci(msg.payload.number);
msg.payload = { result: result };
return msg;Example 2: Image Processing with Buffers
// Function code
// Assuming msg.payload contains image buffer
const imageBuffer = Buffer.from(msg.payload);
// Perform image processing (placeholder)
// const processed = someImageLibrary.process(imageBuffer);
msg.payload = imageBuffer;
return msg;Example 3: Using External Modules
First, ensure the module is installed in your Node-RED environment:
npm install sharpThen in the function code:
const sharp = require('sharp');
// Resize an image
sharp(msg.payload)
.resize(200, 200)
.toBuffer()
.then(buffer => {
msg.payload = buffer;
node.send(msg);
})
.catch(err => {
node.error(err);
});
// Don't return anything when using async operationsExample 4: Delayed Processing with Queue
Configure delay to 1000ms (1 second):
// Function code
msg.payload = {
processed: true,
timestamp: Date.now()
};
return msg;Messages will be processed one per second, even if they arrive faster.
Technical Details
Worker Thread Architecture
The node creates a single worker thread that:
- Accepts messages from the main thread
- Executes the function code
- Returns results to the main thread
- Processes queued messages sequentially
Queue Behavior
- Messages are queued when the worker is busy
- Queue is processed FIFO (First In, First Out)
- The configured delay applies between message processing
Buffer Handling
- Input buffers are converted to
SharedArrayBufferfor zero-copy transfer - Worker thread receives the data as
Buffer - Output buffers are transferred back using transferable objects for efficiency
Module Resolution
The worker thread inherits the module search paths from the parent process, allowing it to require the same modules available to Node-RED.
Error Handling
Errors in the function code are caught and reported via:
- Node-RED debug panel
- Console logs (prefixed with "Worker caught error:")
- The node's error output
// Example: Proper error handling
try {
const result = riskyOperation(msg.payload);
msg.payload = result;
return msg;
} catch (err) {
node.error('Operation failed: ' + err.message);
// Optionally return error in message
msg.error = err.message;
return msg;
}Performance Considerations
When to Use Worker Function
Good use cases:
- CPU-intensive computations (image processing, data analysis)
- Operations that block the event loop
- Processing large datasets
- Complex mathematical calculations
Not recommended for:
- Simple data transformations (use regular function node)
- I/O operations (already non-blocking in Node.js)
- Very frequent small operations (overhead of worker communication)
Optimization Tips
- Minimize data transfer: Only send necessary data to the worker
- Batch processing: Process multiple items in a single message when possible
- Use delay wisely: Set appropriate delays to control resource usage
- Buffer efficiency: Leverage the built-in buffer handling for binary data
- Avoid excessive queuing: Monitor queue size in high-throughput scenarios
Comparison with Standard Function Node
| Feature | Worker Function | Standard Function |
|---|---|---|
| Execution | Separate thread | Main event loop |
| Blocking | Non-blocking | Can block if code is slow |
| Concurrency | Sequential (queued) | Immediate |
| Buffer handling | SharedArrayBuffer | Direct |
| Module access | Yes | Yes |
| Overhead | Higher (thread communication) | Lower |
Troubleshooting
Worker exits unexpectedly
- Check for unhandled exceptions in function code
- Verify all required modules are installed
- Review Node-RED logs for error details
Messages not processing
- Verify function code returns or calls
node.send() - Check if worker is stuck in an infinite loop
- Review queue status (check delay configuration)
Buffer data corrupted
- Ensure proper Buffer handling in function code
- Verify data types before processing
- Check for race conditions in async operations
Best Practices
- Keep functions focused: One worker function per specific task
- Handle errors gracefully: Always use try-catch for risky operations
- Test with delays: Verify behavior under high load using the delay setting
- Monitor performance: Use Node-RED debug to track execution times
- Document complex logic: Add comments in the function code
- Clean up resources: Use the finalization code for proper cleanup
- Avoid global state: Each message should be independent when possible