Node-RED

Node-RED Delay Node: Rate Limiting MQTT Messages

High-frequency sensors can flood a broker, a database or an operator's phone. Learn how the Node-RED delay node delays and rate-limits messages, when to queue or drop, how per-topic mode works and how to stay within broker limits.

Node-RED delay node throttling a fast stream of MQTT messages before publishing to a broker
Run this on your own MQTT brokerGet a private, managed MQTT broker on the Free plan and start from ready-made code samples.
Try it free Code samples No card required

The Node-RED delay node holds messages back for a set time or releases them at a fixed rate, which makes it the simplest way to tame fast MQTT streams. In this tutorial you will use it to throttle high-frequency sensor data before publishing, rate-limit each topic separately, choose between queueing and dropping, control the queue at runtime and stay comfortably within broker limits.

Why Rate Limiting Matters for MQTT Flows

A sensor sampling every 100 milliseconds produces ten messages a second. Multiply that by a few dozen sensors and Node-RED is pushing hundreds of messages a second towards whatever sits downstream. Often nothing downstream needs that rate:

  • Brokers enforce limits. Shared and public brokers cap message rates per client. The free public MQTT broker at broker.connectmq.com, for example, allows 10 messages per second per client. Exceed it and messages are rejected or the client is throttled.
  • Dashboards cannot keep up. A browser chart redrawing 50 times a second is unreadable and wastes CPU.
  • Databases and APIs charge per write. Writing every raw sample to a cloud database or calling an HTTP API per message gets expensive and can trip API rate limits.
  • Notifications annoy people. A temperature hovering around a threshold can generate dozens of alerts a minute.

The Node-RED delay node solves all of these without code.

Delay Node Modes at a Glance

Open a delay node and the Action dropdown offers two families of behaviour:

Mode Option What it does Typical use
Delay each message Fixed delay Holds every message for the same time Debouncing, sequencing actions
Delay each message Random delay Holds each message for a random time in a range Spreading load, simulating devices
Delay each message Override delay with msg.delay Uses the delay in milliseconds from the message Per-message timing
Rate limit All messages Releases at most N messages per interval Protecting a broker or API
Rate limit For each msg.topic Limits each topic independently, keeping the latest value Multi-sensor throttling

Delay mode never drops anything; it only shifts messages in time. Rate limit mode either queues extra messages or drops them, depending on the option you pick.

Queue or Drop: The Decision That Matters

In rate limit mode with All messages, the default is to queue: messages beyond the rate wait in memory and are released one by one. Tick drop intermediate messages and extra messages are discarded instead. Recent Node-RED versions also offer sending intermediate messages to a second output, so you can route the overflow somewhere else, for example to a counter.

Choose by asking whether every message matters:

  1. Every message matters (commands, events, counts): queue. Make sure the average input rate is below the release rate, or the queue grows forever.
  2. Only the latest value matters (temperatures, levels, positions): drop, or use per-topic mode. You keep fresh data and memory stays flat.
  3. You need both: send the overflow to the second output and aggregate it, for example into an average.

A queue that grows without bound is the classic delay node failure. If producers outpace the release rate for hours, memory use climbs until Node-RED slows down or crashes. You can cap queues globally with the nodeMessageBufferMaxLength setting in settings.js, but the better fix is to choose dropping for telemetry.

Example: Throttle a Fast Sensor Before Publishing

Simulate a noisy sensor and throttle it to one message every two seconds before republishing on a summary topic. Replace 3e5b with your own random string to keep the topics unique on the public broker.

[
  {"id":"tabdl","type":"tab","label":"Delay demo"},
  {"id":"brkdl","type":"mqtt-broker","name":"ConnectMQ public","broker":"broker.connectmq.com","port":"1883","clientid":"nr-delay-3e5b","autoConnect":true,"usetls":false,"protocolVersion":"4","keepalive":"60","cleansession":true},
  {"id":"tick","type":"inject","z":"tabdl","name":"every 200 ms","props":[{"p":"payload","v":"","vt":"date"}],"repeat":"0.2","once":true,"onceDelay":"1","x":130,"y":80,"wires":[["sim"]]},
  {"id":"sim","type":"function","z":"tabdl","name":"simulate vibration","func":"msg.topic = 'connectmq/demo/3e5b/press1/vibration';\nmsg.payload = { mm_s: Number((2 + Math.random() * 3).toFixed(2)), ts: msg.payload };\nreturn msg;","outputs":1,"x":330,"y":80,"wires":[["rate"]]},
  {"id":"rate","type":"delay","z":"tabdl","name":"1 msg / 2 s, drop","pauseType":"rate","timeout":"5","timeoutUnits":"seconds","rate":"1","nbRateUnits":"2","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":true,"allowrate":false,"outputs":1,"x":540,"y":80,"wires":[["pub","dbgdl"]]},
  {"id":"pub","type":"mqtt out","z":"tabdl","name":"publish","topic":"","qos":"0","retain":"false","broker":"brkdl","x":730,"y":60,"wires":[]},
  {"id":"dbgdl","type":"debug","z":"tabdl","name":"released","active":true,"complete":"payload","x":740,"y":110,"wires":[]}
]

