MQTT Fundamentals

MQTT Topic Alias: Saving Bandwidth on Long Topic Names

MQTT 5 topic aliases replace long topic names with a two-byte number after the first publish. Learn how the negotiation works, how many bytes you actually save and how to use aliases safely from MQTT.js.

Diagram showing a long topic name replaced by a short number to illustrate the mqtt topic alias feature
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

An MQTT topic alias lets a client send a long topic name once and then refer to it with a two-byte integer for the rest of the connection. On constrained links such as cellular, LoRa backhaul or satellite, that can cut the size of small telemetry packets by more than half. This guide explains how the Topic Alias Maximum is negotiated, how to calculate your savings and how to use aliases correctly from code.

What an MQTT Topic Alias Is

Topic aliases are one of the MQTT 5 features that target efficiency. In MQTT 3.1.1 every PUBLISH packet carries the full topic name as a UTF-8 string with a two-byte length prefix. Well-structured topic trees, such as ISA-95 style paths, are descriptive but long. A path like connectmq/factory1/production/line1/cnc1/telemetry is 50 characters, and if your payload is a 20-byte number with a timestamp, the topic is more than twice the size of the data.

With MQTT 5, the sender can attach a Topic Alias property (identifier 0x23, a two-byte integer) to a PUBLISH. The first time it does so, the packet contains both the full topic name and the alias, and the receiver records the mapping. Subsequent PUBLISH packets can carry a zero-length topic name plus the alias, and the receiver substitutes the stored topic.

Three rules define the feature:

  1. Aliases are per connection and per direction. The client-to-broker mapping and broker-to-client mapping are independent. Aliases are not part of the session state and are forgotten on disconnect, even if the session persists.
  2. Each side sets a ceiling. The receiver announces how many aliases it will accept with the Topic Alias Maximum property (0x22). A value of 0, or no property at all, means aliases are not accepted in that direction.
  3. Mappings can be replaced. Sending a PUBLISH with an existing alias number and a non-empty topic name rebinds that alias to the new topic.

How Topic Alias Maximum Negotiation Works

Negotiation happens in the CONNECT and CONNACK packets:

Packet Property Meaning
CONNECT (client to broker) Topic Alias Maximum Highest alias the broker may use when sending PUBLISH to this client
CONNACK (broker to client) Topic Alias Maximum Highest alias the client may use when sending PUBLISH to the broker
PUBLISH (either direction) Topic Alias The alias number, from 1 up to the receiver's maximum

So if the broker's CONNACK says 10, your client may use aliases 1 to 10 on outgoing publishes. If your CONNECT says 0 or omits the property, the broker will always send full topic names to you. Alias 0 is never valid.

If a sender breaks these limits, for example by using alias 11 when the maximum is 10, or by sending an empty topic name with an alias that was never defined, the receiver closes the connection with reason code 0x94 Topic Alias invalid. The MQTT reason codes reference lists this code alongside the others you are likely to meet while debugging.

Calculating the Bandwidth Savings

You do not need a lab to estimate the savings; the packet layout is fixed. Take a QoS 0 publish in MQTT 5 with the 50-character topic above and a 20-byte payload:

Field Full topic First publish with alias Later publishes with alias
Fixed header (type + remaining length) 2 2 2
Topic name (2-byte length + string) 52 52 2
Properties length 1 1 1
Topic Alias property (id + value) 0 3 3
Payload 20 20 20
Total MQTT bytes 75 78 28

After the first message, each publish is 47 bytes smaller, a reduction of about 63 percent at the MQTT layer. The first publish costs 3 extra bytes, which is repaid immediately on the second message.

Keep the bigger picture in mind. TCP and IP headers add roughly 40 bytes per segment, and TLS adds record overhead on top. On a link where you send one message per minute, those transport costs and keep alive traffic dominate, and topic aliases barely move the bill. On a link sending many small messages per second, or batching several messages into one TCP segment, the topic name is a large share of every byte and aliases pay off. The MQTT bandwidth usage guide walks through the full per-message calculation including TLS.

You can verify the numbers with Wireshark: capture on port 1883, apply the mqtt display filter, and compare the Topic Length and Msg Len fields of the first and second PUBLISH from your client.

Using Topic Aliases with MQTT.js

MQTT.js supports aliases both manually and automatically. Here is the manual approach against the public broker, which makes the mechanics visible:

const mqtt = require("mqtt");

const TOPIC = "connectmq/demo/9c1e/factory1/production/line1/cnc1/telemetry";

const client = mqtt.connect("mqtts://broker.connectmq.com:8883", {
  clientId: "alias-demo-9c1e",
  protocolVersion: 5,
  properties: {
    topicAliasMaximum: 10, // we accept up to 10 aliases from the broker
  },
});

