BunkerM now records every MQTT message that passes through your broker into a local SQLite database. No setup, no external service, no data leaving your network. Open Logs, Message History, and everything is there: searchable, filterable, and replayable.
MQTT is fire-and-forget by design. Once a message is delivered, it is gone. That is exactly what you want in production, until something goes wrong.
A temperature sensor sent a bad reading at 3 AM and triggered a downstream alert. A device published an unexpected payload that caused a consumer to crash. A new firmware update changed the payload format and you need to know what the old format looked like to write a migration. In all of these cases, you need to look at what was actually published, after the fact.
The usual answer is to add a subscriber that logs everything to a file or a database. That means another service to deploy, another thing to maintain, another failure point. For a self-hosted setup where simplicity is the whole point, this is a poor trade-off.
Message History is a passive recorder built directly into BunkerM. A background service subscribes to # and writes every incoming message to a SQLite database at /var/lib/history/history.db inside the container. It starts automatically. There is nothing to configure.
Each record stores the full topic, the payload (text or base64 for binary), QoS level, retain flag, payload size, and a millisecond-precision timestamp. Internal $SYS/ broker diagnostics are excluded.
By default, BunkerM keeps up to 50,000 messages and 7 days of history. When either limit is crossed, the oldest entries are pruned automatically. Both limits are adjustable via environment variables if your setup needs more headroom.
The Message History page lives under Logs in the sidebar. At the top, four stat cards give you a quick read: total messages stored, number of unique topics, database size on disk, and the current retention window.
Below that, a topic dropdown (populated from everything the broker has seen) and a free-text search box let you narrow the table. The search matches both topic paths and payload content. Results are paginated at 100 per page, newest-first.
Every row has a replay button. Click it to open a dialog pre-filled with the original topic and payload. You can edit the payload, adjust QoS and the retain flag, then publish. The replayed message goes straight to the broker and gets recorded as a new entry.
A pressure sensor on a production line is sending inconsistent readings. The anomaly detector flagged it, but the alert only tells you the deviation score, not what was actually published. Pull up Message History, filter by the sensor topic, and scroll back to the flagged timestamp. The raw payload is right there. You can see whether it was a bad value, a missing field, or a unit change in the firmware.
You are building a new consumer service that needs to handle a specific sequence of MQTT messages from your production sensors. Instead of waiting for the right conditions to occur naturally, capture a representative set of messages in history, then replay them against your new service in a controlled environment.
Something toggled a light switch at 2 AM. The automation rule that did it may have triggered on a payload from another device. Message History lets you reconstruct the exact sequence: filter by the relevant topics around that timestamp and trace back what was published before the switch fired.
A device just pushed a firmware update that changed its JSON structure. You need to update the consumer that reads from that topic, but the new firmware is already deployed and you no longer have access to a device running the old version. The old payloads are in Message History. Use them as the reference while writing the migration.
By default, the SQLite file lives inside the container and is lost when the container is removed. Mount a named Docker volume to keep history across restarts:
docker run -d \
-p 1900:1900 -p 2000:2000 \
-v history_data:/var/lib/history \
bunkeriot/bunkerm:latest
The official docker-compose.yml already includes this volume. If you are using Compose, no changes are needed.
Message History ships in the latest BunkerM image. Pull and restart your container:
docker pull bunkeriot/bunkerm:latest
docker compose up -d The history service starts automatically. Go to Logs, Message History and it will be there.
Full documentation is at bunkerai.dev/docs/message-history. Source is at https://github.com/bunkeriot/BunkerM.