Five messages a second go in; one message every two seconds comes out, always a fresh reading. Watch the result from a terminal:

mosquitto_sub -h broker.connectmq.com -p 1883 -i demo-sub-3e5b \
  -t "connectmq/demo/3e5b/#" -v

Without the delay node, this flow would publish five messages a second from one client, already half the public broker's per-client limit. Add a second sensor and you would be at the limit.

Per-Topic Rate Limiting for Many Sensors

When a single mqtt in node subscribes with a wildcard such as connectmq/demo/3e5b/+/telemetry, a plain rate limit treats all topics as one stream. A chatty sensor would then crowd out a quiet one. Switch the delay node to Rate limit → For each msg.topic.

In this mode the node keeps only the most recent message for each topic and releases them at the configured rate, cycling through topics. Every sensor gets its turn, and only its latest value is sent. That is exactly what a dashboard or a database writer wants. Make sure msg.topic is set correctly; if every message has the same topic, per-topic mode behaves like a single queue of one.

Control the Queue at Runtime

A delay node in queueing mode listens for special properties on incoming messages:

Property Effect
msg.reset Clears the queue without sending anything
msg.flush Sends queued messages immediately; a number sends that many
msg.rate In rate limit mode with the "allow msg.rate to override" option, changes the rate in milliseconds between messages
msg.delay In override mode, sets this message's delay in milliseconds

msg.reset is useful when a machine stops: queued readings from before the stop are no longer meaningful. msg.flush helps when a connection comes back and you want to release buffered commands at once. Wire an inject node with the property set to true to try them.

Debouncing Alerts with a Delay

Rate limits also cure alert storms. Place a rate-limited delay node set to one message per 10 minutes with drop intermediate messages before an email or chat notification node. The first alert goes out at once; repeats within the window are discarded. For per-device alerts, set msg.topic to the device ID and use per-topic mode, so one device cannot suppress another's alarm. If you prefer to keep this logic in code, the cooldown example in our Node-RED subflows guide does the same thing per topic.

Common Mistakes Checklist

  1. Queueing telemetry. Use drop or per-topic mode when only the latest value matters.
  2. Rate limiting after the expensive step. Put the delay node before database writes, HTTP calls or heavy function nodes, not after.
  3. Missing msg.topic. Per-topic mode needs a meaningful topic on every message.
  4. Confusing delay with rate limit. Delay mode shifts every message; it does not reduce the message count.
  5. Throttling at the wrong layer. If devices publish far faster than anyone needs, fix the firmware sample rate instead of discarding data in Node-RED.
  6. Ignoring broker limits. Know your broker's message rate and size limits and design below them.

For transformations before or after throttling, see the Node-RED function node guide, and for the basics of wiring MQTT in Node-RED, the Node-RED MQTT tutorial. The delay node's options are also documented in the built-in help and the Node-RED core nodes documentation.

Publish Throttled Data to ConnectMQ

Once your flow publishes at a sensible rate, move it to a private broker. ConnectMQ is a hosted MQTT broker with TLS on port 8883, MQTT 5 message expiry and per-plan quotas that protect every tenant from floods. The free Serverless plan supports up to 25 connections and 256 KB messages, and paid Serverless plans add QoS 2 and shared subscriptions when you scale. Create your broker at app.connectmq.com with no credit card, then switch the broker node to TLS with your generated credentials. To compare deployment models, read our guide to the cloud MQTT broker.

Frequently Asked Questions

What is the difference between delay and rate limit in the Node-RED delay node?

Delay mode holds each message for a time but passes every message through. Rate limit mode controls how many messages leave per interval and can queue or drop the extra ones.

How do I rate limit each MQTT topic separately in Node-RED?

Set the delay node's action to Rate limit and choose "For each msg.topic". The node keeps the latest message per topic and releases topics in turn at the configured rate.

How do I clear a delay node's queue?

Send a message with msg.reset set to any value. The queue is emptied without sending the queued messages.

Can the delay node cause memory problems?

Yes, if it queues messages faster than it releases them for long periods. Use drop or per-topic mode for telemetry, or limit queue size with nodeMessageBufferMaxLength in settings.js.

Related articles

Node-RED OPC UA Client to MQTT with ISA-95 Topics

Use node-red-contrib-opcua to subscribe to OPC UA variables on a PLC or simulation server, map node IDs to ISA-95 style MQTT topics, and publish values with quality and timestamps.

9 min read

All articles →

Your private MQTT broker is a few clicks away

Create an account, get your broker credentials and connect your first device — no servers to install, patch or scale.