Best Practices for MQTT Client Development on the EMQX Platform
Message Queuing Telemetry Transport (MQTT) is a flexible and lightweight publish-subscribe protocol widely adopted in IoT applications. However, due to its flexibility and rich feature set, improper configuration or implementation on the client side can lead to performance issues and may even impact overall system stability.
This page outlines the best practices for developing MQTT clients that connect to and communicate through the EMQX Platform. By following these guidelines, you can ensure your clients make optimal use of EMQX’s capabilities while maintaining stability, performance, and security at scale.
Topics covered include connection management, topic hierarchy design, QoS configuration, message publishing strategies, and the effective use of EMQX-specific features such as shared subscriptions, retained messages, and event-driven data integration.
Manage Connection
MQTT clients must manage connections efficiently to ensure uninterrupted data flow, handle intermittent network conditions gracefully, and minimize resource usage on both the client and broker sides.
This section covers essential practices for establishing, maintaining, and recovering client connections when interacting with the EMQX Platform.
Establish and Maintain a Stable Connection
Client ID Configuration
Each MQTT client must use a unique identifier to establish a session with the broker. Proper Client ID design helps avoid connection conflicts and simplifies client lifecycle management.
- Use unique client IDs to avoid ID conflicts.
- Consider using device serial numbers or UUIDs as unique identifiers.
- In certain scenarios, such as large-scale deployments, use structured naming conventions, such as
{product_type}-{region}-{device_id}
.
Keep Alive Interal
The Keep Alive interval defines how frequently the client must communicate with the broker to keep the connection alive. Choosing an appropriate value ensures the timely detection of disconnects without unnecessary network overhead.
- Set the Keep Alive interval based on the client’s network environment, typically within the range of 30 to 250 seconds.
- For unstable or mobile networks, use shorter intervals (e.g., 60–120 seconds) to detect connection loss quickly.
- For stable or high-reliability networks, longer intervals (e.g., 180–250 seconds) are acceptable to reduce network traffic.
- Ensure the client sends heartbeat (PINGREQ) packets before the Keep Alive interval expires to avoid broker-side disconnection.
Session Management
MQTT sessions determine whether the broker retains client state, such as subscriptions and undelivered messages. Selecting the right session type impacts message delivery reliability and resource usage.
- Enable persistent sessions (
Clean Session = False
) when message delivery continuity or subscription recovery is required. - Use temporary sessions (
Clean Session = True
) for clients that only require real-time data, helping to reduce broker resource usage.
Handle Disconnections and Recovery
Intermittent connectivity is common in real-world network environments. Implementing automatic reconnection mechanisms and exponential backoff strategies can effectively improve connection recovery success rates.
Automatic Reconnection Mechanism
Automatically reconnecting after a lost connection ensures service continuity and reduces manual intervention.
- Enable automatic reconnection to restore connectivity after unexpected disconnects.
- Implement connection status monitoring to detect and respond to disconnections promptly.
Exponential Backoff Strategy
Exponential backoff helps prevent reconnection storms, especially when multiple clients attempt to reconnect simultaneously after a network failure.
- Double the retry interval after each failed reconnection attempt to prevent connection storms.
- Set a maximum backoff interval (e.g., 120 seconds) to cap retry delays.
- Reset and retry immediately upon detecting network restoration (e.g., interface status change or signal recovery).
Manage and Optimize Topic Subscription
Topic subscriptions are a core part of MQTT communication, allowing clients to receive messages relevant to their role. However, poor subscription design, such as excessive filters or inefficient hierarchies, can lead to increased broker load, slower message routing, and unnecessary client-side processing.
This section outlines best practices for managing and optimizing topic subscriptions when connecting to the EMQX Platform.
Subscription Limits per QoS Level
Subscribing to too many topics, especially at higher Quality of Service (QoS) levels, can increase the processing overhead on both the client and broker. To maintain optimal performance, the following recommended limits apply:
QoS Level | Delivery Guarantee | Recommended Max Subscriptions |
---|---|---|
QoS 0 | At most once | 100 |
QoS 1 | At least once | 50 |
QoS 2 | Exactly once | 25 |
These values are best-practice guidelines based on common usage patterns. While not hard limits, exceeding them may lead to degraded performance, especially in resource-constrained environments.
Wildcard Topic Subscriptions
Wildcard filters allow clients to subscribe to multiple topics with a single subscription, simplifying configuration and reducing subscription count.
- Single-level wildcard (
+
): Matches one topic level only. Example:sensor/+/temperature
matches bothsensor/room1/temperature
andsensor/room2/temperature
. - Multi-level wildcard (
#
): Matches one or more levels at and below the current level. Example:sensor/#
matchessensor/room1/temperature
,sensor/room2/humidity
, andsensor/room3/status/battery
.
Best Practice:
Use wildcard subscriptions where applicable to reduce management complexity. However, avoid overly broad filters (e.g., #
at the root level) as they can result in clients receiving large volumes of irrelevant messages, increasing processing load and memory usage.
Topic Hierarchy Design
Well-structured topics make it easier to manage subscriptions, apply access control, and scale your MQTT deployment. A clear, consistent topic design improves both client and broker performance.
Best Practices for Topic Structure
Use a unified topic format Adopt a consistent topic naming scheme, such as:
{product_type}/{region}/{device_id}/{data_type}
Limit topic depth Keep topic hierarchies to five levels or fewer. Excessively deep structures increase routing complexity and may impact performance.
Avoid leading wildcards Do not use patterns like
#/+
or+/#
, as these introduce ambiguity and increase broker-side computation during topic matching.Separate message types by category Use distinct prefixes for command and data topics. For example:
cmds/device001 # Commands sent to the device data/device001 # Data published by the device
QoS Levels and Performance
The MQTT protocol supports three QoS levels that define the reliability of message delivery between clients and the broker. Choosing the appropriate QoS level directly impacts network traffic, processing load, and overall system performance.
This section provides an overview of each QoS level, performance recommendations, and optimization strategies when using EMQX.
QoS Levels Explained
Each QoS level represents a trade-off between delivery reliability and communication overhead:
QoS Level | Delivery Guarantee | Typical Use Cases |
---|---|---|
QoS 0 | At most once | Non-critical telemetry, periodic sensor data |
QoS 1 | At least once | Important data where duplicates are acceptable |
QoS 2 | Exactly once | Critical messages, such as commands or transactions |
Higher QoS levels provide more reliable delivery but incur additional protocol overhead and processing latency.
Client-Side Performance Guidelines
Message throughput for MQTT clients is influenced by the selected QoS level, internal scheduling logic, and device performance. The following throughput ranges are recommended per client:
QoS Level | Recommended Max Messages/sec (per client) |
---|---|
QoS 0 | 1,000 |
QoS 1 | 300 |
QoS 2 | 150 |
These values are general recommendations based on typical MQTT client behavior. Actual limits depend on hardware, implementation efficiency, and message size.
Avoid excessive subscription counts or message bursts, as these can lead to increased client-side scheduling delays and reduced processing efficiency.
Optimization Strategies
To balance reliability and performance, consider the following best practices:
- Prefer lower QoS levels whenever business requirements allow. For example, use QoS 0 for streaming telemetry data.
- Use shared subscriptions to distribute message load across multiple backend consumers.
- Implement batch publishing to reduce per-message overhead and resource consumption.
- Apply message compression for large payloads to improve transmission efficiency over constrained networks.
Message Publishing Strategy
Efficient message publishing helps reduce bandwidth usage, lower processing overhead, and improve end-to-end delivery performance. This section outlines recommended practices for controlling message size, frequency, structure, and content when publishing to the EMQX broker.
Publishing Best Practices
Properly managing how and when messages are published helps reduce system load and improves throughput across clients and brokers.
Control Message Size
Large or inefficient messages can slow down delivery and increase memory usage on both client and broker.
- Keep individual messages below 128 KB where possible.
- For large payloads, consider chunked transmission or external references (e.g., file URLs).
- Avoid sending high volumes of very small messages. Batch messages when appropriate.
Manage Publishing Frequency
Controlling how often data is published helps balance system responsiveness with resource efficiency.
- Avoid publishing at excessively high frequencies, which can exhaust client or broker resources.
- Use change-triggered publishing, where messages are sent only when data changes.
- Implement throttling or aggregation mechanisms to reduce publish frequency and smooth data flow.
Prioritize Message Importance
Assigning the correct priority and QoS level ensures critical data is reliably delivered while minimizing overhead for less important data.
- Use higher QoS levels for critical data, such as commands or alerts, to ensure delivery.
- Use lower QoS levels or batch publishing for non-critical telemetry or frequent updates.
Message Format and Payload Optimization
Designing message payloads efficiently improves processing speed, reduces bandwidth usage, and simplifies downstream parsing and analysis.
Use Standardized Message Formats
Consistent formatting makes it easier to integrate with backend systems, debug issues, and maintain schemas over time.
- Use standardized formats like JSON or Protocol Buffers.
- Define clear message structures that include necessary metadata.
- Consider including timestamps, device IDs, and message types.
Optimize Payload Content
Smaller, well-structured payloads transmit faster and reduce the risk of congestion, especially in constrained networks.
- Remove unnecessary or redundant fields.
- Use short and meaningful field names.
- Consider compression algorithms to reduce data size
- For repetitive or frequently changing data, consider using incremental update mechanisms to send only what has changed.
Shared Subscriptions
Shared subscriptions are an MQTT 5.0 feature that allows multiple clients to subscribe to the same topic while sharing the message load. This enables built-in load balancing and failover, making it ideal for scaling backend services and ensuring high availability.
The EMQX Platform fully supports shared subscriptions, allowing clients to consume data collaboratively under a shared group identifier.
Syntax and Format
The shared subscription format follows the MQTT 5.0 standard:
$share/{group_id}/{topic_filter}
group_id
: Shared subscription group identifier for distinguishing different groupstopic_filter
: The topic filter pattern, same as used in standard subscriptions
Example
Three clients sharing a subscription to the sensor/data
topic using the shared group group1
:
$share/group1/sensor/data
Benefits of Shared Subscriptions
Shared subscriptions are a powerful tool for increasing scalability and resilience in MQTT client architectures:
Load balancing
Messages are evenly distributed among clients in the same group, preventing any single client from becoming a bottleneck.
Automatic failover
If a client disconnects, EMQX reroutes undelivered messages to other available clients in the group, ensuring service continuity and reliability.
High availability
Ideal for high-concurrency or large-scale device access scenarios where backend systems must remain responsive and fault-tolerant.
Shared Subscription Limitations
While shared subscriptions offer significant advantages, they are not suitable for all workloads:
- Performance degradation Increasing the number of clients in a shared group can impact message distribution efficiency.
- Not suitable for very high throughput When handling more than 5,000 messages per second, it is recommended to bridge data to external messaging systems such as Kafka via EMQX's Data Integration feature.
- Best suited for medium workloads Shared subscriptions work best when scaling horizontally in moderate-volume environments. For ultra-high throughput, use dedicated messaging pipelines.
Common Use Cases
Shared subscriptions are especially effective in the following scenarios:
- Backend service scaling: Multiple service instances jointly process device data from a common topic.
- Load balancing: Distribute incoming MQTT traffic across multiple clients.
- High availability architecture: Implement service redundancy and failover.
Retained Messages
Retained messages are a feature of the MQTT protocol that allows the broker to store the last published message on a topic and automatically send it to any client that later subscribes to that topic. This ensures that new subscribers can immediately receive the most recent status or configuration data without waiting for the next publish.
The EMQX broker fully supports retained messages and provides additional controls such as message expiry.
When to Use Retained Messages
Retained messages are useful in scenarios where clients need access to the latest known value as soon as they subscribe.
Common use cases include:
- Device initialization Provide devices with the most recent state or configuration when they come online.
- Broadcast announcements Share global announcement messages (e.g., system notifications).
- Monitoring and diagnostics Publish health or diagnostic data that should be available to subscribers at any time.
- Configuration distribution Store and distribute device configuration settings, ensuring clients always receive the latest version.
How to Publish and Clear Retained Messages
To use retained messages in MQTT, simply set the retain
flag to true
when publishing. To remove a retained message, publish an empty payload to the same topic with the retain
flag enabled.
# Set a retained message
publish(topic="sensor/status", message="Device online", retain=True)
# Clear a retained message
publish(topic="sensor/status", message="", retain=True)
Best Practices for Retained Messages
To ensure retained messages are used effectively and safely in production, consider the following recommendations:
Use sparingly: Retained messages consume broker memory. Avoid excessive use, especially for dynamic or frequently updated data.
Set message expiration: When supported, define an expiry interval to prevent outdated information from being delivered to new subscribers.
Keep payloads small: Retained messages are best suited for concise data such as flags, status updates, or config hashes, not for large payloads or files.
Avoid wildcard subscriptions for retained topics: When a client subscribes using a wildcard topic (e.g.,
sensor/#
), the broker delivers all matching retained messages, which may cause a performance spike. Use specific topic filters when subscribing to retained message topics.
Last Will and Testament (LWT)
Last Will and Testament (LWT) is a standard MQTT feature used to detect and signal unexpected client disconnections. When a client disconnects ungracefully (e.g., due to power failure or network loss), the broker automatically publishes a predefined LWT message to a specified topic. This allows other systems to react to the disconnection in real time.
The EMQX Platform supports LWT and provides full control over its topic, payload, QoS, and retention settings.
Common Use Cases
LWT is a valuable mechanism for detecting client-side failures and initiating system responses:
- Device status monitoring: Update dashboards or monitoring systems when a device disconnects unexpectedly.
- Fault alerts: Trigger automated alarms, email notifications, or logs when critical devices go offline.
- Resource cleanup: Inform backend services to release or reallocate resources tied to the disconnected device.
Configuration Guidelines
To configure LWT effectively, consider the following best practices:
- Topic Use a dedicated topic structure, such as
status/{client_id}
, to publish LWT messages clearly and consistently. - Message content Keep the payload concise. Include essential metadata such as device ID, timestamp, or status (e.g.,
"offline"
). - QoS level Select a QoS level that balances reliability and network cost. For most use cases, QoS 1 is recommended to ensure message delivery.
- Retain flag Set the
retain
flag if you want new subscribers to be immediately aware of a device’s offline status upon subscribing.
Security Best Practices
Security is critical when building MQTT clients, especially in IoT and enterprise environments where sensitive data is transmitted between devices and services. EMQX supports strong authentication, authorization, and encryption mechanisms to help secure MQTT communication.
This section outlines best practices for client-side security, focusing on identity management, access control, and transport-layer protection.
Client Authentication and Authorization
Secure client identity and strict permission control are the foundation of a secure MQTT environment.
Certificate-Based Authentication
Using digital certificates provides strong, verifiable client identity and supports scalable device provisioning.
- Use X.509 certificates for authenticating MQTT clients.
- Implement certificate rotation policies to ensure keys are updated regularly.
- Store certificates and private keys securely on the client to prevent unauthorized access or leakage.
Access Control
Granular access control prevents clients from publishing or subscribing to unauthorized topics. Follow the principle of least privilege, granting each device or client only the minimum permissions it needs.
Transport-Layer Security
Encrypting traffic between clients and the broker is essential to protect data integrity and confidentiality.
TLS/SSL Encryption
Transport Layer Security (TLS) prevents eavesdropping and tampering during message transmission.
- Use TLS 1.2 or higher for all MQTT client connections.
- Regularly audit and update TLS configurations to remove deprecated or insecure cipher suites.
- Enable certificate validation to protect against man-in-the-middle attacks.
Protocol Hardening and Validation
Strengthen the overall security posture by enforcing safe protocol-level defaults.
- Disable insecure protocol versions and cipher suites.
- Validate the broker’s certificate on the client side before initiating a session.
- Implement certificate revocation checking mechanisms.
Device Event Logging
While EMQX functions as a high-performance MQTT broker focused on real-time message routing, many applications require comprehensive logging of device activities and system events for monitoring, analytics, and troubleshooting purposes.
This section explains how to extend EMQX with event logging capabilities using the built-in Event Topics and Data Integration features available in EMQX Platform.
Understand Broker-Side Event Storage Limitations
By design, EMQX does not persist message content or provide historical storage of device activity. Its focus is on real-time delivery and connection state tracking.
EMQX Broker Scope
- Handles real-time routing and delivery of MQTT messages.
- Does not store message payloads or retain historical event logs.
- Maintains only connection states and routing information.
- Does not provide historical event tracking capabilities.
To implement full observability, message auditing, or long-term storage, event data must be forwarded to external systems using EMQX's Data Integration feature.
Record Events via Data Integration
In real-world IoT deployments, it’s often necessary to go beyond basic message delivery and implement comprehensive event logging. EMQX Platform supports event-based data integration, allowing you to export operational events to external systems for monitoring, analytics, auditing, and debugging purposes.
The following categories represent common types of events developers may need to record:
- Device connection/disconnection events
- Subscription and unsubscription activities
- Message content and metadata
- Authentication and authorization events
Event Topics Available
EMQX Cloud provides a variety of system event topics under the $events/
namespace. These topics expose internal broker events, enabling you to monitor client behavior, message delivery, and security-related operations in real-time.
Category | Topic | Description |
---|---|---|
Client events | $events/client_connected | Client connected |
$events/client_disconnected | Client disconnected | |
$events/client_subscribed | Client subscribed to a topic | |
$events/client_unsubscribed | Client unsubscribed from a topic | |
Session events | $events/session_created | New session created |
$events/session_terminated | Session ended | |
Message events | $events/message_delivered | Message delivered to client |
$events/message_dropped | Message dropped by the broker | |
$events/message_acked | Message acknowledged by client | |
Security events | $events/client_check_authn_complete | Authentication check completed |
$events/client_check_authz_complete | Authorization check completed |
Implementation Strategy
To enable device activity logging and observability, follow this three-step approach:
Step 1: Configure data integration rules
- Define rules in the EMQX Platform Console to match specific event topics (e.g.,
$events/client_connected
). - Use SQL-like filtering or condition matching if needed.
Step 2: Choose a storage or streaming backend
Select an appropriate destination based on your use case:
- Time-series databases: InfluxDB, TimescaleDB for metrics and trend visualization
- Document stores: MongoDB, Elasticsearch for flexible querying and event storage
- Data warehouses: BigQuery, Redshift for analytics and reporting
- Streaming systems: Kafka, RabbitMQ for real-time event streaming
Step 3: Process and store event data
- Parse and enrich event data with metadata (e.g., tenant ID, geolocation).
- Apply filters to reduce noise and focus on relevant events.
- Normalize and transform event format for downstream services.
- Implement retention policies for historical data to meet compliance and auditing needs.
Best Practices for Event Recording
Event filtering
- Subscribe only to necessary event types to avoid excessive data volume.
- Apply client-side filters for specific devices, regions, or product types.
- Use wildcards cautiously when matching topics to avoid oversubscribing.
Data formatting and consistency
- Define a standard event schema across systems and integrations.
- Include essential metadata such as:
- Timestamp
- Client ID or device ID
- Event type
- Implement data validation and error handling in your pipeline.
Performance considerations
- Monitor throughput and latency of the event forwarding pipeline.
- Implement buffering mechanisms for high-volume event streams.
- Apply batch processing for non-critical event streams to reduce overhead.
Security and compliance
- Ensure all event data is transmitted and stored using encryption.
- Apply access controls on logging backends to protect sensitive data.
- Define and enforce data retention and privacy policies based on local regulations.
Monitoring and alerting
Integrate event logs with your monitoring and alerting systems to detect issues and automate responses.
Examples of Actionable Alerts
Set up monitoring for critical events and establish alerting mechanisms:
- Offline detection: Alert when critical devices disconnect unexpectedly.
- Subscription anomalies: Detect unusual subscription patterns or abuse.
- Delivery failures: Monitor dropped messages or unacknowledged QoS 1/2 messages.
- Authentication failures: Track repeated failed login attempts for security auditing.
Ayalytics and Reporting
Use stored event data for:
- Device connectivity analytics
- Usage pattern analysis
- Performance optimization insights
- Compliance reporting and auditing
For detailed information on configuring event topics and data integration, please refer to the documentation: Data Sources and Fields
Quotas and Limitations
The EMQX Platform enforces different usage limits depending on your deployment plan and resource specifications. These quotas may include constraints on connections, subscriptions, message rates, and data throughput.
For the most up-to-date and detailed quota information, refer to the official documentation: Quotas and Limits.
Summary
This guide has outlined the essential best practices for developing efficient, stable, and secure MQTT clients using the EMQX Platform. By following these recommendations, developers can optimize client performance and ensure smooth integration with EMQX at scale.
Key takeaways include:
- Connection management Establish robust client connections with automatic reconnection and session persistence strategies.
- Topic subscription design Use structured topic hierarchies and wildcards wisely to reduce complexity and improve efficiency.
- QoS configuration Select appropriate QoS levels based on business requirements, prioritizing lower levels where reliability trade-offs are acceptable.
- Shared subscriptions Leverage MQTT 5.0 shared subscriptions for backend scaling, load balancing, and failover.
- Security practices Implement end-to-end security through strong authentication, authorization, and TLS encryption.
- Event logging and data integration Use EMQX’s rule engine and event topics to forward operational data to external systems for observability and analytics.
For high-throughput scenarios (e.g., exceeding 5,000 messages per second), it is recommended to bridge MQTT data to message queue systems such as Kafka through data integration instead of relying solely on shared subscriptions.
Before deployment, ensure your system design complies with the EMQX Platform’s quota specifications. For more complex or large-scale use cases, explore EMQX Platform’s advanced features to support high availability, elasticity, and operational observability.