Message History
Message History lets you save selected fields from MQTT messages to EMQX Tables. Create a mapping to choose an MQTT topic filter, a target table, and the fields to store.
EMQX Tables stores and queries data, but it does not automatically receive messages from an EMQX Broker deployment. Without Message History, you must manually configure a data integration connector, rule, and action. Message History sets up and manages this ingestion pipeline through a three-step mapping workflow.
With Message History, you can:
- Set up MQTT data storage without manually building a data integration pipeline.
- Preview recent records and check delivery metrics from the Broker deployment.
- Retain telemetry in EMQX Tables for SQL queries and trend analysis.
- Enable, disable, or delete individual mappings without deleting data already stored in EMQX Tables.
Message History is available only on the international site for Dedicated and Dedicated Flex deployments running EMQX v6.1.4 or later.
How Message History Works
The mapping wizard has three steps:
- Storage Location: Select an EMQX Tables deployment in the same network as the Broker and a database. Select a Tables user and enter its password. Then set a retention period (TTL) and timestamp column name.
- Message & Table Schema: Enter an MQTT topic filter and target table, map message values to tag or field columns, and choose the timestamp source and precision.
- Confirmation: Review the storage location, topic, and table schema, then create the mapping.
After you select the storage location, Message History creates or reuses a connection to EMQX Tables. When you confirm the mapping, it creates a data integration rule and an EMQX Tables action. The rule selects values from messages that match the topic filter, and the action writes those values to the target table.
If the target table does not exist, the first successful write creates it with the selected TTL and timestamp column name. These settings do not change an existing table. Values in the first successful write determine the column types, so later messages must use compatible types. The message example only previews the schema; it does not create the table or write a record.
Only messages received while a mapping is enabled are stored. Message History does not backfill earlier MQTT traffic or replay stored messages to subscribers. For client connection and subscription events, use Event History instead.
Each matching message consumes data integration TPS. Check your deployment's data integration TPS capacity before creating a mapping.
Before You Start
- Make sure that the Broker deployment is running.
- Prepare a running EMQX Tables deployment in the same network as the Broker. Tables deployments reached through a NAT Gateway or PrivateLink from another network are not eligible.
- Prepare an EMQX Tables database and a user that has access to it. The user must have the
SqlSelectandSqlInsertprivileges; the Broker Integration preset grants both. Have the user's password ready. See Manage EMQX Tables Users.
Example: Store Sensor Readings
In this example, devices publish temperature and humidity readings to topics such as sensors/sensor-001/telemetry. The mapping stores readings from all sensors in the sensor_history table in the public database. It uses the Broker received time for the timestamp column, so the payload does not need a timestamp.
Create the Mapping
In the Cloud Console, open the Broker deployment and select Message History in the left menu. Click Map a Topic to a Table if this is the first mapping, or New Mapping if mappings already exist.
Under Storage Location, select the EMQX Tables deployment, the
publicdatabase, and the Tables user. Enter the user's password. Leave Time-To-Live (TTL) at30 daysand the timestamp column name attimestamp. Click Next to create or reuse the connection.
Under Message & Table Schema, enter
sensors/+/telemetryfor MQTT Topic andsensor_historyfor Table Name. The+wildcard matches one topic level, so this filter includes readings from different sensor IDs.Replace the MQTT Message Example with this payload:
json{ "device_id": "sensor-001", "temperature": 23.5, "humidity": 58.5 }In Field Mapping, set
payload.device_idto the Tag role. Keeppayload.temperatureandpayload.humidityas Field columns. Leave their target column names asdevice_id,temperature, andhumidity.TIP
After the first successful write, the table has a timestamp column named
timestamp, adevice_idtag for filtering by device, andtemperatureandhumidityfields for the readings. At least one Field column is required, and target column names must be unique.Keep Timestamp Column set to Broker Received Time and Time Precision set to Milliseconds (ms). Click Next.

Review the destination, topic, and schema preview, then click Confirm. The mapping appears in the Message History list.

Publish and Query a Message
In the Broker deployment, open Diagnostics -> MQTT Client, connect, and publish the example payload to
sensors/sensor-001/telemetry.Return to Message History and expand the mapping row to preview recent records. Click the mapping ID to open its details and check the delivery metrics.
Open Data Explorer in the linked EMQX Tables deployment, select the
publicdatabase, and run:sqlSELECT * FROM sensor_history ORDER BY "timestamp" DESC LIMIT 10;
The query should return a row for sensor-001 with the published temperature and humidity. See Data Explorer for more query options.

Configure Other Message Formats
- Topic filters: Use MQTT
+and#wildcards to capture multiple topics. A mapping stores only messages received while it is enabled; it does not copy earlier messages. - Message examples: The Console detects fields and nested paths in a JSON object. A plain-text payload produces one
payloadfield. Arrays are not supported. The example defines the columns; it does not sample messages received by the Broker. - Additional fields: Use Add Field to map MQTT metadata such as
clientid,topic,qos,username, orpeername. Choose Tag for values you expect to filter or group by, and Field for measured values. Keep at least one Field column. - Message time: To store when a device produced a reading, add a Unix timestamp or a date-time string such as
2026-09-23T08:00:00Zto the example payload, then select that field under Timestamp Column. For a Unix timestamp, set Time Precision to match its unit. The Console converts a recognized RFC 3339 string to the selected precision. Otherwise, use Broker Received Time. - Existing connections: If a Message History connection already uses the selected Tables deployment, database, and user, the Console reuses it. Its TTL and timestamp column name are read-only in the wizard. Those settings affect only tables first created through that connection; check the settings of any existing target table separately.
Troubleshoot Setup and Writes
- If clicking Next does not create a connection, make sure that the Tables deployment is running in the same network as the Broker. Also check the Tables credentials and database access. Message History connections share the Broker's connector limit with Data Integration connectors.
- If no records appear, make sure that the mapping is enabled and that the published topic matches its MQTT topic filter. Messages published before the mapping was created are not copied into the table.
- Open the mapping details and check the Success, Failed, and Dropped metrics. A write can fail if the Tables deployment is unavailable, database access is insufficient, the timestamp is invalid, or a value does not match the table's column type.
- If the mapping was created for an existing table, inspect that table's timestamp column, TTL, and schema in EMQX Tables. The mapping's connection settings do not change an existing table.
View and Manage Mappings
The Message History list shows each mapping's ID, MQTT topic, database, table, and enabled state.
- Expand a mapping row to preview up to 10 recent records.
- Click the mapping ID to view its destination, TTL, delivery metrics, and up to 100 recent records.
- Refresh the preview to load the latest records.
- Use Data Explorer for broader queries.
Message History queries EMQX Tables for each preview and orders the results by the timestamp column.

Mappings cannot be edited after creation. You can enable, disable, or delete them:
- Use the switch in the Enable column to disable or enable a mapping. Disabling a mapping stops new writes but keeps data already stored in EMQX Tables.
- To delete a mapping, click its delete icon and enter the mapping ID in the confirmation dialog. Deleting a mapping does not delete the target table or stored data. If no other mapping uses its dedicated connection, that connection is also removed.