EMQX Enterprise Version 6
6.0.0
Release Date: 2025-09-30
Make sure to check the breaking changes and known issues before upgrading to EMQX 6.0.0.
Feature Highlights
EMQX Enterprise 6.0.0 is the first release of the EMQX Enterprise version 6 series, bringing significant architectural improvements and new capabilities.
Message Queue
The native Message Queue feature unifies real-time MQTT publish/subscribe with persistent asynchronous queuing. The server buffers messages that match a topic filter, retaining them even when subscribers are offline. Clients can consume these messages through the special $q/{topic}
topic, ensuring reliable message delivery.
Message Queues support offline message storage, last-value retention, and flexible dispatch strategies, enhancing MQTT with both real-time and durable messaging capabilities.
Namespace
The Namespace feature improves multi-tenancy and observability with namespace-level roles in the Dashboard. Users are restricted to their own resources (e.g., Rules, Actions, and Connectors) with fine-grained permissions such as Administrator or Viewer, and roles can be managed via the Dashboard, API, or CLI, simplifying multi-tenant operations.
Session count tracking has also been optimized: counts refresh on demand when there are fewer than 1,000 connections, and every 5 seconds otherwise. During rolling upgrades from older versions, counts may temporarily appear inconsistent, but will stabilize once all nodes are updated.
MQTT Durable Sessions
Durable storage has been optimized by separating session data from the broker’s other metadata, significantly reducing RAM usage and improving storage efficiency.
New configuration options provide finer control over RocksDB memory usage and performance. In addition, the default serialization schema for stored messages has been updated to ASN.1, further enhancing efficiency.
New Data Integrations
- Google BigQuery
- AWS AlloyDB
- CockroachDB
- AWS Redshift
Enhanced Integration
AWS:
- Support for Instance Metadata Service v2 APIs from EC2 instances when using S3 or S3Tables data integration. This enables seamless access to S3 buckets without manual AWS credential configuration, leveraging IAM roles for better security.
- Parquet format support for S3 Tables Action.
RabbitMQ: Define custom Headers and Properties Templates in RabbitMQ Sink to enhance message routing and compatibility within RabbitMQ.
Snowflake: Snowpipe Streaming upload mode for Snowflake Action (preview feature).
RocketMQ: New
key
andtag
template fields in Action, along with akey_dispatch
option for the Produce Strategy, allowing greater customization of message metadata.
Elixir Support
All packages now ship with Elixir support through the Mix build system, opening EMQX to the Elixir community and enabling better tooling with IEx console.
Enhanced LDAP Support
LDAP authorization now supports extended ACL rules in JSON format, and LDAP authentication can fetch ACL rules directly from LDAP with client-side caching.
Improved Tracing
Configurable limits for maximum traces (trace.max_traces
) and trace file sizes (trace.max_file_size
). After max_file_size
is reached, the trace log will rotate to a new file instead of halting.
Cluster Management
New cluster.description
configuration option allows users to set and display custom cluster descriptions in the EMQX Dashboard.
Enhancements
Message Queue
- #15789 Implemented Message Queues, which are collections of messages identified by
topic_filter
. Each queue has an explicit lifecycle and is automatically replenished with published messages matched with the queue's topic filter during the queue's lifetime. Clients can cooperatively consume messages from a queue by subscribing to a special topic in the format:$q/{topic}
.
Core MQTT Functionalities
- #15805 Introduced a dedicated worker pool for handling sharded fanout message delivery. Previously, the broker pool handled both subscription management and message dispatch, which could lead to scheduling contention. This change separates the fanout dispatch workload into its own pool to ensure more balanced and efficient handling of pub/sub operations.
Access Control
#15349 Optimize external resource management for authentication and authorization. Previously, EMQX could remain connected to a resource configured for a disabled authenticator or authorizer.
#15294 Enhanced LDAP authentication and authorization. LDAP authorization now supports extended ACL rules in JSON format. LDAP authentication can now fetch ACL rules from LDAP. These rules are cached in the client's metadata, so authorization is performed without additional LDAP queries.
#15730 Added support for overriding the client ID based on authentication results. If an authentication backend returns a
clientid_override
attribute upon successful authentication, it will replace the client’s original client ID.The following backends now support
clientid_override
:- HTTP
- JWT
- LDAP
- MongoDB
- MySQL
- Postgres
- Redis
#15820 Changed default value of config
authorization.no_match
fromallow
todeny
for better security defaults.
Clustering
- #15600 Introduced a new configuration option
cluster.description
that allows you to add a descriptive label to the EMQX cluster. This description can be updated viaPUT /cluster
, and retrieved with theGET /cluster
API.
LLM-Based MQTT Data Processing
#15467 Exposed transport configuration options for AI Completion Providers. Users can now configure connection timeouts and the maximum number of connections to AI Completion Providers. This helps prevent
checkout_timeout
errors when message throughput is high and the provider is under load.Flow designer supports integrating with the Google Gemini model.
#15631 Added a new API endpoint to list all models available for an AI provider.
#15467 Exposed transport options for AI Completion Providers. These options allow configuring connection timeouts and maximum connections to an AI Completion Provider.
#15724 Introduced
openai_response
type for AI Completion Providers and completion profiles to use OpenAI'sresponse
API.
Data Integration
#15418 EMQX supports data integration with BigQuery.
#15401 Added support for the Snowpipe Streaming upload mode in the Snowflake Action. Note: Snowpipe Streaming is currently a preview feature and is only available for Snowflake accounts hosted on AWS.
#15387 Added rate limiting to Kinesis Producer Connector and Action health checks to comply with AWS API quotas and improve cluster behavior.
- Health check calls to
ListStreams
andDescribeStream
are now limited to 5/s and 10/s per Connector, respectively, matching AWS rate limits. - A distributed limiter is coordinated by a core node in the cluster to enforce these limits consistently.
- If a health check is throttled or times out, the Connector or Action will now retain its previous status instead of being marked as disconnected.
Also introduced a new
resource_opts.health_check_interval_jitter
, which adds a uniform random delay toresource_opts.health_check_interval
to reduce the chance of multiple Actions under the same Connector running health checks at the same time.- Health check calls to
#15176 Upgraded the GreptimeDB Connector client and supported an optional new parameter
ttl
to set the default time-to-live for automatically created tables.#15649 EMQX supports data integration with AWS AlloyDB, CockroachDB, and AWS Redshift.
#15635 Added new
key
andtag
template fields in the RocketMQ Action, allowing customization of the message's key and tag. Also, introduced a newkey_dispatch
option for theProduce Strategy
field.#15621 Now,
access_key_id
andsecret_access_key
are optional fields for the S3 Tables Connector. If omitted, they'll be obtained from the Instance Metadata Service v2 APIs from the EC2 instance where EMQX is deployed.#15628 Removed HStreamDB data integration.
#15544 Added Arrow Flight SQL NIF driver support for Datalayers Integration.
#15637 Added support for templating message headers and properties for the RabbitMQ Action.
#15864 Removed the deprecated "Bridges V1" APIs and configuration schemas. All endpoints under
/bridges/*
and configuration entries under thebridges
root key are no longer available, as data integrations have fully migrated to the "Connectors/Actions/Sources" model.#15583 Updated the
brod
client to version 4.4.4, expanding support for a wider range of Kafka APIs. This update addresses the deprecation ofJoinGroups
API versionsv0
-v1
.
Smart Data Hub
- #15525 Prevented deletion of internal schemas that are still in use. If a schema is referenced by a Schema Validation or Message Transformation, it can no longer be removed to avoid runtime errors and configuration inconsistencies.
Durable Storage
#15463 Improved durable storage RAM usage and storage efficiency.
- Introduced the following configuration parameters for the durable storage to improve control over RocksDB memory usage and storage performance:
durable_storage.messages.rocksdb.write_buffer_size
: RocksDB memtable size per shard.durable_storage.messages.rocksdb.cache_size
: RocksDB block size per shard.durable_storage.messages.rocksdb.max_open_files
: Limits the number of file descriptors used by RocksDB per shard.durable_storage.messages.layout.wildcard_thresholds
: Allows to tune wildcard thresholds for thewildcard_optimized_v2
storage layout.
- Additionally, the default
serialization_schema
for stored messages has been changed toasn1
.
- Introduced the following configuration parameters for the durable storage to improve control over RocksDB memory usage and storage performance:
#16044 Some of config fields for durable sessions have been removed or renamed, and old values are marked as deprecated:
durable_sessions.heartbeat_interval
has been renamed todurable_sessions.checkpoint_interval
.durable_sessions.idle_poll_interval
anddurable_sessions.renew_streams_interval
have been removed, as sessions are now fully event-driven.durable_sessions.session_gc_interval
anddurable_sessions.session_gc_batch_size
have been removed as obsolete.
CLI
- #15399 The
node_dump
tool now exports the current system configuration in HOCON format, with sensitive information (such as passwords and secrets) automatically redacted for security.
Namespace
#15841 Improved the refresh rate of the session count for namespaced sessions.
- If a namespace has fewer than 1000 connections, its session count is now updated on demand.
- For namespaces with 1000 or more connections, the count is updated every 5 seconds.
During a rolling upgrade from versions prior to 6.0, session counts may appear inconsistent due to changes in the internal tracking tables. This is expected: as clients reconnect to upgraded nodes, the session counts will gradually stabilize and become accurate once all nodes are running version 6.0 or later.
Observability
#15594 Introduced a new configuration option
trace.max_traces
to control the maximum number of active cluster-wide traces. This limit does not apply to node-local traces managed usingemqx ctl trace
.This update also optimized tracing implementation to eliminate potential atom leaks per created trace.
#15556 Introduced a new configuration option
trace.max_file_size
to limit the maximum file size for each individual trace.#15650 Implemented automatic trace log rotation.
When a trace file size exceeds
trace.max_file_size
, EMQX no longer discards all subsequent events and emits an incomprehensible warning tostderr
. Instead, portions of the oldest events are discarded while the most recent ones are retained.As such, this also implies that:
- EMQX now maintains multiple trace log files per active trace. The layout of the trace directory has changed accordingly.
- Trace API has been updated to reflect this behavior. The Log Stream API may return new errors, such as when a stream becomes stale due to a slow consumer.
#15904 Support viewing and updating of tracing configuration through Trace API.
Performance
- #15451 Introduced an experimental
socket
backend for TCP listeners, aimed at improving message processing latency and reducing compute resource usage. The feature can be enabled with the newtcp_backend
listener option.
Build and Tooling
- #15484 Switched the build system to Elixir's Mix, enabling all packages to include native Elixir support. This change improves developer tooling, allows integration with Elixir dependencies when needed, and enables use of the IEx shell as a more powerful EMQX console.
License
- #15921 Introduced a license alarm for cluster-wide maximum transactions per second (TPS).
- Each node calculates TPS as the average number of MQTT messages sent and received over the past 10 seconds.
- The total cluster TPS is aggregated every 5 seconds.
- If the observed TPS exceeds the licensed limit, an alarm is triggered.
- The alarm remains active until a license with a higher TPS allowance is applied.
MQTT over QUIC
- #15997 Added support for disabling QUIC stack loading by setting the environment variable
QUICER_SKIP_NIF_LOAD=1.
Bug Fixes
Core MQTT Functionalities
#15396 Removed redundant cleanup operations for shared subscriptions of disconnected clients. These operations were prone to crashes under high disconnect volumes and could lead to inconsistencies in the global broker state.
#15361 Fixed a
function_clause
error when parsing a malformedUser-Property
pair with invalid (too short) length.#15783 Ensure that any changes to connection rate limits take effect immediately after the listener update has completed. Previously, parts of internal limiter state were not directly affected by configuration changes. For example, after increasing the burst rate, the effective rate limit could appear stricter than expected.
Access Control
- #15489 Fixed OIDC issuer URL validation in Single Sign-On (SSO) settings. Previously, issuer URLs containing a port number (for example,
https://xxxxxxxx:8443/webman/sso/.well-known/openid-configuration
) were rejected with abad_port_number
error. These URLs are now supported.
Rule Engine
- #15569 Fixed an issue where a Republish Rule Action could fail if the
direct_dispatch
template was empty or resolved to a non-boolean value. In these cases, the default valuefalse
is now used.
Data Integration
- #15522 Fixed an issue where Snowflake Connector would fail to start correctly if
username
was not provided. - #15476 Fixed a missing callback in
emqx_connector_aggreg_delivery
that caused a crash when formatting delivery process status for aggregated-mode Actions (e.g., Azure Blob Storage, Snowflake, S3 Tables). This occurred during failures or when inspecting delivery processes withgen_server:format_status/1
. The issue is now resolved, and more detailed delivery status information will be logged. - #15394 Fixed a rare race condition where Action metrics could become inconsistent due to unexpected asynchronous replies.
- #15647 Fixed an issue where a MongoDB Connector was marked as
Disconnected
if the MongoDB account specified in the connector configuration lacked privileges to performfind
queries on thefoo
collection. - #15603 Fixed an issue in the MQTT bridge where a stale connection could be shown as
Connected
and would not automatically reconnect. - #15383 Fixed a potential resource leak in MQTT bridge. When a bridge failed to start, the topic index table was not properly cleaned up.
- #15786 Fixed a potential atom leak when probing RocketMQ Connectors.
- #15806 Improved validation for Oracle Actions during creation. Previously, in rare cases, an Action containing an invalid SQL statement could be added successfully.
- #15848 Improved error reporting for the Oracle Connector. When the connector becomes disconnected, its status now includes a more specific reason, making diagnostics easier.
- #15693 Fixed a resource leak in Postgres-based bridges. Under certain race conditions during pool initialization, deleting a Connector could leave its connection pool behind. This has been corrected to ensure connection pools are properly cleaned up.
- #15543 Fixed an issue in HTTP Server data integration when sending large payloads. If the payload size was 10 MB or more, the HTTP request could fail.
Smart Data Hub
#15839 Fixed an encoding issue with Protobuf schemas that use
map<_, _>
fields. Previously, schemas containingmap<string, string>
fields could fail to encode valid payloads, resulting in cryptic runtime errors.Example schema:
protobufsyntax = "proto3"; message test { map<string, string> args = 1; }
Example rule:
sqlSELECT schema_encode('xxx', json_decode(payload), 'test') as protobuf_test FROM "t/#"
Example payload failed to be encoded:
json{ "args": { "env": "stag" } }
Previous error similar to:
2025-06-17T06:59:22.725785+00:00 [warning] tag: RULE_SQL_EXEC, clientid: c_emqx, msg: SELECT_clause_exception, reason: {error,{gpb_type_error,{bad_unicode_string,[{value,env},{path,"test.args.key"}]}},[{'$schema_parser_xxx',mk_type_error,3,[{file,"$schema_parser_xxx.erl"},{line,437}]},{'$schema_parser_xxx','-v_map<string,string>/3-lc$^0/1-0-',3,[{file,"$schema_parser_xxx.erl"},{line,429}]},{'$schema_parser_xxx','v_map<string,string>',3,[{file,"$schema_parser_xxx.erl"},{line,429}]},{'$schema_parser_xxx',v_msg_test,3,[{file,"$schema_parser_xxx.erl"},{line,404}]},{'$schema_parser_xxx',encode_msg,3,[{file,"$schema_parser_xxx.erl"},{line,73}]},{emqx_schema_registry_serde,with_serde,2,[{file,"emqx_schema_registry_serde.erl"},{line,212}]}...
Observability
#15931 Resolved a bug where spurious but harmless error logs could appear during node startup:
[error] Generic event handler emqx_alarm_handler crashed ... Reason: {aborted,{no_exists,[emqx_activated_alarm,runq_overload]}}
#15973 Fixed a bug where an alarm activation timeout could crash the connection process under certain conditions.
MQTT over QUIC
- #15614 QUIC Listener: When TLS key logging (
SSLKEYLOGFILE
) is enabled, EMQX now dumps TLS keys even if the handshake fails.
Clustering
- #16021 Fixed issues that occasionally prevented the DS Raft backend from functioning correctly when an existing node joined a new cluster and subsequently became member of DS replica sets.
Cluster Linking
- #15894 Previously, when listing all cluster links via
GET /cluster/links
, disabled links would be returned having aninconsistent
status. Now they are returned asdisconnected
.
Performance
#15696 Added connection rate limiting support for WebSocket (WS) and WebSocket Secure (WSS) listeners. The
max_conn_rate
andmax_conn_burst
configuration options are now enforced: incoming connections exceeding the defined rate are immediately closed upon acceptance, consistent with existing TCP listener behavior.Additionally, the behavior of
max_connections
has been updated. When the connection limit is exceeded, WS/WSS listeners now close connections immediately before any HTTP handshake, resulting in an abrupt socket close instead of returning an HTTP 429 response.#15854 Reduced the default
active_n
value from100
to10
to improve MQTT client responsiveness, especially under high message rates with small payloads.The lower
active_n
introduces more backpressure at the TCP layer, stricter than the defaultReceive-Maximum
of32
, which helps in the following scenarios:- The client process is blocked by external authorization checks
- Data integration operations are delaying message handling
- The system is under heavy load or nearing resource limits
#15981 Prevented excessive memory growth caused by Mnesia transaction blocking during cleanup of large volumes of audit logs. This improves system stability and memory efficiency during heavy audit log maintenance operations.