The MQTT message size limit in the specification is about 256 MB per packet, but the limit that actually matters is the one set by your broker, your client library and your device's memory, which is usually far lower. This guide explains each of those limits, what happens when a message is too big, and three strategies for moving large payloads such as images, logs or firmware without breaking your MQTT connections.
The Protocol Ceiling: 256 MB
MQTT encodes the length of each packet's variable header and payload in a "remaining length" field of up to four bytes, seven usable bits each. The largest value that fits is 268,435,455 bytes, roughly 256 MB. Subtract the topic name and headers, and that is the theoretical maximum payload. The encoding is explained byte by byte in the guide to MQTT packet structure.
Nobody runs production systems near that ceiling. A broker that accepted 256 MB messages from any client would be easy to exhaust: it has to buffer the packet, possibly store it for offline sessions or as a retained value, and copy it to every subscriber. MQTT was designed for many small messages, and every layer of a real deployment reflects that.
Where the Real Limits Are
| Layer | Typical limit | What sets it |
|---|---|---|
| MQTT specification | 268,435,455 bytes per packet | Remaining length encoding |
| Broker | Configured maximum message or packet size | Broker configuration or plan |
| MQTT 5 negotiation | Maximum Packet Size property | Client and broker each announce what they accept |
| Client library | Internal buffer size | Library defaults, e.g. 256 bytes in Arduino PubSubClient |
| Device | Free RAM | A microcontroller may have only tens of KB available |
| Network | Throughput and stability | Large messages take longer and fail more often on weak links |
The smallest limit in the chain wins. A broker that accepts 1 MB is irrelevant if an ESP8266 subscriber can only buffer a few kilobytes. If you work with Arduino-class hardware, the PubSubClient buffer size guide covers that particular trap.
MQTT Message Size Limits on ConnectMQ
These are the current limits per broker type:
| Broker | Maximum message size |
|---|---|
| Public test broker (broker.connectmq.com) | 64 KB |
| Serverless (Free) plan | 256 KB |
| Serverless (Paid) plan | 1 MB |
| Dedicated, BYOC and Self Managed Enterprise | Depends on the deployment |
For most telemetry, alarms and commands, even 64 KB is generous: a JSON sensor reading is typically well under 1 KB. If you regularly approach these limits, that is usually a sign the payload belongs somewhere else, as described below.
MQTT 5 Maximum Packet Size
MQTT 5 made size limits explicit with the Maximum Packet Size property (0x27):
- In CONNECT, the client tells the broker the largest packet it is willing to receive. The broker must not send anything bigger; it discards such messages for that client instead.
- In CONNACK, the broker tells the client the largest packet it accepts. A client that sends more breaks the protocol.
Note that this is the size of the whole packet, including the fixed header, topic and properties, not just the payload. Leave some headroom.
Reading the broker's limit in MQTT.js:
const mqtt = require("mqtt");
const client = mqtt.connect("mqtts://broker.connectmq.com:8883", {
clientId: "size-check-8b4d",
protocolVersion: 5,
properties: { maximumPacketSize: 64 * 1024 }, // what this client accepts
});
client.on("connect", (connack) => {
const max = connack.properties?.maximumPacketSize;
console.log("Broker maximum packet size:", max ?? "not announced");
client.end();
});
If the property is absent, the broker did not announce a limit in CONNACK, but it may still enforce one. Always know your broker's documented limit.
What Happens When a Message Is Too Large
Behaviour depends on the protocol version and the direction:
- Client to broker, MQTT 5. The broker typically disconnects the client with reason code
0x95 Packet too large. - Client to broker, MQTT 3.1.1. There is no reason code; the broker closes the connection. The client sees a generic connection loss.
- Broker to client. If a subscriber announced a smaller Maximum Packet Size, the broker drops the message for that subscriber. In 3.1.1, the subscriber's library may fail to parse it or disconnect.
- Inside the client. Some libraries refuse to send and return an error; Arduino PubSubClient simply returns
falsefrompublish().
The dangerous pattern is a client that queues the oversized message, reconnects, and immediately retries it. The result is a disconnect loop, one of the classic reasons an MQTT client keeps disconnecting. Validate the size before publishing and drop or reroute messages that are too big.
Strategies for Large Payloads
1. Make the Payload Smaller
Before splitting anything, shrink it. Field names in JSON are repeated in every message; short keys, binary encodings such as CBOR or Protobuf, and gzip compression often reduce payloads dramatically. Sending only changed values rather than full state also helps. The guide to MQTT payload format compares the options.
2. Chunk the Message
When a payload is moderately large, for example a few hundred kilobytes of log data, you can split it into numbered chunks and reassemble on the receiving side. This Python publisher splits a file into 32 KB chunks with a small JSON header per chunk:
import base64, hashlib, json, math, time, uuid
import paho.mqtt.client as mqtt
CHUNK = 32 * 1024
TOPIC = "connectmq/demo/8b4d/files"
def send_file(client, path):
data = open(path, "rb").read()
transfer_id = uuid.uuid4().hex[:8]
total = math.ceil(len(data) / CHUNK)
sha = hashlib.sha256(data).hexdigest()
for i in range(total):
part = data[i * CHUNK:(i + 1) * CHUNK]
msg = {"id": transfer_id, "seq": i, "total": total, "sha256": sha,
"data": base64.b64encode(part).decode()}
client.publish(f"{TOPIC}/{transfer_id}", json.dumps(msg), qos=1).wait_for_publish()
time.sleep(0.15) # respect per-client rate limits
client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id="chunker-8b4d")
client.connect("broker.connectmq.com", 1883, keepalive=60)
client.loop_start()
send_file(client, "report.csv")
client.loop_stop()
client.disconnect()
Base64 adds about a third to the size, so 32 KB of binary becomes roughly 43 KB on the wire, comfortably under the public broker's 64 KB limit. The subscriber collects chunks by id, orders them by seq, and verifies the SHA-256 once all total parts arrive. Use QoS 1 so chunks are not silently lost, and design for duplicates and missing parts with a timeout. On the public broker, keep the 10 messages per second limit in mind, which is what the sleep handles.
Chunking adds complexity, so reserve it for payloads that are too large for one message but small enough that MQTT remains the right transport.
3. Send the File Out of Band
For images, video, firmware images and large exports, the most robust pattern is to keep the bytes off MQTT entirely. Upload the file to object storage or a web server over HTTPS, then publish a small MQTT message that points to it:
{
"type": "firmware",
"version": "2.4.1",
"url": "https://files.example.com/fw/sensor-2.4.1.bin",
"sha256": "9f2c...e81a",
"size": 1048576
}
Devices fetch the file with HTTP range requests and resume support, verify the hash, and report progress back over MQTT. You keep MQTT's strengths, instant notification and fan-out to many devices, while HTTP and storage services handle bulk transfer.
A Size Decision Checklist
- Under 10 KB: send as one message, no special handling.
- 10 KB to your broker's limit: compress or use a compact encoding, and confirm every subscriber can buffer it.
- Above the limit but only occasionally: chunk with sequence numbers and checksums.
- Large binary files or regular bulk transfers: upload out of band and publish a reference.
- In every case: check the size in code before calling publish.
Send Messages on ConnectMQ
ConnectMQ gives you clear, plan-based limits, from 256 KB messages on the free Serverless plan to 1 MB on the paid Serverless plan, with Dedicated, BYOC and Self Managed Enterprise options for larger deployments. Experiment on the free public MQTT broker first, then move to a fully managed MQTT service when you need private credentials and higher limits. The MQTT tutorial covers the fundamentals if you are just getting started.
Get Started with ConnectMQ
Create a free Serverless broker at app.connectmq.com, no credit card required, and get a username, password and client ID in minutes. To compare hosting options, read our guide to choosing a cloud MQTT broker.
Frequently Asked Questions
What is the maximum MQTT message size?
The protocol allows packets up to 268,435,455 bytes, about 256 MB. In practice brokers set much lower limits; on ConnectMQ it is 64 KB on the public broker, 256 KB on the free plan and 1 MB on the paid Serverless plan.
What happens if I publish a message that is too large?
The broker rejects it, usually by closing the connection. MQTT 5 clients receive reason code 0x95 Packet too large, while MQTT 3.1.1 clients just see the connection drop.
Should I send files over MQTT?
Small files can be sent directly or in chunks. For large files, upload them over HTTPS to storage and publish a small MQTT message containing the URL and checksum.
Does the size limit include the topic name?
Broker limits are often expressed per message or per packet, and MQTT 5 Maximum Packet Size counts the whole packet, including topic and properties. Leave headroom above your payload size.



