Library / SDK
knolleary/pubsubclient avatar
knolleary/pubsubclient

PubSubClient: the Arduino MQTT client its author no longer maintains

A client library for the Arduino Ethernet Shield that provides support for MQTT.

4,015 stars1,503 forksC++MIT

At a glance

What is it?
PubSubClient brought MQTT publish/subscribe to Arduino boards through the Ethernet Client API. The README now says the library is not maintained and points users to alternatives, so the decision is less about features than about whether you can accept a frozen codebase.
Who is it for?
PubSubClient still works for small, QoS 0 telemetry on Ethernet, ESP8266 and ESP32 boards, and the examples folder gives you a starting sketch for each. It is the wrong pick for anything that needs maintenance, larger payloads or guaranteed delivery, because the README states the library is not maintained, publishes only at QoS 0, and defaults to a 256-byte packet limit.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 112 days ago.
What is it written in?
Mainly C++, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 25, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The problem PubSubClient solves on a microcontroller

A microcontroller has no operating system to lean on. There is no MQTT daemon to install, no TLS stack to borrow, and often only a few kilobytes of RAM. PubSubClient exists to close that gap: it implements the client half of MQTT on top of the Arduino Ethernet Client API, so any board that can open a TCP socket through that interface can publish and subscribe to a broker. The README describes it as a client for doing simple publish/subscribe messaging with a server that supports MQTT.

The audience is narrow and specific. It is for people writing Arduino sketches for an Ethernet shield, an Arduino YUN, a WiFi shield, a CC3000, an Intel Galileo or Edison, an ESP8266 or an ESP32. The library does not manage WiFi credentials, DHCP or TLS. It expects the sketch to have already established a working network connection and to hand it a Client object. If your project runs on Linux and can link a full MQTT library, PubSubClient is solving a problem you do not have.

How PubSubClient moves bytes between a sketch and a broker

The design is deliberately thin. A PubSubClient object wraps a reference to an Arduino Client, and the sketch calls connect, publish, subscribe and loop. The loop call is where incoming traffic is processed: the library reads from the socket, parses MQTT control packets, and invokes a callback function that the sketch registered. There is no background thread and no internal queue, so if the sketch blocks for a long time, the client is not reading.

That single-threaded model explains several of the documented limits. The keepalive interval defaults to 15 seconds, configurable through MQTT_KEEPALIVE in PubSubClient.h or through setKeepAlive. The packet buffer defaults to 256 bytes including the header, configurable through MQTT_MAX_PACKET_SIZE or setBufferSize. The protocol version defaults to MQTT 3.1.1 and can be switched to 3.1 via MQTT_VERSION. Each of these is a compile-time or runtime knob on the same small state machine, and each one trades RAM against capability.

One design detail worth noticing is the WiFi Shield note in the README: sending packets larger than 90 bytes with that shield requires enabling the MQTT_MAX_TRANSFER_SIZE define. The library does not detect the shield and adjust itself. The user is expected to know the hardware constraint and set the define.

Installing PubSubClient and a first real use

The library is distributed through the Arduino ecosystem. The README points to the bundled examples under File > Examples > PubSubClient inside the Arduino application, and the repository ships a library.properties and a library.json, which is what the Arduino IDE and PlatformIO read to identify a library. The examples directory contains sketches named mqtt_basic, mqtt_auth, mqtt_esp8266, mqtt_large_message, mqtt_publish_in_callback, mqtt_reconnect_nonblocking and mqtt_stream. The mqtt_basic sketch is the shortest path to a working publish.

The README gives no sketch source of its own, so the honest starting point is to open the bundled example rather than copy a snippet from a blog post. In the Arduino application the path is File > Examples > PubSubClient, and the README names mqtt_basic as one of the sketches there. The repository layout confirms the same examples are checked in under examples/, alongside src/, keywords.txt, library.json, library.properties and tests/.

What the README does document is the configuration surface you will meet inside that sketch and the header. The defaults are stated directly: MQTT_MAX_PACKET_SIZE controls the 256-byte message limit, MQTT_KEEPALIVE controls the 15-second keepalive, and MQTT_VERSION selects MQTT 3.1.1 or 3.1. The same three can be changed at runtime with PubSubClient::setBufferSize(size), PubSubClient::setKeepAlive(keepAlive) and the version define. For the Arduino YUN the README says to use the included YunClient in place of EthernetClient and to do a Bridge.begin() first.

For a board that needs authentication, the mqtt_auth example shows the connect call carrying credentials. For a board that needs to survive broker restarts, mqtt_reconnect_nonblocking shows a reconnect loop that does not stall the sketch, which matters precisely because loop() is the only place incoming packets are processed. The README does not document what a failed publish returns, so test that on your own hardware before relying on it.

Where the 256-byte buffer and QoS 0 publishing bite

The README is unusually candid about limitations, and two of them decide real projects. First, the client can only publish QoS 0 messages, though it can subscribe at QoS 0 or QoS 1. QoS 0 means fire and forget: the library hands the packet to the socket and does not wait for a PUBACK. On a wired Ethernet link this is usually fine. On a WiFi link with a marginal signal, a dropped packet is simply gone, and the sketch has no way to know. If your application is a command that must arrive, PubSubClient's publish path is the wrong tool; you would need application-level acknowledgement on top of it.

