How many connections can an MQTT broker handle? The honest answer is "it depends", but it depends on a short, specific list of resources you can measure and plan for. This article explains what limits concurrent MQTT connections, why published numbers rarely match your workload, how to test capacity yourself, and how managed providers translate all of this into plan limits.
Why There Is No Single Number
You will find impressive connection counts in vendor marketing and conference talks. They are usually real, but they are measured under specific conditions: idle clients, no TLS or with session resumption, tiny or no payloads, generous hardware and carefully tuned kernels. Change any of those and the number moves.
What matters for you is not the maximum a broker can reach in a lab, but how many of your clients, with your keepalive, TLS, subscription and message patterns, a given deployment can serve with headroom. That requires understanding the bottlenecks.
What Limits Concurrent MQTT Connections
| Resource | Why each connection uses it | What makes it worse |
|---|---|---|
| Memory | Socket buffers, TLS state, session object, subscriptions, in-flight messages | Large buffers, many subscriptions per client, queued QoS 1/2 messages |
| File descriptors | Every TCP socket is an open file on Unix-like systems | Low default ulimits, extra descriptors for logs and persistence |
| CPU for TLS | Handshakes involve public-key cryptography | Reconnect storms, no session resumption, large key sizes |
| CPU for keepalives | PINGREQ and PINGRESP for every client on every interval | Very short keepalive intervals across large fleets |
| Network and kernel | Connection tables, accept queues, load balancer limits | Small accept backlog, conntrack tables, per-IP limits |
| Session state | Persistent sessions survive disconnects | Long session expiry for clients that never return |
Memory
Memory is usually the first hard limit for large fleets of quiet devices. Each connection carries kernel socket buffers, the broker's own per-client structures, TLS session state and any queued messages. Subscriptions add more, especially with many wildcard filters. Clients that disconnect with persistent sessions keep using memory until the session expires.
File descriptors
On Linux, each socket consumes a file descriptor. The default soft limit on many distributions is far too low for a broker, which is why "too many open files" is one of the most common errors when people first self-host. You can inspect and raise it:
# Current limits for the shell
ulimit -n
ulimit -Hn
# Limits of a running broker process (replace PID)
cat /proc/PID/limits | grep "open files"
# Count open sockets of the broker
ls /proc/PID/fd | wc -l
For a systemd service, raise the limit in a drop-in file:
# /etc/systemd/system/mosquitto.service.d/limits.conf
[Service]
LimitNOFILE=200000
Then run sudo systemctl daemon-reload && sudo systemctl restart mosquitto.
TLS
TLS protects every production connection, and it has a cost. The ongoing encryption of small MQTT messages is cheap, but the handshake is comparatively expensive. That matters most when many clients connect at once, for example after a site-wide power cut or a broker restart. A broker that comfortably holds its steady-state fleet can still struggle to accept all of them in the same minute. Jittered reconnect delays on clients are the best defense.
Keepalives
Each client sends a PINGREQ when it has nothing else to send within its keepalive interval. Across a large fleet, very short keepalives create a steady background load. A keepalive around 30 to 60 seconds is a common balance between fast failure detection and overhead; battery devices often use longer values.
Network path
Load balancers, NAT gateways and firewalls all keep per-connection state and have their own limits. In self-hosted setups, check the kernel accept backlog (net.core.somaxconn) and connection tracking table sizes if you place a stateful firewall in front of the broker.
How to Test Connection Capacity Yourself
If you run your own broker, measure rather than guess. The script below opens many idle connections from one machine against a broker you control, such as a local Mosquitto instance. Do not run connection tests against a shared or public broker; you will hit flood protection and affect other users.
# conn_test.py - open N idle MQTT connections to YOUR OWN test broker
import sys
import time
import paho.mqtt.client as mqtt
HOST = sys.argv[1] if len(sys.argv) > 1 else "localhost"
COUNT = int(sys.argv[2]) if len(sys.argv) > 2 else 500
connected = 0
def on_connect(client, userdata, flags, reason_code, properties):
global connected
if not reason_code.is_failure:
connected += 1
clients = []
start = time.time()
for i in range(COUNT):
c = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id=f"conn-test-{i}")
c.on_connect = on_connect
try:
c.connect(HOST, 1883, keepalive=60)
c.loop_start()
clients.append(c)
except OSError as exc:
print(f"failed at {i}: {exc}")
break
if i % 100 == 0:
time.sleep(0.5) # pace the ramp-up
time.sleep(5)
print(f"{connected}/{COUNT} connected in {time.time() - start:.1f}s")
input("Press Enter to disconnect all clients...")
for c in clients:
c.disconnect()
c.loop_stop()
Run it with python conn_test.py localhost 2000 while watching broker memory and CPU with top or htop. Note that each paho client starts its own thread, so the test machine itself becomes the bottleneck at some point; dedicated load tools that use event loops scale further. Raise ulimit -n on the test machine too. Repeat the test with TLS enabled and with realistic subscriptions, because idle plain-TCP numbers are the most optimistic you will ever see.
How Managed Brokers Set Connection Limits
Managed providers face the same constraints, but they turn them into plan quotas so you do not have to tune kernels. On a shared cluster, the quota also protects every tenant from every other tenant.
ConnectMQ publishes these connection limits by plan:
| Plan | Connection limit | Other key limits |
|---|---|---|
| Public test broker | Fair-use, per-client limits | 64 KB messages, 10 msg/s, 10 subscriptions per client |
| Serverless (Free) | Up to 25 | QoS up to 1, 256 KB messages |
| Serverless (Paid) | Up to 1,000 | QoS 2, 1 MB messages, shared subscriptions |
| Dedicated | Sized for your workload on an isolated cluster | Discussed with the team |
| BYOC | Sized for your workload in your own cloud account | Discussed with the team |
| Self Managed Enterprise | You operate and size it | Discussed with the team |
For Dedicated and BYOC, the right number depends on the factors in this article: your keepalive, TLS usage, message rate and session behavior. Share those details when you scope the deployment instead of asking for a single headline figure. If you go over a quota, MQTT 5 clients receive reason code 0x97 quota exceeded; our guide to MQTT broker connection quotas explains how to handle it.
Counting Connections Correctly
Teams frequently undercount. Use this checklist when estimating:
- Every device or gateway with its own MQTT session.
- Every backend service instance: database writers, alerting, APIs.
- Every integration tool such as Node-RED, Telegraf or Home Assistant.
- Every dashboard or browser tab running an MQTT client over WebSocket.
- Developer tools: desktop explorers, CLI sessions, test scripts.
- Temporary overlap during deployments, when old and new service instances run together.
- Growth headroom for the next six to twelve months.
Gateways change the math. An industrial gateway that aggregates fifty PLC tags or a BLE gateway that forwards dozens of sensors uses one MQTT connection, not fifty. If you are close to a plan limit, aggregating at the edge is often cheaper than upgrading.
Practical Takeaways
- Connection capacity is a function of memory, file descriptors, TLS cost, keepalive traffic and session state, not a fixed number.
- Steady-state capacity and reconnect-storm capacity are different; design clients with jittered backoff.
- Test your own workload on hardware you control, with TLS on.
- On a managed service, plan quotas are the number that matters, and you should count every client, not just devices.
For throughput rather than connections, read estimating MQTT messages per second, and for growth strategies see how to scale an MQTT broker. The cloud MQTT broker guide puts it all in the context of hosting choices.
Get Started with ConnectMQ
ConnectMQ is a fully managed MQTT service with clear connection limits per plan, so you can plan capacity without tuning servers. Create a free Serverless broker at app.connectmq.com, no credit card required, and move to paid Serverless, Dedicated or BYOC as your fleet grows.
Frequently Asked Questions
How many connections can an MQTT broker handle on a single server?
It depends on memory, file descriptor limits, TLS usage, keepalive intervals and session state. Measure with your own client behavior and TLS enabled rather than relying on a headline number.
Does TLS reduce the number of MQTT connections a broker can handle?
TLS adds memory per connection and makes handshakes CPU-intensive, which matters most during reconnect storms. Steady-state encrypted traffic for small messages is comparatively cheap.
Do idle MQTT clients still use broker resources?
Yes. An idle client still holds a socket, memory for its session and subscriptions, and sends keepalive pings, so quiet fleets consume capacity too.
How many connections does the ConnectMQ free plan allow?
The Serverless (Free) plan allows up to 25 concurrent connections, and the paid Serverless plan allows up to 1,000. Dedicated and BYOC deployments are sized for your workload.



