Skip to content
Stand with Ukraine flag

Rule Engine

The Rule Engine is the data processing backbone of ThingsBoard. Every incoming telemetry reading, attribute update, device lifecycle event, or RPC call becomes a Message that flows through a Rule Chain — a visual pipeline of Rule Nodes that filter, enrich, transform, or act on it.

A Rule Engine Message is an immutable, serializable data structure representing a single event:

FieldDescription
Message IDTime-based universally unique identifier
OriginatorThe entity that generated the message (Device, Asset, etc.)
TypeWhat triggered the message — e.g. POST_TELEMETRY_REQUEST, INACTIVITY_EVENT
PayloadJSON body with the event data
MetadataKey-value pairs with contextual data (device name, type, custom fields added by nodes)

For the full list of built-in type strings, originators, metadata fields, and payload shapes, see Rule Engine Message Types.

A Rule Node processes one incoming message at a time and produces one or more outgoing messages. Nodes are the building blocks of Rule Chains and fall into seven categories — see Rule Nodes for the full reference.

A Rule Chain is a directed graph of Rule Nodes connected by relations. When a node produces an outgoing message, the relation type (e.g. Success, Failure, True, False, or a custom name) determines which connected nodes receive it next.

The Root Rule Chain is the default entry point for all incoming messages. There is exactly one Root Rule Chain per tenant at a time. A tenant administrator can define any number of additional chains; both the root and additional chains can forward messages to each other using the Rule Chain flow node.

Device profile routing — a Device Profile can override routing for all its devices with two settings:

SettingEffect
Default rule chainMessages from devices of this profile are routed to the specified chain instead of the Root Rule Chain
QueueMessages from devices of this profile are placed in the specified queue instead of the default Main queue

This lets you isolate processing logic and queue priorities per device type without modifying the root chain.

Every message processing attempt ends as Success, Failure, or Timeout:

ResultWhen it occurs
SuccessThe last node in the processing path completes successfully
FailureA node produces a Failure output and no downstream node handles it
TimeoutOverall processing time exceeds the configured threshold

A message is only marked as Failure if the failure output is unhandled. Connecting a node to the Failure relation (e.g. a log or fallback write) means the failure is handled and the message can still end as Success:

To track success, failure, and timeout counts across all rule chains, use the statistics dashboard. To investigate why a specific node failed, enable debug mode on that node.

  1. Go to Rule chains in the left sidebar.
  2. Click + Add rule chain ⇾ Create new rule chain in the top-right corner.
  3. Enter a name and click Add.
  4. Click the rule chain row to open the editor and configure nodes.
  1. Go to Rule chains in the left sidebar.
  2. Click the Export rule chain icon in the desired row.

A JSON file is saved to your computer.

  1. Go to Rule chains in the left sidebar.
  2. Click + Add rule chain ⇾ Import rule chain in the top-right corner.
  3. Upload the JSON file and click Import.
  1. Go to Rule chains.
  2. Click the flag icon in the desired row and confirm.
  1. Go to Rule chains in the left sidebar.
  2. Open the chain that contains the nodes you want to extract.
  3. Select the nodes and the links between them — drag a selection rectangle around the group, or Ctrl-click each node and each link individually. Without the links in the selection, Create nested rule chain stays disabled.
  4. Press Ctrl+R, or right-click the selection and choose Create nested rule chain. ThingsBoard creates a new rule chain from the selected nodes and replaces them in the current chain with a single Rule Chain node pointing at it.
  1. Go to Rule chains in the left sidebar.
  2. Open the rule chain that will reference the target chain.
  3. From the Flow palette, drag a Rule Chain node onto the canvas.
  4. In the node’s configuration, select the target rule chain.
  5. Wire one or more connections from the relevant node output of your existing flow into the Rule Chain node, then save.
  1. Go to Rule chains.
  2. Click the Delete icon in the desired row — or select multiple rows and use Delete selected.

To configure a rule node, double-click it in the Rule Chain editor. The configuration window is specific to each node type.

Nodes with TBEL/JS scripts provide a Test button. Use it to verify the script with custom inputs before deploying:

PanelContent
Top-leftMessage type
LeftMessage payload
RightMetadata
Script areaThe TBEL/JS function
OutputExecution result

ThingsBoard provides a Statistics dashboard for tracking throughput, failures, and exceptions across all queues, and Debug mode for per-node message tracing. See Rule Engine Monitoring for the full reference, including the debug event columns, the two debug modes, and the step-by-step troubleshooting workflow.

Rule Engine uses message queues to guarantee delivery under load, handle traffic spikes, and control the order in which messages are processed. See Queues for configuration details, submit and retry strategies, and the three built-in queues.

ThingsBoard provides an HTTP API to send custom requests directly to the Rule Engine and return the processing result in the response body — useful for extending the platform API, enriching calls with device/asset attributes, or powering custom widgets.

Use the rule-engine-controller endpoints from the REST API reference. The entity ID in the request becomes the message originator. If omitted, the calling user entity is used.

A DHT22 sensor reports temperatures between −40 °C and +80 °C. Any reading outside that range should be discarded and logged instead of saved.

  1. Go to Rule chains and open the Root Rule Chain.
  2. Drag a Script Filter node onto the canvas. Enter title Temperature Validation and write the script:
    return typeof temperature === 'undefined' || (temperature >= -40 && temperature <= 80);
    Click Add.
  3. Delete the Post Telemetry relation between Message Type Switch and Save Timeseries (hover the connection arrow and click ✕).
  4. Draw a Post Telemetry relation from Message Type Switch to Temperature Validation.
  5. Draw a True relation from Temperature Validation to Save Timeseries.
  6. Draw a False relation from Temperature Validation to Log Other.
  7. Click Apply changes.

Test — out-of-range value (99 °C):

Terminal window
curl -X POST -d '{"temperature":99}' \
http://localhost:8080/api/v1/$ACCESS_TOKEN/telemetry \
-H "Content-Type:application/json"

The value does not appear in Latest Telemetry — filtered and logged.

Test — valid value (24 °C):

Terminal window
curl -X POST -d '{"temperature":24}' \
http://localhost:8080/api/v1/$ACCESS_TOKEN/telemetry \
-H "Content-Type:application/json"

The value appears in Latest Telemetry — saved successfully.