Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

MQTTium logo

MQTTium

A dependable, dependency-free asyncio MQTT client for Python.

PyPI Python versions CI Coverage Documentation Apache-2.0 license

MQTTium is an async-native MQTT 3.1.1 and MQTT 5 client for Python 3.11–3.14. It is designed for services, gateways, and connected devices that need explicit completion semantics, bounded resource use, and predictable recovery when a connection or process fails.

The package has no runtime dependencies and is fully typed.

The current pre-v1 native API deliberately differs from 1.0.0rc14, including message delivery, publication completion, configuration names, and the SQLite format. If you are upgrading an existing application or database, read the migration guide first.

Why MQTTium?

Need MQTTium provides
Protocol coverage MQTT 3.1.1 and MQTT 5, QoS 0/1/2, typed properties, Last Will, and enhanced authentication
Explicit completion Publish receipts that separate local admission from the relevant MQTT acknowledgement exchange
Controlled load Independent message and byte budgets, wait-or-refuse backpressure, bounded ingress, writes, and application delivery
Session continuity Jittered reconnect plus in-memory or SQLite-backed inflight state with incremental replay
Delivery choices Async iteration with optional manual acknowledgement, or synchronous auto-ack callbacks
Transports TCP, TLS, WebSocket, and Unix-domain sockets
Operations Immutable runtime snapshots, queue high-water marks, and broker-negotiated limits
Efficient native path Progressive publish_many(), loop-bound publish_nowait(), and hot paths measured under the same semantics

MQTTium keeps protocol state in a synchronous state machine and leaves sockets, timers, callbacks, and task ownership to the asyncio adapter. That separation makes QoS transitions and rollback independently testable while keeping the native client free of background threads.

Install

The native API below is published as the pre-release 1.0.0rc17:

python -m pip install mqttium==1.0.0rc17

To try unreleased changes, install a checkout instead and record the Git commit when reporting a source-build issue:

git clone https://github.com/yoch/mqttium.git
cd mqttium
python -m pip install .

1.0.0rc17 revises the 1.0.0rc16 API before 1.0; see the changes since 1.0.0rc16. Applications still on 1.0.0rc14 should use its RC14 documentation and read the migration guide before upgrading.

First round trip

This example subscribes, publishes at QoS 1, waits for PUBACK, and consumes the message:

import asyncio

from mqttium.api import AsyncClient


async def main() -> None:
    client = AsyncClient("example-client")
    try:
        await client.connect("127.0.0.1", 1883)
        await client.subscribe("devices/+/status", qos=1)

        receipt = await client.publish(
            "devices/demo/status",
            b"online",
            qos=1,
        )
        await receipt.wait()

        async for message in client.messages():
            print(message.topic, message.payload)
            break
    finally:
        await client.disconnect()


asyncio.run(main())

await client.publish(...) waits until the publication is admitted and its bounded effect transfer is complete; it does not wait for the MQTT exchange to finish. The returned receipt observes that later completion. QoS 0 completes on writer handoff because MQTT defines no acknowledgement, QoS 1 on PUBACK, and QoS 2 on PUBCOMP.

Choose the delivery model deliberately

Iterator delivery is the default and the asynchronous processing path. It is also the only mode that supports manual_ack=True:

client = AsyncClient(manual_ack=True)

async for message in client.messages():
    await process(message)
    await client.ack(message)

For synchronous notification, construct the client with message_delivery="callback" and register on_message or topic-specific callbacks before the first connection attempt. Message callbacks are synchronous by contract and run inline on the delivering reader, outside protocol locks. They retain no MQTTium callback queue, so callback execution time is natural receive-side backpressure. Use messages() instead when handling needs to await, may take significant time, or needs manual acknowledgement.

Message routes are frozen after the first connection attempt. Create a new client when a later connection needs a different routing table.

Backpressure is part of the API

publish() waits for capacity by default. Applications with a defined shed, retry, or spill policy can request immediate refusal instead:

from mqttium import FlowControlError
from mqttium.api import AsyncClient

client = AsyncClient()

try:
    receipt = client.publish_nowait("telemetry", payload, qos=1)
except FlowControlError:
    await shed_or_retry(payload)

Outbound protocol state, encoded writes, inbound protocol state, and iterator delivery have independent bounds because they have different lifetimes. Passing None disables an optional bound and should be a deliberate capacity decision.

For a sustained producer, publish_many() walks its input progressively instead of materialising chunks or creating one task per publication. Admissions remain ordered and the returned aggregate receipt tracks the committed prefix:

from mqttium.api import PublishMessage

batch = await client.publish_many(
    PublishMessage("telemetry", sample, qos=1) for sample in samples
)
await batch.wait()

If iteration or admission fails after earlier elements committed, PublishBatchError exposes the aggregate receipt for that committed prefix; MQTTium does not roll it back.

Performance

Performance is a design constraint, not a separate fast mode. MQTTium measures the native asyncio path together with MQTT semantics, bounded resource use, backpressure, and event-loop fairness rather than relaxing those contracts for a benchmark configuration.

