Kafka integration
TBMQ Kafka Integration enables communication with Apache Kafka, allowing TBMQ to publish messages to external Kafka clusters. This is useful for the following scenarios:
- Streaming IoT Data — forwarding device telemetry, logs, or events to Kafka for processing and storage.
- Event-Driven Architectures — publishing messages to Kafka topics for real-time analytics and monitoring.
- Decoupled System Communication — using Kafka as a buffer between TBMQ and downstream applications.
Data flow
Section titled “Data flow”- Device (client) publishes an MQTT message to a topic matching the integration’s topic filters.
- TBMQ broker receives the message and forwards it to the TBMQ Integration Executor.
- Integration Executor processes the message and sends it to a configured Kafka topic.
- Kafka consumers process the message in downstream systems.
Prerequisites
Section titled “Prerequisites”- A running TBMQ instance, version 2.1 or later, with the TBMQ Integration Executor service running. Without a reachable executor, saving an integration fails with a validation timeout.
- An external Kafka cluster ready to receive messages (e.g., Confluent Cloud).
- A client capable of publishing MQTT messages (e.g., TBMQ WebSocket Client).
Create TBMQ Kafka Integration
Section titled “Create TBMQ Kafka Integration”- Go to the Integrations page and click the “+” button.
- Select Kafka as the integration type and click Next.
- On the Filters and events step, keep the default Topic filters entry
tbmq/#, leave Lifecycle events empty, and click Next. - In the Configuration step, enter the Bootstrap servers (Kafka broker addresses). See below for common and Confluent Cloud configurations. Leave Topic at its default
tbmq.messages— that is the topic this tutorial reads from at the end. - Click Add to save the integration.
Kafka bootstrap servers configuration
Section titled “Kafka bootstrap servers configuration”Specify the bootstrap server address of your own Kafka cluster (e.g., localhost:9092 for a broker you run locally — not TBMQ’s internal Kafka, which uses the same address in the default deployments). The screenshot below shows the basic configuration for establishing a connection between TBMQ and a Kafka broker.
Step 1: In Confluent, open your environment → Cluster → Cluster settings. Find the Bootstrap server URL (format: URL_OF_YOUR_BOOTSTRAP_SERVER:9092) and copy it to the integration.
Step 2: Add the following Other properties key-value pairs for SASL/SSL authentication:
| Key | Value |
|---|---|
ssl.endpoint.identification.algorithm |
https |
sasl.mechanism |
PLAIN |
sasl.jaas.config |
org.apache.kafka.common.security.plain.PlainLoginModule required username="CLUSTER_API_KEY" password="CLUSTER_API_SECRET"; |
security.protocol |
SASL_SSL |
Replace CLUSTER_API_KEY and CLUSTER_API_SECRET with your Confluent cluster API key and secret.
To generate an API key, go to Data Integration → API Keys → Create key in your Confluent cluster.
Step 3: Create a Kafka topic on Confluent. Go to Topics → Create Topics and set the name to tbmq.messages.
Topic filters
Section titled “Topic filters”Topic filters define MQTT-based subscriptions that trigger the integration. When TBMQ receives a message matching a configured topic filter, the integration processes it and forwards the data to the Kafka cluster.
Topic filters are optional if you select at least one lifecycle event type instead — an integration only has to have one of the two.
For example, with the topic filter tbmq/devices/+/status, any of the following messages will trigger the integration:
tbmq/devices/device-01/statustbmq/devices/gateway-01/statusConfiguration
Section titled “Configuration”| Field | Default | Description |
|---|---|---|
| Send only message payload | off | If enabled, only the raw message payload is forwarded. If disabled, TBMQ wraps the payload in a JSON object with additional metadata. |
| Bootstrap servers | localhost:9092 |
Kafka broker addresses (comma-separated list of hostnames/IPs and ports). Required. |
| Topic | tbmq.messages |
The Kafka topic where messages will be published. Required. |
| Key | — | Optional record key. If set, Kafka hashes it so records with the same key land on the same partition. If left empty, Kafka’s sticky partitioner picks a partition and switches only when the batch is full. The integration never sets a partition explicitly. |
| Client ID prefix | tbmq-ie-kafka-producer |
Prefix for the Kafka client ID. The full ID is prefix-integrationId-executorServiceId, so each executor’s producer is distinguishable in the Kafka cluster. |
| Automatically retry times if fails | 0 |
Producer-level retries for a record whose send fails with a transient error (retries). |
| Produces batch size in bytes | 16384 |
Maximum batch size before records are sent (batch.size). |
| Time to buffer locally (ms) | 0 |
How long to wait for more records before sending a batch (linger.ms). |
| Client buffer max size in bytes | 33554432 |
Total memory for buffering records waiting to be sent (buffer.memory). |
| Number of acknowledgments | -1 |
acks — 0 (no acknowledgment), 1 (leader only), or all / -1 (all in-sync replicas, the default and safest). |
| Compression | none |
Compression algorithm: none, gzip, snappy, lz4, zstd. |
| Other properties | — | Additional Kafka producer configuration as key-value pairs — this is where SASL/SSL settings go. |
| Kafka headers | — | Custom headers added to every record. |
| Charset encoding | UTF-8 |
Charset used to encode the Kafka headers values: US-ASCII, ISO-8859-1, UTF-8, UTF-16BE, UTF-16LE, or UTF-16. |
| Metadata | — | Custom key-value pairs attached to forwarded messages, exposed as metadata in the JSON body. |
With Send only message payload enabled, the record value is the payload alone — as UTF-8 text if it is valid UTF-8, Base64-encoded otherwise.
Client lifecycle events
Section titled “Client lifecycle events”Besides the messages matched by topic filters, this integration can deliver client lifecycle events — a client connecting, disconnecting, changing its subscriptions, or failing authentication or authorization.
Pick the event types on the Filters and events step while creating the integration, or add them later:
- Open the integration on the Integrations page and click the Toggle edit mode button (pencil icon).
- Click the Lifecycle events field to list the available event types, then select the ones you need: Client connected, Client disconnected, Client subscribed, Client unsubscribed, Client authentication failed, Client authorization failed, Client connection failed. Each one is added as a chip; remove it with its x.
- Click Apply changes.
Events are published to the same Topic as messages, using the configured Key, Kafka headers, and producer settings. Send only message payload applies to message payloads only — an event is always published as its full JSON body.
Integration events
Section titled “Integration events”These are the integration’s own events, recorded inside TBMQ for debugging and troubleshooting. They are not the client lifecycle events described above: those are about MQTT clients and are published to your Kafka topic, while these describe the integration itself and never leave TBMQ.
- Lifecycle Events — logs events such as
Started,Created,Updated,Stopped. - Statistics — insights into integration performance, including processed message counts and error rates.
- Errors — captures failures related to authentication, timeouts, payload formatting, or connectivity issues.
Send an uplink message
Section titled “Send an uplink message”- Navigate to the WebSocket Client page.
- Select WebSocket Default Connection (or any working connection) and click Connect. Verify the connection status shows
Connected. - Set the Topic field to
tbmq/kafka-integrationto match the integration’s topic filtertbmq/#. - Leave the pre-filled Payload
{"temperature": 25}as is — it is what lands in the Kafka topic below. - Click the Send icon to publish the message.
If successful, the message should be available in your Kafka service under the topic tbmq.messages:
{ "payload": "eyJ0ZW1wZXJhdHVyZSI6MjV9", "topicName": "tbmq/kafka-integration", "clientId": "tbmq_df52bNUQ", "eventType": "PUBLISH_MSG", "qos": 1, "retain": false, "tbmqIeNode": "tbmq_ie_node", "tbmqNode": "tbmq_node", "ts": 1742554969254, "props": {}, "metadata": { "integrationName": "Kafka integration" }}Message field descriptions:
| Field | Description |
|---|---|
payload |
Base64-encoded content of the MQTT message (e.g., "eyJ0ZW1wZXJhdHVyZSI6MjV9" decodes to {"temperature": 25}). |
topicName |
MQTT topic to which the message was published. |
clientId |
ID of the MQTT client that published the message. |
eventType |
Type of event. PUBLISH_MSG for a forwarded message; a client lifecycle event carries its own type instead. |
qos |
Quality of Service level of the incoming message. |
retain |
Whether the message has the Retain flag set. |
tbmqIeNode |
Node ID of the Integration Executor that handled the message. |
tbmqNode |
Node ID of the TBMQ broker that received the message. |
ts |
Timestamp (milliseconds) when the message was received. |
props |
MQTT 5.0 user properties or other MQTT properties. |
metadata |
Additional metadata from integration configuration (e.g., integration name). |
Was this helpful?