Second, the maximum message size including header is 256 bytes by default. That is not a large payload. A JSON sensor reading with a timestamp and a device identifier can approach it quickly, and the mqtt_large_message example exists because raising the limit is a common need. Raising it costs RAM, and on a board with very little of that, the buffer competes with everything else in the sketch. The README does not describe what happens to an oversized publish beyond the existence of the limit, so treat the boundary as something to test on your own hardware rather than assume.

The hardware exclusion is equally concrete: the library cannot currently be used with hardware based on the ENC28J60 chip, such as the Nanode or the Nuelectronics Ethernet Shield. The README names NanodeMQTT as an alternative for those boards. No amount of configuration fixes this one, because the constraint is in the network stack the library sits on.

PubSubClient versus ArduinoMqttClient and the maintained alternatives

The most direct comparison is with ArduinoMqttClient, the MQTT client published by Arduino itself. Both are C++ libraries that speak MQTT over an Arduino Client, so the sketch-level shape is similar. The difference is ownership and direction: ArduinoMqttClient is part of the Arduino ecosystem's own library set, while PubSubClient is a single-author project whose README now opens with a caution that the library is not maintained and urges users to pick an actively maintained alternative.

That is the real distinction for a new project. PubSubClient has years of accumulated example sketches covering Ethernet, ESP8266, ESP32, authentication, large messages and non-blocking reconnect, and those examples still compile against the documented API. ArduinoMqttClient does not carry the same example inventory in this repository, because it is a different repository. Choosing between them is choosing between a frozen but well-documented API and a library whose future is decided by someone else's release schedule.

There is also the ENC28J60 case, where neither of the above is the answer and the README itself points to NanodeMQTT. That is a useful reminder that the MQTT client is the top layer of a stack, and the bottom layer sometimes makes the decision for you.

Maintenance status, licence and what upgrading actually costs

The maintenance question is settled by the README, not by inference. It states plainly that the library is not maintained, that the author no longer has the local setup to develop and test it, and that alternative libraries exist. The last push to the repository was on 2026-06-10, but the release history tells a longer story: v2.8 dates from 2020-05-20, v2.7 from 2018-11-02 and v2.6 from 2016-02-02. A repository can receive commits without a tagged release, and the gap between the newest release and the present is the number that matters when you are pinning a version in a dependency file.

The practical upgrade cost is low in one sense and high in another. Low, because the API surface is small and the header-level configuration defines are stable across the 2.x line, so a sketch written against v2.8 is unlikely to break. High, because there is no one to fix a bug you find, no one to add MQTT 5, and no one to respond to a change in broker behaviour. The tests directory exists in the repository, but the README does not document how to run it, so you cannot assume a working test suite is available to validate a patch you write yourself.

The licence is MIT, stated in the README and shipped as LICENSE.txt. MIT is permissive: it allows use, modification and redistribution with the copyright notice and permission notice retained. Nothing in the licence obliges the author to maintain the code, and nothing in it prevents you from forking. If your organisation needs a maintained fork, MIT gives you the legal room to make one; it does not give you anyone to make it. This is a description of the licence text, not legal advice, and anyone embedding the library in a product should read LICENSE.txt directly.

Editorial conclusion

PubSubClient still works for small, QoS 0 telemetry on Ethernet, ESP8266 and ESP32 boards, and the examples folder gives you a starting sketch for each. It is the wrong pick for anything that needs maintenance, larger payloads or guaranteed delivery, because the README states the library is not maintained, publishes only at QoS 0, and defaults to a 256-byte packet limit. Before writing new code, check the README's own recommendation of an actively maintained alternative and confirm your board is not ENC28J60-based, which the README excludes.

Frequently asked questions

How do I install PubSubClient in the Arduino IDE?

The README directs users to the bundled examples under File > Examples > PubSubClient within the Arduino application, and the repository ships library.properties and library.json so the Arduino IDE and PlatformIO can identify the library. The README does not spell out a manual installation procedure beyond that.

What is PubSubClient.h?

It is the header for the library, and it is also where several compile-time defaults live. The README states that MQTT_MAX_PACKET_SIZE, MQTT_KEEPALIVE and MQTT_VERSION can all be changed in PubSubClient.h, and that the WiFi Shield needs MQTT_MAX_TRANSFER_SIZE enabled there for packets over 90 bytes.

What is a good PubSubClient alternative?

The README itself says alternative libraries exist and urges users to pick one that is actively maintained, without naming a specific replacement. For ENC28J60-based hardware such as the Nanode or the Nuelectronics Ethernet Shield, the README points to NanodeMQTT.

How does PubSubClient compare with ArduinoMqttClient?

Both are C++ MQTT clients that sit on top of an Arduino Client, but ArduinoMqttClient is published by Arduino as part of its own library set while PubSubClient is a single-author project whose README now declares it unmaintained. The README does not name ArduinoMqttClient specifically; it only says actively maintained alternatives exist.

Official sources

  1. knolleary/pubsubclient on GitHub
  2. License: MIT
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/knolleary-pubsubclient.svg)](https://hysenlabs.com/projects/knolleary-pubsubclient)