The separate mqtt-python-client-bench project carries cross-client campaigns with exact source revisions, environment fingerprints, scenario semantics, validity labels, and raw evidence. MQTTium only treats cross-client points as comparable when the completion contract matches; unsupported capabilities remain N/A rather than being approximated with a different operation. gmqtt is the closest established asyncio peer for many native scenarios, while Eclipse Paho is retained as a widely known synchronous reference rather than presented as a direct asyncio peer.

For MQTTium-to-MQTTium regression work, the benchmarking contract requires exact source identity and controlled paired measurements. Small suspected regressions are checked with same-code controls and interleaved A/B runs before they justify runtime complexity. Absolute throughput still depends on the machine, broker, workload, and completion semantics.

Reconnect and durable sessions

Automatic reconnect is opt-in through ReconnectPolicy. Durable recovery also requires a durable broker session; storing client-side inflight state alone is not sufficient.

from mqttium import MQTTProtocolVersion
from mqttium.api import AsyncClient, Properties, ReconnectPolicy
from mqttium.persistence import SqliteInflightStore

store = SqliteInflightStore("mqtt-session.sqlite")
client = AsyncClient(
    "gateway",
    protocol=MQTTProtocolVersion.MQTTv5,
    clean_start=False,
    connect_properties=Properties({"session_expiry_interval": 86_400}),
    reconnect=ReconnectPolicy(max_retries=None),
    store=store,
)

SqliteInflightStore persists unfinished outbound QoS 1/2 exchanges, inbound QoS 1 still awaiting a manual ack(), inbound QoS 2 protocol state, and the accounting metadata needed to replay them. It does not persist arbitrary application work, already-acknowledged messages, or subscription intent. The application owns the store and must close it after the client has shut down.

Migration from 1.0.0rc14

The current native API is the only supported client surface. The migration guide covers removed compatibility interfaces and helpers, the frozen constructor and statistics vocabulary, progressive batch publication, synchronous message callbacks, receipt-based publication completion, and the new SQLite schema. Historical databases are not upgraded automatically.

Use the Read the Docs version matching your installed release: v1.0.0rc17 for this API, v1.0.0rc16, v1.0.0rc15 or v1.0.0rc14 for earlier candidates, and latest for the current source. The legacy stable URL redirects to the latest published candidate until a final release provides Read the Docs' automatic stable version.

Documentation

The current source documentation is available on Read the Docs latest. For a released package, select its version instead.

Start here Use it for
Getting started Installation, lifecycle, publishing, subscribing, and delivery
Configuration and sizing Choosing queue, byte, inflight, timeout, and reconnect settings
Sessions and persistence Broker sessions, reconnect, SQLite, and restart recovery
Transports and security TCP, TLS, WebSocket, Unix sockets, and credential handling
MQTT 5 Properties, authentication, topic aliases, and negotiated limits
Operations Runtime snapshots, pressure diagnosis, and graceful shutdown
Benchmarking Performance methodology, regression controls, and measurement semantics
Native API reference Supported imports, signatures, defaults, and exceptions
Compatibility matrix Python, platform, broker, protocol, and transport validation

Architecture, conformance, stability tiers, benchmarking methodology, and release evidence are documented separately so current contracts are not mixed with historical reports.

Support and contributing

  • Read the support policy before requesting usage help.
  • Use the structured issue form for reproducible bugs.
  • Report vulnerabilities privately as described in the security policy.
  • See the contribution guide for development and validation commands.

MQTTium is original software licensed under Apache-2.0. Paho and gmqtt are referenced only for migration, interoperability, and cross-client comparison.

Metadata

Release files for mqttium 1.0.0rc17

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for mqttium 1.0.0rc17
File Size Uploaded
mqttium-1.0.0rc17.tar.gz 150.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for mqttium 1.0.0rc17
File Interpreter ABI Platform
mqttium-1.0.0rc17-py3-none-any.whl Python 3 none any Details

Total release size: 333.8 kB

Release files / mqttium-1.0.0rc17.tar.gz

Download URL mqttium-1.0.0rc17.tar.gz
Size 150.9 kB
Tags Source
SHA-256 checksum
How to use checksums
fca7df82bafc6ed0b19e148c51a29af5b92ae8cdf79e9c54d651f02de3ca298a
BLAKE2b-256 checksum
How to use checksums
ac2dd95c70cf3dc92b0b64eceb10a39a579b673938333f43ac2f929e72556b8c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 27, 2026.

Transparency log

Release files / mqttium-1.0.0rc17-py3-none-any.whl

Download URL mqttium-1.0.0rc17-py3-none-any.whl
Size 183.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
8da1cbf61a1564c9b72d1d4e7e5ff19b7e630586b6c0c82960d39d33f8d0bc53
BLAKE2b-256 checksum
How to use checksums
c648a4bcf7379542c738bf603aaf04f5f32cccd2e066683d2c1d1c16b4fbb507
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 27, 2026.

Transparency log
Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page