client.on("connect", (connack) => {
  const brokerMax = connack.properties?.topicAliasMaximum ?? 0;
  console.log("Broker accepts topic aliases up to:", brokerMax);

  if (brokerMax < 1) {
    console.log("Aliases not available, publishing with full topic names");
  }

  let count = 0;
  const timer = setInterval(() => {
    const payload = JSON.stringify({ t: Date.now(), rpm: 1200 + count });

    if (brokerMax < 1) {
      client.publish(TOPIC, payload);
    } else if (count === 0) {
      // First publish: full topic name + alias establishes the mapping
      client.publish(TOPIC, payload, { properties: { topicAlias: 1 } });
    } else {
      // Later publishes: empty topic name, alias only
      client.publish("", payload, { properties: { topicAlias: 1 } });
    }

    if (++count === 5) {
      clearInterval(timer);
      client.end();
    }
  }, 1000);
});

client.on("error", (err) => console.error("MQTT error:", err.message));

Subscribe from another terminal to confirm the broker resolved the alias and delivers the full topic to subscribers:

mosquitto_sub -h broker.connectmq.com -p 1883 -i alias-watch-9c1e \
  -t "connectmq/demo/9c1e/#" -v -V mqttv5

Automatic Alias Assignment

For real applications, let the library manage the mapping:

const client = mqtt.connect("mqtts://broker.connectmq.com:8883", {
  clientId: "alias-auto-9c1e",
  protocolVersion: 5,
  autoAssignTopicAlias: true, // assign aliases to new topics automatically
  autoUseTopicAlias: true,    // reuse an existing alias when the topic repeats
});

With these options, MQTT.js tracks which topics already have aliases, stays within the broker's announced maximum and falls back to full topic names when it runs out. You keep publishing with normal topic strings in your code.

Pitfalls and Best Practices

Topic aliases are simple, but a few mistakes cause most of the trouble:

  • Reusing aliases after reconnect. Mappings vanish when the TCP connection closes. Code that remembers "alias 1 is my telemetry topic" across reconnects will send an undefined alias and be disconnected with 0x94. Always re-send the full topic first on every new connection.
  • Ignoring the CONNACK value. Never hard-code a maximum. Read it from CONNACK each time, because it can differ between brokers, plans and versions.
  • Aliasing rarely used topics. Aliases help topics you publish often. Spending an alias slot on a topic you publish once a day gains nothing.
  • Intermediaries that rewrite packets. An empty topic name only makes sense together with its alias property. Gateways or protocol translators that drop MQTT 5 properties can break this, so test the full network path.
  • Expecting savings on QoS-heavy flows. QoS 1 and 2 add acknowledgement packets that aliases do not shrink.

A quick checklist before enabling aliases on a fleet:

  1. Confirm the client library supports MQTT 5 and topic aliases.
  2. Log the broker's Topic Alias Maximum at connect time.
  3. Reset alias tables in your reconnect handler.
  4. Capture a few packets to verify the expected byte savings.
  5. Watch for 0x94 disconnects in logs after rollout.

Topic Aliases on ConnectMQ

ConnectMQ supports MQTT 5.0 on every endpoint, including topic aliases, together with session expiry, message expiry and shared subscriptions. That means you can keep descriptive, ISA-95 style topic names for readability and still send compact packets from constrained devices. The MQTT tutorial is a good starting point if you are still designing your topic structure, and the topic naming conventions guide helps keep those names consistent.

Try Topic Aliases on ConnectMQ

Experiment on the free public MQTT broker first, then move to a private fully managed MQTT service with TLS and your own credentials when you are ready for real devices. Sign up at app.connectmq.com to create a free Serverless broker without a credit card, or read the guide to choosing a cloud MQTT broker first.

Frequently Asked Questions

Is the MQTT topic alias available in MQTT 3.1.1?

No. Topic aliases were introduced in MQTT 5.0 and are carried as a PUBLISH property, which does not exist in 3.1.1. Both the client and the broker must use MQTT 5.

Do topic aliases survive a reconnect?

No. Aliases belong to the network connection, not the session. After any reconnect the sender must publish the full topic name again before using the alias.

What does reason code 0x94 mean?

It means Topic Alias invalid: the sender used an alias of 0, above the receiver's Topic Alias Maximum, or with an empty topic name before the mapping was defined. Fix the alias handling and reconnect.

Do subscribers see the alias or the full topic?

Subscribers see the full topic. The broker resolves the alias on the incoming side, and any alias on the outgoing side is negotiated separately with each subscriber.

Related articles

Why Your MQTT Client Keeps Disconnecting (and How to Fix It)

Reconnect loops are one of the most common MQTT problems. Learn the five usual causes, from duplicate client IDs to keep alive timeouts and oversized packets, and follow a diagnosis flow that pinpoints yours.

8 min read

Who Invented MQTT? The History from Oil Pipelines to IoT

MQTT was invented in 1999 by Andy Stanford-Clark of IBM and Arlen Nipper of Arcom to monitor oil pipelines over satellite. Follow its path to open source, OASIS, ISO and today's managed cloud brokers.

7 min read

MQTT Maximum Message Size: Limits and Large Payload Strategies

MQTT can technically carry a 256 MB packet, but brokers, client libraries and devices impose far lower limits. Learn where the real limits are, what happens when you exceed them, and how to send large payloads.

7 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.