diff --git a/apps/emqx/src/emqx_schema.erl b/apps/emqx/src/emqx_schema.erl
index afbe2cfa7..77340ca87 100644
--- a/apps/emqx/src/emqx_schema.erl
+++ b/apps/emqx/src/emqx_schema.erl
@@ -1104,6 +1104,14 @@ fields("ws_opts") ->
sc(
ref("deflate_opts"),
#{}
+ )},
+ {"validate_utf8",
+ sc(
+ boolean(),
+ #{
+ default => true,
+ desc => ?DESC(fields_ws_opts_validate_utf8)
+ }
)}
];
fields("tcp_opts") ->
diff --git a/apps/emqx/src/emqx_ws_connection.erl b/apps/emqx/src/emqx_ws_connection.erl
index 4a25494ad..1511eb6e0 100644
--- a/apps/emqx/src/emqx_ws_connection.erl
+++ b/apps/emqx/src/emqx_ws_connection.erl
@@ -205,7 +205,8 @@ init(Req, #{listener := {Type, Listener}} = Opts) ->
compress => get_ws_opts(Type, Listener, compress),
deflate_opts => get_ws_opts(Type, Listener, deflate_opts),
max_frame_size => get_ws_opts(Type, Listener, max_frame_size),
- idle_timeout => get_ws_opts(Type, Listener, idle_timeout)
+ idle_timeout => get_ws_opts(Type, Listener, idle_timeout),
+ validate_utf8 => get_ws_opts(Type, Listener, validate_utf8)
},
case check_origin_header(Req, Opts) of
{error, Reason} ->
diff --git a/changes/perf-12392.en.md b/changes/perf-12392.en.md
new file mode 100644
index 000000000..d44b80b91
--- /dev/null
+++ b/changes/perf-12392.en.md
@@ -0,0 +1,4 @@
+New WebSocket listener option: `validate_utf8` for performance tuning.
+
+
+
diff --git a/rel/i18n/emqx_schema.hocon b/rel/i18n/emqx_schema.hocon
index be16c765e..5ff4e063e 100644
--- a/rel/i18n/emqx_schema.hocon
+++ b/rel/i18n/emqx_schema.hocon
@@ -1275,6 +1275,13 @@ fields_ws_opts_allow_origin_absence.desc:
fields_ws_opts_allow_origin_absence.label:
"""Allow origin absence"""
+fields_ws_opts_validate_utf8.desc:
+"""Set to false
to disable WebSocket Frame UTF-8
+ validation for performance"""
+
+fields_ws_opts_validate_utf8.label:
+"""Enable/Disable WebSocket Frame utf8 validation"""
+
common_ssl_opts_schema_versions.desc:
"""All TLS/DTLS versions to be supported.
NOTE: PSK ciphers are suppressed by 'tlsv1.3' version config.