Releases: yoch/mqttium
Release list
MQTTium 1.1.0
MQTTium 1.1.0 fixes connection stalls and silent message-loss cases found while integrating 1.0.0 into a production listener, and adds the state and error information needed to operate the client in a service.
Main changes
- Reconnection now distinguishes a pending retry from a final disconnect, retries the initial connection when configured, and handles terminal broker refusals explicitly.
- Durable sessions resume correctly after process restart. Unacknowledged QoS 1 publications are resent when a broker session is lost, while already acknowledged inbound messages survive reconnect and disconnect boundaries.
- Keepalive detects half-open connections during steady publishing and no longer reports application backpressure as a PINGRESP timeout.
- MQTT 3.1.1 uses safe inbound defaults and a default outbound QoS 1/2 window of 20, preventing brokers from silently dropping bursts beyond their own inflight window.
- Connection, subscription, and publish failures expose typed errors and broker reason data.
- Shared-subscription routing, iterator ownership, topic aliases, WebSocket interoperability, and IPv4/IPv6 connection racing have been corrected.
- Client statistics now expose connection age, the last disconnect cause, callback failures, and unrouted messages.
Compatibility
This release keeps the client API and SQLite schema 5, but several corrections intentionally change Stable behavior. In particular, refused subscriptions now raise SubscribeError, concurrent messages() iterators are rejected, connection failures are wrapped in ConnectError, and DISCONNECTED now means that no automatic reconnect is pending.
Review the 1.1 migration notes before upgrading a service with custom reconnect, subscription, or exception handling.
Install
python -m pip install "mqttium==1.1.0"See the full changelog and release qualification report.
MQTTium 1.0.0
MQTTium 1.0.0 is the first stable release of the dependency-free, async-native MQTT client for Python 3.11–3.14.
Native MQTT for asyncio
- MQTT 3.1.1 and MQTT 5, QoS 0/1/2, typed properties, Wills and enhanced authentication.
- TCP, TLS, WebSocket and Unix-domain transports.
- Explicit publish receipts, progressive batches, independent message/byte limits, and wait-or-refuse backpressure.
- Async message iteration with optional manual acknowledgement, or short synchronous callbacks.
- Session recovery with in-memory or SQLite-backed inflight state.
Upgrading
The client implementation, API and SQLite schema are unchanged from 1.0.0rc17. RC17 applications need no API or database migration for this release. Earlier candidates contain incompatible API and persistence changes: read the migration guide before upgrading.
The Stable API follows SemVer and the documented deprecation policy. Statistics and the two supplied inflight stores remain Provisional; internal engine and extension interfaces have no compatibility guarantee.
This release also corrects migration documentation, examples and benchmark measurement. Historical audit and performance evidence remains available with its original scope and limitations.
Performance qualification
The current benchmark does not establish non-regression in the unbounded-overload cells at 4 KiB and 26,000 messages/s. Even identical-code controls exceed their confidence budget. No runtime regression is established by those invalid measurements; the overload comparison remains unqualified. See the publication checkpoint for the exact evidence and release disposition.
Install
python -m pip install mqttium==1.0.0MQTTium 1.0.0rc17
MQTTium 1.0.0rc17 is a pre-release (Beta) of the native API. It revises the RC16 public API before 1.0: contracts with no effect, no use or a duplicate are removed, internal-state leaks are closed, and four protocol bugs are fixed.
python -m pip install mqttium==1.0.0rc17Read the changes since 1.0.0rc16 before upgrading.
Highlights
- Pre-1.0 public surface: dead and duplicate contracts removed,
PublishReceiptand result types no longer expose internal state, the Will takes aPublishMessage, store protocol methods are Internal, statistics use one naming scheme, and invalid arguments raise builtin errors. - Fix sealed packet identifiers being freed with subscription identifiers, a sealed row left behind by a failed cleanup delete, a resumed QoS 1 PUBACK sent before the broker's resend, and stored inbound QoS 1 rows not counting as local Session State.
- Simpler runtime: send-quota slots owned by packet identifier, inbound Receive Maximum derived from its owners, named teardown steps.
- Every TLA+ model is now a refinement model; TLC checks 58 configurations in CI.
- Faster reception (about +14 to +19 % on the ARM64 engine paths) and less CPU per awaited
publish().
Qualification and known issue
RC17 evidence report: CI and ARM64 CI, Linux/macOS soak, EMQX/HiveMQ interoperability, strict ARM64 network and open-loop gates, and paired regression checks against RC16 passed. The full changelog lists individual changes.
Issue #493, event-loop lag at 64-byte saturation versus RC14, remains open for 1.0. RC17 showed no further lag regression against RC16. Multi-hour fuzz/soak campaigns and migration validation remain required for the final 1.0 release.
MQTTium 1.0.0rc16
MQTTium 1.0.0rc16 is a pre-release (Beta) of the native API. It preserves the RC15 public API and resolves the 39 findings of the RC15 formal runtime audit.
python -m pip install mqttium==1.0.0rc16Highlights
- Fix inbound QoS 1/2 durability and acknowledgement ordering so a persisted exchange completes only after its message reaches the application.
- Fix outbound QoS 2 replay, send-quota ownership, receipt failure handling, and packet identifier retention across reconnects.
- Preserve the valid prefix of an ingress lot before a malformed or protocol-violating packet, and keep observed acknowledgements from being lost behind blocked writes.
- Fix reconnect progress while
on_disconnectruns and retry promptly when a replacement connection fails withinstable_after. - Add pinned TLA+ checking for released-behaviour counterexamples and repaired configurations, with deterministic regression tests.
Qualification and known issue
RC16 evidence report: CI and ARM64 CI, Linux/macOS soak, EMQX/HiveMQ interoperability, strict ARM64 network and open-loop gates, and paired writer regression checks passed. The full changelog lists individual fixes.
Issue #493, event-loop lag at 64-byte saturation versus RC14, remains open for 1.0. RC16 showed no further lag regression against RC15; it does not resolve the RC14 gap. Multi-hour fuzz/soak campaigns and migration validation remain required for the final 1.0 release.
MQTTium 1.0.0rc15
MQTTium 1.0.0rc15 is a pre-release (Beta). It is the first published candidate of the pre-v1 native API, which deliberately revises 1.0.0rc14.
python -m pip install mqttium==1.0.0rc15Upgrading from 1.0.0rc14? Read the migration guide first. It covers message delivery, publication completion (receipts), the frozen constructor and statistics vocabulary, synchronous message callbacks, removed Paho/one-shot helpers, and the new SQLite schema. Historical databases are not upgraded automatically.
Highlights
- Native API: one asyncio-native
AsyncClient. Publication completes through receipts, message callbacks are synchronous, iterators handle asynchronous processing, and the constructor and statistics vocabulary is frozen. - Correctness and robustness fixes from a series of audits, notably:
- subscription acknowledgement ownership and identifier reuse;
- cancellation of requests;
- one connection deadline per attempt;
- finite timing validation;
- replay byte budgets that include MQTT 5 properties;
- WebSocket receive limits aligned with the MQTT packet limit;
- bounded stream shutdown;
- permanent reconnect failures;
- SQLite commit/rollback failure handling;
- private SQLite files (
0600/0700).
- Blockers closed before this cut (external audit, 2026-09-23): one-shot topic iterables under writer pressure (#490), SQLite batch rollback failure leaving a reusable transaction (#491), and a misleading local release manifest (#492).
The complete list is in the changelog.
Known issue
- On the dedicated ARM64 runner, publisher event-loop lag (p95) is about 15–20 % higher than 1.0.0rc14 at saturation with 64-byte payloads (about +0.1–0.15 ms near 26,000 messages/s). Throughput is unchanged, and nothing is measurable below ~22,000 messages/s. It is accepted for this candidate as part of the lean-native rewrite's trade-offs and tracked in #493, together with making that measurement reliable.
Evidence
RC15 evidence report: CI, ARM64 CI, Linux/macOS soaks and EMQX/HiveMQ interoperability on the release candidate. Multi-hour fuzz/soak campaigns and migration validation remain required before a final 1.0.
MQTTium 1.0.0rc14
What's Changed
- perf: avoid shield overhead for PublishReceipt waiters by @yoch in #432
- perf: simplify callback dispatch and inline sync pairs by @yoch in #433
- mission: prune persistence contract by @yoch in #434
- perf: remove redundant effect-drain shield by @yoch in #440
- mission: drop executable MQTT 3.1 support by @yoch in #435
- mission: make PROTOCOL_ERROR effects strict by @yoch in #437
- mission: remove obsolete internal test seams by @yoch in #436
- mission: investigate removing message_delivery="both" by @yoch in #438
- refactor: fail fast on unusable MQTT 5 peer packet limit by @yoch in #439
- docs: MQTTium-only hot-path performance reconnaissance by @yoch in #431
- ci: add a neutral ARM64 receive-candidate comparison by @yoch in #449
- ci: fix feed benchmark parent import in ARM64 comparison by @yoch in #450
- ci: add a neutral ARM64 receive layout-stability diagnostic by @yoch in #451
- fix: harden decoder ingress allocations and receive contracts by @yoch in #452
- perf: receive directly into the decoder's storage by @yoch in #448
- fix: preserve inline callback routing and reconnect delivery by @yoch in #454
- chore: prepare v1.0.0rc14 by @yoch in #459
Full Changelog: v1.0.0rc13...v1.0.0rc14
MQTTium 1.0.0rc13
Release candidate 1.0.0rc13.
Correctness
- Local store/persistence failures during ingress now propagate with their original exception instead of a peer-attributed
PROTOCOL_ERROR; observed terminal broker outcomes still settle, and a local-terminal failure fail-stops the client (no automatic reconnect or replay, explicitconnect()refused).
Performance / internal
- Restored the ordinary QoS 0 publication hot path (generic carrier overhead removed).
- Reduced QoS 1/2 publication preparation overhead (plain tuple carrier).
- Explicit success-ACK provenance carried into the writer; ordinary admission no longer reclassifies ACK bytes.
- No Stable API or ordering/backpressure semantics changed; no material performance regression observed vs rc12.
Compatibility
- MQTT 3.1 is explicitly out of the support matrix (Stable enum member retained); only MQTT 3.1.1 and MQTT 5 are supported and tested.
Evidence
- Python 3.11–3.14, cross-platform (Linux/macOS/Windows), ARM64, fuzz, resilience, soak and broker interoperability (Mosquitto 3.1.1+5, EMQX 5.8.9, HiveMQ 2026.5) gates green.
- Full evidence: https://github.com/yoch/mqttium/blob/v1.0.0rc13/docs/reports/RELEASE-CANDIDATE-1.0.0rc13.md
MQTTium 1.0.0rc12
MQTTium 1.0.0rc12 improves the native QoS 1 publication and callback-response path without changing the Stable API.
Highlights:
- reuse one validated QoS 1/2 publication preparation across resident-writer preflight and protocol admission;
- preserve SEND ordering when a synchronous
on_messagecallback publishes reentrantly; - give protocol ACKs and application data separate one-shot eager permits, preserving per-turn fairness while removing the common response writer hop; and
- align the trusted ARM64 workflows with the runner's Python 3.14 environment.
On the dedicated ARM64 runner, the selected policy reduced callback-response ACK p50 by 49.51% and increased callback-response throughput by 14.23%, while QoS 0 and QoS 1 capacity remained within 1.47% and 0.15% of the baseline respectively. Same-code controls and all decision-cell variability checks passed.
The complete hosted Python 3.11–3.14, Linux, macOS, Windows, fuzz, resilience, soak, package, installed-artifact and post-merge ARM64 checks passed. See the RC12 evidence report for scope, provenance and limitations.
MQTTium 1.0.0rc11
What's Changed
- Optimize idle callback dispatch by @yoch in #402
- Synthesize native topic callback routing by @yoch in #405
- Add topic-filtered message callbacks on AsyncClient by @yoch in #403
- Correct MQTT 5 Receive Maximum PUBREC documentation by @yoch in #411
- Validate MQTT 5 outbound payload format indicators by @yoch in #412
- Preserve fatal protocol error classifications by @yoch in #413
- Align CONNECT properties with effective inbound limits by @yoch in #414
- Retain assigned ClientID for durable session resume by @yoch in #415
- Prepare MQTTium 1.0.0rc11 by @yoch in #416
Full Changelog: v1.0.0rc10...v1.0.0rc11
MQTTium 1.0.0rc10
What's Changed
- Consolidate MQTT 5 AUTH, Topic Alias, and replay ownership by @yoch in #378
- Add generative AsyncClient runtime concurrency fuzzing by @yoch in #379
- Install qualified V1 runtime fuzz nightly by @yoch in #380
- Add two-window runtime fuzz composition by @yoch in #381
- Fix PUBREL replay under exhausted Receive Maximum by @yoch in #391
- Use effective CONNECT Topic Alias Maximum on ingress by @yoch in #392
- Reject server DISCONNECT before MQTT 5 by @yoch in #393
- Preserve durable outbound ownership on delete failure by @yoch in #396
- Send MQTT 5 Protocol Error DISCONNECT for empty PUBLISH topic by @yoch in #395
- test(fuzz): enforce outbound wire multiplicity obligations by @yoch in #390
- test(fuzz): assert terminal publish waiter accounting by @yoch in #397
- Engine structural simplification: dedup runtime plumbing, fix replay-parked settlement resurrection by @yoch in #398
- Runtime fuzzer V3: pressure/interleaving profile and parked-publisher qualification by @yoch in #399
- test(fuzz): make shared-runner deadlines explicit by @yoch in #400
- chore: prepare 1.0.0rc10 by @yoch in #401
Full Changelog: v1.0.0rc9...v1.0.0rc10