WuKongIM Docs

Configuration Reference

Searchable WuKongIM configuration handbook explaining every public TOML field, environment override, key default, and constraint.

This is the quick-reference handbook for WuKongIM's public startup configuration, checked against the startup schema. Every row explains what the field controls, its one environment mapping, and any important default, zero-value, mutual-exclusion, compatibility, or security boundary.

How to use this reference

  • Browse by domain with the page outline, or use browser Find to search for a TOML key, WK_* environment variable, or keyword.
  • Prefer TOML for normal configuration; environment variables override TOML. Unknown TOML paths and unknown WK_* variables fail startup.
  • duration uses Go syntax such as 500ms, 5s, or 24h. Environment values for string_list and object_list must be JSON and replace the complete list.
  • Configuration is loaded at node startup. Restart the node after a change unless the subsystem explicitly documents otherwise.

Defaults and configuration baselines

Starting with v3.0.0-beta.7, wukongim init creates a security-oriented installation baseline at /etc/wukongim/wukongim.toml by default and explicitly disables Diagnostics and Plugin. Use wukongim init --config PATH to choose another location; the original wukongim config init --config PATH compatibility entry point also remains available. wukongim.toml.example is a loadable development and tuning baseline. Neither baseline is a complete catalog of runtime defaults. In the table, “omitted” means neither TOML nor an environment value was supplied; it may differ from an explicit 0, empty string, or false.

node.id, node.data_dir, and cluster.listen_addr are always required. Seed joining additionally requires cluster.id, non-empty cluster.seeds, a peer-reachable cluster.advertise_addr, and a non-empty cluster.join_token.

For task-oriented field discovery, start with Common Configurations; this page is the field-by-field reference.

Node

TOMLEnvironmentTypeDescription
node.idWK_NODE_IDuint64Stable, non-zero node ID unique within the cluster; do not change it after data exists. Required at startup.
node.data_dirWK_NODE_DATA_DIRstringRoot directory for this node's durable data; place it on writable, backed-up storage. Required at startup.

Cluster

Identity and discovery

TOMLEnvironmentTypeDescription
cluster.listen_addrWK_CLUSTER_LISTEN_ADDRstringListener for inter-node Cluster RPC; it may bind 0.0.0.0, but a wildcard must not be advertised to peers. Required at startup.
cluster.start_timeoutWK_CLUSTER_START_TIMEOUTdurationMaximum wait for startup readiness gates, including committed Slot write probes; omitted or 0 uses 30s. Must be non-negative. Size from measured cold recovery; quorum, routing, and placement checks and steady-state request timeouts remain unchanged.
cluster.idWK_CLUSTER_IDstringStable Controller cluster identity; required for seed joining. Static inventories and implicit single-node clusters derive it from node IDs when omitted.
cluster.seedsWK_CLUSTER_SEEDSstring_listExisting node addresses used to discover the cluster during dynamic joining; must be non-empty and cannot be combined with cluster.nodes.
cluster.advertise_addrWK_CLUSTER_ADVERTISE_ADDRstringStable address stored in membership for peers to call this node; required with cluster.seeds and must be reachable by peers.
cluster.join_tokenWK_CLUSTER_JOIN_TOKENstringShared credential that authenticates dynamic cluster joining; it must be non-empty whenever present and is required with cluster.seeds. Redacted in startup snapshots and diagnostics.
cluster.nodesWK_CLUSTER_NODESobject_listStatic Controller voters with {id, addr} elements; a non-empty list must contain the current node.id, with non-zero unique IDs and non-empty addresses. It cannot be combined with cluster.seeds; an explicit empty list (including environment JSON null) currently falls back to an implicit single-node cluster and cannot disable clustering.

Slot Raft

TOMLEnvironmentTypeDescription
cluster.initial_slot_countWK_CLUSTER_INITIAL_SLOT_COUNTuint32Independent Slot Raft Groups written to persisted Controller state at first initialization; it cannot exceed cluster.hash_slot_count, and omitted or 0 uses 1. Existing clusters follow the persisted value: changing this setting does not resize Slots, and increasing it may block readiness. Do not change it after initialization.
cluster.hash_slot_countWK_CLUSTER_HASH_SLOT_COUNTuint16Stable hash-slot partitions that route keys across Slot Raft Groups; omitted or 0 uses 256. Do not change it after cluster initialization.
cluster.slot_replica_nWK_CLUSTER_SLOT_REPLICA_Nuint16Voter replicas per Slot Raft Group when initializing Controller state; existing clusters follow persisted Controller state. 0 derives the static voter count but falls back to 1 during seed joining; an explicit static value cannot exceed the voter count.
cluster.channel_replica_nWK_CLUSTER_CHANNEL_REPLICA_Nuint16Desired data replicas for newly created channels; 0 follows the local effective cluster.slot_replica_n, becoming 1 during seed joining rather than reading the persisted Controller replica count. Multi-replica clusters should set the same explicit value on every node and fit available nodes and failure domains.
cluster.slot_tick_intervalWK_CLUSTER_SLOT_TICK_INTERVALdurationLocal Slot Raft tick interval; defaults to 50ms and must be greater than 0.
cluster.slot_election_tickWK_CLUSTER_SLOT_ELECTION_TICKintTicks waited before a Slot Raft election can start; defaults to 40 and must exceed the heartbeat tick.
cluster.slot_heartbeat_tickWK_CLUSTER_SLOT_HEARTBEAT_TICKintSlot Raft heartbeat interval in ticks; defaults to 2 and must be greater than 0.
cluster.slot_log_compaction_enabledWK_CLUSTER_SLOT_LOG_COMPACTION_ENABLEDboolEnables local Slot Raft snapshots and log compaction; enabled when omitted.
cluster.slot_log_compaction_trigger_entriesWK_CLUSTER_SLOT_LOG_COMPACTION_TRIGGER_ENTRIESuint64Applied entries since the last snapshot required before another compaction; defaults to 10000 and must be positive.
cluster.slot_log_compaction_check_intervalWK_CLUSTER_SLOT_LOG_COMPACTION_CHECK_INTERVALdurationMinimum interval between Slot Raft log-compaction checks; defaults to 30s and must be positive.

Channel Runtime

TOMLEnvironmentTypeDescription
cluster.channel_reactor_countWK_CLUSTER_CHANNEL_REACTOR_COUNTintChannel Reactor partitions on this node; 0 derives a CPU-aware runtime value.
cluster.channel_store_append_workersWK_CLUSTER_CHANNEL_STORE_APPEND_WORKERSintMaximum blocking Leader store-append workers; 0 keeps the Channel runtime default.
cluster.channel_store_append_batch_max_waitWK_CLUSTER_CHANNEL_STORE_APPEND_BATCH_MAX_WAITdurationMaximum wait for coalescing Leader store-appends across channels; 0 keeps the Channel worker default.
cluster.channel_store_apply_workersWK_CLUSTER_CHANNEL_STORE_APPLY_WORKERSintMaximum blocking Follower store-apply workers; 0 keeps the Channel runtime default.
cluster.channel_rpc_workersWK_CLUSTER_CHANNEL_RPC_WORKERSintMaximum blocking Channel replication RPC workers; 0 uses 96.
cluster.channel_rpc_batch_max_itemsWK_CLUSTER_CHANNEL_RPC_BATCH_MAX_ITEMSintMaximum same-target Pull or PullHint items coalesced into one RPC; 0 uses 8.
cluster.max_channelsWK_CLUSTER_MAX_CHANNELSintMaximum loaded Channel Runtimes on this node; 0 leaves the count unlimited.
cluster.channel_append_batch_max_recordsWK_CLUSTER_CHANNEL_APPEND_BATCH_MAX_RECORDSintQueued record count that triggers a Channel store-append flush; 0 keeps the runtime default.
cluster.channel_append_batch_max_waitWK_CLUSTER_CHANNEL_APPEND_BATCH_MAX_WAITdurationMaximum age of the oldest queued Channel append before flushing; 0 keeps the runtime default.
cluster.channel_append_batch_adaptive_flushWK_CLUSTER_CHANNEL_APPEND_BATCH_ADAPTIVE_FLUSHboolEnables a shorter adaptive flush delay for low-traffic channels; disabled when omitted.
cluster.channel_append_batch_cold_max_waitWK_CLUSTER_CHANNEL_APPEND_BATCH_COLD_MAX_WAITdurationLow-traffic channel delay used by adaptive flushing; 0 uses the normal batching window.
cluster.channel_follower_recovery_probe_intervalWK_CLUSTER_CHANNEL_FOLLOWER_RECOVERY_PROBE_INTERVALdurationBase interval for probing parked Followers for recovery; 0 keeps the Channel runtime default.
cluster.channel_follower_recovery_probe_jitterWK_CLUSTER_CHANNEL_FOLLOWER_RECOVERY_PROBE_JITTERdurationRandom jitter window that spreads parked-Follower recovery probes; 0 keeps the runtime default.

Health and durable commits

TOMLEnvironmentTypeDescription
cluster.node_health_report_intervalWK_CLUSTER_NODE_HEALTH_REPORT_INTERVALdurationInterval for reporting compact node health to Controller; defaults to 5s and must be positive.
cluster.node_health_report_ttlWK_CLUSTER_NODE_HEALTH_REPORT_TTLdurationHow long Controller trusts the latest node-health report; defaults to 30s and cannot be shorter than the report interval.
cluster.commit_coordinator_syncWK_CLUSTER_COMMIT_COORDINATOR_SYNCboolDurable-commit compatibility switch; omitted is equivalent to true, and an explicit value must also be true because WuKongIM does not allow durable sync to be disabled.
cluster.commit_coordinator_flush_windowWK_CLUSTER_COMMIT_COORDINATOR_FLUSH_WINDOWdurationMaximum delay for grouping adjacent Channel durable commits; defaults to 500us, and an explicit value must be positive.
cluster.commit_coordinator_max_requestsWK_CLUSTER_COMMIT_COORDINATOR_MAX_REQUESTSintMaximum logical requests grouped into one physical commit; 0 applies no request-count limit.
cluster.commit_coordinator_max_recordsWK_CLUSTER_COMMIT_COORDINATOR_MAX_RECORDSintMaximum message records grouped into one physical commit; 0 applies no record-count limit.
cluster.commit_coordinator_max_bytesWK_CLUSTER_COMMIT_COORDINATOR_MAX_BYTESintMaximum approximate payload bytes grouped into one physical commit; 0 applies no byte limit.
cluster.commit_coordinator_shardsWK_CLUSTER_COMMIT_COORDINATOR_SHARDSintIndependent commit coordinators for the message database; 0 uses 1. Increase only after storage-specific load tests.

Channel Migration

TOMLEnvironmentTypeDescription
channel_migration.enableWK_CHANNEL_MIGRATION_ENABLEboolStarts the background worker that advances Channel migrations and creates repair tasks; enabled when omitted.
channel_migration.scan_intervalWK_CHANNEL_MIGRATION_SCAN_INTERVALdurationInterval for scanning and advancing Channel migration work; omitted uses 1s, and an explicit value must be positive.
channel_migration.scan_limitWK_CHANNEL_MIGRATION_SCAN_LIMITintChannel Runtime metadata rows read from one Slot page per scan; omitted uses 64, and an explicit value must be positive.
channel_migration.max_pages_per_tickWK_CHANNEL_MIGRATION_MAX_PAGES_PER_TICKintMaximum physical Slot pages scanned per worker tick; omitted uses 1, and an explicit value must be positive.
channel_migration.max_tasks_per_tickWK_CHANNEL_MIGRATION_MAX_TASKS_PER_TICKintMaximum repair tasks created per scan; omitted uses 1, and an explicit value must be positive.
channel_migration.task_limitWK_CHANNEL_MIGRATION_TASK_LIMITintMaximum active migration tasks inspected by the executor per tick; omitted uses 1, and an explicit value must be positive.

Channel & Retention

TOMLEnvironmentTypeDescription
channel.message_retention_physical_gc_enableWK_CHANNEL_MESSAGE_RETENTION_PHYSICAL_GC_ENABLEboolEnables background physical deletion of local messages beyond each channel's retention boundary; disabled when omitted.
channel.message_retention_scan_intervalWK_CHANNEL_MESSAGE_RETENTION_SCAN_INTERVALdurationInterval for scanning one channel-catalog page for retention cleanup; 0 uses 1m.
channel.message_retention_channel_batch_sizeWK_CHANNEL_MESSAGE_RETENTION_CHANNEL_BATCH_SIZEintMaximum local channel-catalog entries processed per cleanup pass; 0 uses 128.
channel.message_retention_max_trim_messagesWK_CHANNEL_MESSAGE_RETENTION_MAX_TRIM_MESSAGESintMaximum message rows deleted for one channel per cleanup attempt; 0 uses 1000.
channel.message_retention_max_trim_bytesWK_CHANNEL_MESSAGE_RETENTION_MAX_TRIM_BYTESintMaximum payload bytes deleted for one channel per cleanup attempt; 0 applies no byte limit.
channel.large_group_subscriber_thresholdWK_CHANNEL_LARGE_GROUP_SUBSCRIBER_THRESHOLDintTreats a channel as a large group when ordinary subscribers exceed this count; defaults to 500 and must be positive.

API & Client Addresses

TOMLEnvironmentTypeDescription
api.listen_addrWK_API_LISTEN_ADDRstringListener for the product HTTP API; an empty value disables this HTTP service.
api.external_tcp_addrWK_EXTERNAL_TCPADDRstringWKProto TCP address override published to capacity discovery and similar callers, in host:port form; empty derives from the first matching gateway.listeners entry and stays empty if none matches. It does not create a listener.
api.external_ws_addrWK_EXTERNAL_WSADDRstringWebSocket URL override published to capacity discovery and similar callers; empty derives from the first matching gateway.listeners entry and stays empty if none matches. It does not create a listener and is redacted from diagnostic artifacts.
api.external_wss_addrWK_EXTERNAL_WSSADDRstringSecure WebSocket URL override published to capacity discovery and similar callers; empty derives from the first matching gateway.listeners entry and stays empty if none matches. It does not create a listener and is redacted from diagnostic artifacts.

When the corresponding api.external_* is omitted, default external /route and /route/batch complete only wildcard listener hosts from a valid request Host, preserving the Gateway port, scheme, and path. Explicit addresses, concrete listener hosts (including loopback), intranet queries, and explicit node selectors stay unchanged; capacity discovery still returns listener-derived addresses. Completed responses use Cache-Control: no-store. Completion ignores forwarded headers and cannot infer NAT ports or TLS ingress; reverse proxies should preserve the original Host. Configure client-reachable overrides for remapped external ports, separate ingress, or a backend calling /route through an internal host.

Manager

TOMLEnvironmentTypeDescription
manager.listen_addrWK_MANAGER_LISTEN_ADDRstringListener for the Manager administration service; an empty value disables Manager.
manager.auth_onWK_MANAGER_AUTH_ONboolRequires JWT login authentication for Manager routes; disabled when omitted. With false, Manager routes require no JWT, so do not expose an unauthenticated service to untrusted networks.
manager.jwt_secretWK_MANAGER_JWT_SECRETstringSecret used to sign and verify Manager JWTs; required when Manager is listening with authentication enabled. Redacted in startup snapshots and diagnostics.
manager.jwt_issuerWK_MANAGER_JWT_ISSUERstringIssuer written to the Manager JWT iss claim.
manager.jwt_expireWK_MANAGER_JWT_EXPIREdurationManager JWT lifetime; when Manager is listening with authentication enabled, omitted or explicit 0 uses 24h, while a negative value fails startup.
manager.usersWK_MANAGER_USERSobject_listStatic Manager users with username, password, and permissions[{resource, actions}]; actions are r, w, or *. Required when Manager is listening with authentication enabled and fully redacted.

Benchmark

TOMLEnvironmentTypeDescription
bench.api_enableWK_BENCH_API_ENABLEboolExposes /bench/v1/* routes on the API listener for controlled benchmark environments; disabled when omitted and requires non-empty api.listen_addr.
bench.api_tokenWK_BENCH_API_TOKENstringBench API bearer token; an empty value skips token validation, so set it whenever the API is remotely reachable. Redacted in snapshots and diagnostics.
bench.api_max_batch_sizeWK_BENCH_API_MAX_BATCH_SIZEintMaximum top-level records accepted by one Bench API mutation request; omitted uses 10000, while an explicit value at or below 0 removes this limit and is not recommended for remotely reachable environments.
bench.api_max_payload_bytesWK_BENCH_API_MAX_PAYLOAD_BYTESintMaximum JSON body bytes accepted by one Bench API mutation request; omitted uses 10485760 (10 MiB), while an explicit value at or below 0 removes this limit and is not recommended for remotely reachable environments.

Observability Switches

TOMLEnvironmentTypeDescription
observability.metrics_enableWK_METRICS_ENABLEboolEnables runtime metric observers and exposes /metrics when an API listener exists; disabled when omitted. The HTTP metrics endpoint requires non-empty api.listen_addr.
observability.debug_api_enableWK_DEBUG_API_ENABLEboolExposes /debug diagnostics on the API listener; disabled when omitted and requires non-empty api.listen_addr. Never publish it directly to the internet.

Prometheus

TOMLEnvironmentTypeDescription
prometheus.enableWK_PROMETHEUS_ENABLEboolStarts a Prometheus child process managed by WuKongIM; disabled when omitted. Enabling also requires an API listener, metrics, and valid scrape targets; keep it disabled with external Prometheus.
prometheus.query_base_urlWK_PROMETHEUS_QUERY_BASE_URLstringBase URL used by Manager to query an external Prometheus HTTP API; it must be an HTTP(S) URL with a host and no query or fragment. Empty may fall back to managed Prometheus. Redacted from diagnostics.
prometheus.binary_pathWK_PROMETHEUS_BINARY_PATHstringExternal Prometheus executable used by the managed process; empty uses the embedded binary.
prometheus.listen_addrWK_PROMETHEUS_LISTEN_ADDRstringWeb listener for the managed Prometheus process, in host:port form; defaults to 127.0.0.1:9099.
prometheus.data_dirWK_PROMETHEUS_DATA_DIRstringDirectory for generated Prometheus configuration and TSDB data; empty derives it from node.data_dir.
prometheus.retention_timeWK_PROMETHEUS_RETENTION_TIMEdurationTime-based retention window for the managed Prometheus TSDB; omitted or 0 uses 360h.
prometheus.retention_sizeWK_PROMETHEUS_RETENTION_SIZEstringOptional size-based retention limit for the managed Prometheus TSDB; empty applies no size limit.
prometheus.scrape_intervalWK_PROMETHEUS_SCRAPE_INTERVALdurationInterval for managed Prometheus to scrape WuKongIM metrics; omitted or 0 uses 15s.
prometheus.scrape_targetsWK_PROMETHEUS_SCRAPE_TARGETSstring_listMetrics targets for managed Prometheus as host:port values without a URL scheme and with ports from 1 to 65535; an empty list may be derived from the API listener.

Top

TOMLEnvironmentTypeDescription
top.api_enableWK_TOP_API_ENABLEboolExposes the read-only /top/v1/snapshot endpoint on the API listener for wkcli top; disabled when omitted and requires non-empty api.listen_addr.
top.collect_intervalWK_TOP_COLLECT_INTERVALdurationInterval at which Top samples local runtime state; omitted or 0 uses 1s.
top.history_windowWK_TOP_HISTORY_WINDOWdurationIn-memory sample window retained for Top queries; omitted or 0 uses 5m and must be at least twice the collection interval.

Diagnostics

TOMLEnvironmentTypeDescription
diagnostics.enableWK_DIAGNOSTICS_ENABLEboolCaptures bounded node-local diagnostic events; enabled when omitted.
diagnostics.buffer_sizeWK_DIAGNOSTICS_BUFFER_SIZEintMaximum diagnostic events retained in memory; 0 uses 50000.
diagnostics.sample_rateWK_DIAGNOSTICS_SAMPLE_RATEfloatBaseline keep probability for successful diagnostic events, from 0 to 1; omitted uses 0.01.
diagnostics.slow_threshold_msWK_DIAGNOSTICS_SLOW_THRESHOLD_MSintDuration threshold for keeping successful slow events, in milliseconds; omitted or 0 uses 500.
diagnostics.error_sample_rateWK_DIAGNOSTICS_ERROR_SAMPLE_RATEfloatKeep probability for non-success diagnostic events, from 0 to 1; omitted uses 1.
diagnostics.deep_sample_rateWK_DIAGNOSTICS_DEEP_SAMPLE_RATEfloatSampling probability for expensive Reactor or store detail, from 0 to 1; defaults to 0.
diagnostics.deep_slow_threshold_msWK_DIAGNOSTICS_DEEP_SLOW_THRESHOLD_MSintThreshold for deep tracing slow Reactor or store stages, in milliseconds; omitted or 0 follows the normal slow threshold.
diagnostics.deep_max_items_per_batchWK_DIAGNOSTICS_DEEP_MAX_ITEMS_PER_BATCHintMaximum messages expanded into events by one deep-trace batch; 0 uses 16.
diagnostics.debug_matchesWK_DIAGNOSTICS_DEBUG_MATCHESobject_listTemporary high-priority sampling rules; an empty list means none. Each item needs at least one of uid, channel_key, client_msg_no, or trace_id; positive ttl_seconds is required to take effect and zero is silently ignored. sample_rate ranges from 0 to 1, where 0 retains nothing.

Gateway

TOMLEnvironmentTypeDescription
gateway.token_auth_onWK_GATEWAY_TOKEN_AUTH_ONboolRequires each CONNECT token to exactly match the stored device token for the same UID and device_flag; defaults to true. Disable only for a controlled compatibility migration.
gateway.gnet_multicoreWK_GATEWAY_GNET_MULTICOREboolEnables gnet's CPU-scaled multi-event-loop mode; enabled when omitted.
gateway.gnet_num_event_loopWK_GATEWAY_GNET_NUM_EVENT_LOOPintgnet event-loop count; 0 retains the WuKongIM baseline of 4.
gateway.runtime_async_send_workersWK_GATEWAY_RUNTIME_ASYNC_SEND_WORKERSintMaximum workers dispatching SEND frames asynchronously; a non-positive value uses 1000.
gateway.runtime_async_send_queue_capacityWK_GATEWAY_RUNTIME_ASYNC_SEND_QUEUE_CAPACITYintMaximum queued asynchronous SEND frames; a non-positive value uses 131072, and a full queue rejects new SEND frames.
gateway.runtime_async_auth_workersWK_GATEWAY_RUNTIME_ASYNC_AUTH_WORKERSintMaximum workers processing CONNECT authentication asynchronously; a non-positive value uses 16.
gateway.runtime_async_auth_queue_capacityWK_GATEWAY_RUNTIME_ASYNC_AUTH_QUEUE_CAPACITYintMaximum queued CONNECT authentications; a non-positive value uses 8192, and a full queue rejects new CONNECT authentication requests.
gateway.runtime_async_pool_release_timeoutWK_GATEWAY_RUNTIME_ASYNC_POOL_RELEASE_TIMEOUTdurationMaximum graceful-release wait for asynchronous worker pools during shutdown; a non-positive value uses 100ms.
gateway.default_session_async_send_batch_max_waitWK_GATEWAY_DEFAULT_SESSION_ASYNC_SEND_BATCH_MAX_WAITdurationMaximum wait for a SEND shard to collect adjacent frames; 0 uses 1ms, while a negative value normalizes to 0 and disables waiting.
gateway.default_session_async_send_batch_max_recordsWK_GATEWAY_DEFAULT_SESSION_ASYNC_SEND_BATCH_MAX_RECORDSintMaximum frames in one Gateway SEND micro-batch; 0 uses 128.
gateway.default_session_async_send_batch_max_bytesWK_GATEWAY_DEFAULT_SESSION_ASYNC_SEND_BATCH_MAX_BYTESintMaximum payload bytes in one Gateway SEND micro-batch; 0 uses 524288.
gateway.listenersWK_GATEWAY_LISTENERSobject_listClient listener list: name, network, address, transport, and protocol are required; path and proxy_protocol_trusted_cidrs are optional; direct/PROXY v1/v2 detection is enabled by default, with omitted or empty CIDRs accepting unverified address assertions from any peer; names and addresses must each be unique. Omitted opens WKProto TCP on 0.0.0.0:5100 and WSMux on 0.0.0.0:5200; an explicit empty list (including JSON null in the environment) disables Gateway.
gateway.send_timeoutWK_GATEWAY_SEND_TIMEOUTdurationMaximum duration allowed for one message send initiated by Gateway; a non-positive value uses 5s.

Client addresses behind a proxy

This capability is currently under Unreleased; use a target binary containing proxy_protocol_trusted_cidrs. Older binaries require disabling the PROXY preface at the upstream proxy.

Every TCP or WebSocket listener automatically accepts plain client traffic and PROXY protocol v1/v2 on the same port by default, without SDK changes or a proxy vendor selector. proxy_protocol_trusted_cidrs is an optional source filter. Omitted or empty accepts headers from any peer: connection information and logs can contain client-declared addresses whose authenticity has not been verified. Built-in token authentication and message permissions do not rely on those addresses. To restrict header sources to controlled proxies, configure the filter as follows:

[[gateway.listeners]]
name = "tcp-wkproto"
network = "tcp"
address = "0.0.0.0:5100"
transport = "gnet"
protocol = "wkproto"
# Replace with the actual controlled proxy egress IP/CIDR.
proxy_protocol_trusted_cidrs = ["192.0.2.10/32"]

Use the same field on a network = "websocket" listener. At most 128 IPv4/IPv6 CIDRs are accepted; invalid CIDRs fail configuration loading. WK_GATEWAY_LISTENERS accepts this field inside its JSON listener objects and replaces the entire listener list, including all trust rules.

When setting the filter, match the actual TCP peer as seen by WuKongIM, including any SNAT. Use controlled proxy egress networks. A trusted proxy must prepend its own header on forwarded connections; a transparent TCP relay that passes arbitrary client prefixes through is not a safe trusted source. Listeners with nonempty CIDRs reject recognized PROXY headers from other peers. Direct traffic remains accepted.

The upstream proxy must support and send the protocol; WuKongIM cannot recover an address that it did not receive. Parsing occurs before authentication and, for WebSocket, before HTTP Upgrade. TLS/WSS termination belongs to the upstream proxy; X-Forwarded-For is not used by this feature. It does not change the HTTP API, Manager, cluster RPC, advertised routes, or token authentication.

Detection has an absolute five-second deadline from TCP accept, including clients that send no data. Incomplete, malformed, or oversized headers close the connection. The v1 limit is 107 bytes; v2 permits 4096 bytes including the fixed header and optional TLVs. TLV values are ignored; supported TCP address blocks validate TLV framing. UNKNOWN, LOCAL, and valid unsupported v2 address transports retain the physical endpoints. Sessions use the asserted client source as RemoteAddr, retain the actual listener as LocalAddr, and expose the physical proxy through gateway.peer_addr; connection debug logs include peerAddr when it differs.

Message

TOMLEnvironmentTypeDescription
message.person_whitelist_enabledWK_MESSAGE_PERSON_WHITELIST_ENABLEDboolEnforces receiver-side allowlist checks for person messages; disabled by default for compatibility.
message.cmd_channel_suffixWK_MESSAGE_CMD_CHANNEL_SUFFIXstringReserved command-channel suffix; omitted or empty uses ____cmd. Only ASCII letters, digits, underscores and hyphens are allowed; reserve it from business channel IDs. Must match on every node and requires restart. Choose before first use: changing it does not migrate stored command channels or UID bindings and can make pending commands inaccessible.
message.system_uidWK_MESSAGE_SYSTEM_UIDstringPrimary system account UID used when trusted sends omit a sender; omitted or empty uses ____system. Every cluster node must use the same value.
message.system_device_idWK_MESSAGE_SYSTEM_DEVICE_IDstringDevice ID for trusted system sessions; omitted or empty uses ____device, so an empty value cannot disable recognition. Such sessions may bypass channel-type send permissions after the send-ban check.
message.permission_cache_ttlWK_MESSAGE_PERMISSION_CACHE_TTLdurationCache lifetime for permission, membership, and missing-channel reads; 0 disables caching.

Presence

TOMLEnvironmentTypeDescription
presence.activation_timeoutWK_PRESENCE_ACTIVATION_TIMEOUTdurationTimeout for Gateway session route activation against the UID authority; 0 uses 3s.
presence.touch_flush_intervalWK_PRESENCE_TOUCH_FLUSH_INTERVALdurationInterval for flushing local connection activity to UID authorities; 0 uses 1s.
presence.touch_batch_sizeWK_PRESENCE_TOUCH_BATCH_SIZEintMaximum local touched routes processed per flush chunk; 0 uses 512.
presence.touch_max_routes_per_flushWK_PRESENCE_TOUCH_MAX_ROUTES_PER_FLUSHintMaximum dirty routes processed across all chunks in one flush; omitted uses 65536, while an explicit value must be positive and at least presence.touch_batch_size.
presence.route_ttlWK_PRESENCE_ROUTE_TTLdurationHow long a UID authority keeps a route alive after its latest activity; 0 uses 90s.

Channel Append

TOMLEnvironmentTypeDescription
channel_append.shard_countWK_CHANNEL_APPEND_SHARD_COUNTintShards used to look up Channel append authority state; 0 derives a CPU-aware default.
channel_append.advance_pool_sizeWK_CHANNEL_APPEND_ADVANCE_POOL_SIZEintWorker pool that advances Channel Append Writer state machines; 0 uses the runtime default 500.
channel_append.effect_pool_sizeWK_CHANNEL_APPEND_EFFECT_POOL_SIZEintWorker pool used by blocking appends and post-append recipient processing; 0 uses the runtime default 2000.
channel_append.recipient_authority_dispatch_concurrencyWK_CHANNEL_APPEND_RECIPIENT_AUTHORITY_DISPATCH_CONCURRENCYintDeprecated compatibility input; canonical Online Delivery plans ignore this value.

Delivery

TOMLEnvironmentTypeDescription
delivery.enableWK_DELIVERY_ENABLEboolConnects committed messages to the online-delivery runtime; enabled when omitted.
delivery.fanout_page_sizeWK_DELIVERY_FANOUT_PAGE_SIZEintMaximum subscriber UIDs read in one fanout page; 0 uses 512.
delivery.push_batch_sizeWK_DELIVERY_PUSH_BATCH_SIZEintMaximum recipients in one exact-target lookup, delivery plan, or owner-node push chunk; 0 uses 512.
delivery.pending_ack_ttlWK_DELIVERY_PENDING_ACK_TTLdurationLifetime used to remove stale pending acknowledgements during delivery activity; 0 uses 30s.
delivery.pending_ack_max_per_sessionWK_DELIVERY_PENDING_ACK_MAX_PER_SESSIONintMaximum owner-local pending acknowledgements retained for one UID session; 0 uses 1024.
delivery.event_queue_sizeWK_DELIVERY_EVENT_QUEUE_SIZEintMaximum recipient delivery plans waiting for asynchronous processing; 0 uses 1024.
delivery.recipient_worker_concurrencyWK_DELIVERY_RECIPIENT_WORKER_CONCURRENCYintMaximum workers processing recipient delivery plans; 0 uses 320.

Webhook

TOMLEnvironmentTypeDescription
webhook.http_addrWK_WEBHOOK_HTTP_ADDRstringTarget receiving JSON webhook POST requests; empty disables the webhook runtime. Redacted from diagnostic artifacts.
webhook.focus_eventsWK_WEBHOOK_FOCUS_EVENTSstring_listLimits delivery to these names: msg.notify, msg.offline, or user.onlinestatus; an empty list selects all supported events.
webhook.queue_sizeWK_WEBHOOK_QUEUE_SIZEintMaximum webhook events queued in memory before worker execution; 0 uses 1024.
webhook.workersWK_WEBHOOK_WORKERSintMaximum concurrent webhook sender workers; 0 uses 16.
webhook.msg_notify_batch_max_itemsWK_WEBHOOK_MSG_NOTIFY_BATCH_MAX_ITEMSintMaximum messages in one msg.notify webhook request; 0 uses 100.
webhook.msg_notify_batch_max_waitWK_WEBHOOK_MSG_NOTIFY_BATCH_MAX_WAITdurationMaximum wait to collect adjacent msg.notify messages; 0 uses 500ms.
webhook.online_status_batch_max_itemsWK_WEBHOOK_ONLINE_STATUS_BATCH_MAX_ITEMSintMaximum records in one user.onlinestatus request; 0 uses 512.
webhook.online_status_batch_max_waitWK_WEBHOOK_ONLINE_STATUS_BATCH_MAX_WAITdurationMaximum wait to collect adjacent user.onlinestatus records; 0 uses 2s.
webhook.offline_uid_batch_sizeWK_WEBHOOK_OFFLINE_UID_BATCH_SIZEintMaximum offline UIDs in one msg.offline request; 0 uses 512.
webhook.request_timeoutWK_WEBHOOK_REQUEST_TIMEOUTdurationTimeout for one outbound webhook request attempt; 0 uses 5s.
webhook.retry_max_attemptsWK_WEBHOOK_RETRY_MAX_ATTEMPTSintMaximum attempts for an admitted webhook batch before it is dropped; 0 uses 3.
webhook.before_send.enabledWK_WEBHOOK_BEFORE_SEND_ENABLEDboolIndependently enable synchronous admission; defaults to false.
webhook.before_send.http_addrWK_WEBHOOK_BEFORE_SEND_HTTP_ADDRstringHTTP(S) callback endpoint, required when enabled and redacted in diagnostics.
webhook.before_send.timeoutWK_WEBHOOK_BEFORE_SEND_TIMEOUTdurationCallback deadline; zero uses 500ms, capped by the original send deadline.
webhook.before_send.on_timeoutWK_WEBHOOK_BEFORE_SEND_ON_TIMEOUTstringCallback timeout policy: allow or deny; defaults to deny.
webhook.before_send.on_errorWK_WEBHOOK_BEFORE_SEND_ON_ERRORstringCallback error policy: allow or deny; defaults to deny and never overrides explicit rejection.
webhook.before_send.max_in_flightWK_WEBHOOK_BEFORE_SEND_MAX_IN_FLIGHTintPer-node concurrency limit; zero uses 256, saturation rejects immediately.

Plugin

TOMLEnvironmentTypeDescription
plugin.enableWK_PLUGIN_ENABLEboolEnables node-local .wkp plugin processes and PersistAfter hooks; enabled when omitted.
plugin.dirWK_PLUGIN_DIRstringDirectory containing executable .wkp plugin files; when Plugin is enabled, empty derives it from node.data_dir.
plugin.socket_pathWK_PLUGIN_SOCKET_PATHstringUnix socket used for plugin host RPC; when Plugin is enabled, empty derives it from node.data_dir.
plugin.sandbox_dirWK_PLUGIN_SANDBOX_DIRstringRoot directory for each plugin's writable sandbox data; when Plugin is enabled, empty derives it from node.data_dir.
plugin.state_dirWK_PLUGIN_STATE_DIRstringDirectory containing node-local desired plugin state; when Plugin is enabled, empty derives it from node.data_dir.
plugin.timeoutWK_PLUGIN_TIMEOUTdurationTimeout for plugin host RPC and graceful process shutdown; 0 uses 5s.
plugin.hot_reloadWK_PLUGIN_HOT_RELOADboolWatches the plugin directory and reloads changed binaries; enabled when omitted.
plugin.fail_openWK_PLUGIN_FAIL_OPENboolReserved for future Send hooks; omitted is false, but the current value has no effect and PersistAfter is always fail-open.
plugin.persist_after_queue_sizeWK_PLUGIN_PERSIST_AFTER_QUEUE_SIZEintMaximum PersistAfter events queued in memory; 0 uses 1024.
plugin.persist_after_workersWK_PLUGIN_PERSIST_AFTER_WORKERSintMaximum concurrent PersistAfter hook workers; 0 uses 16.

Log

TOMLEnvironmentTypeDescription
log.levelWK_LOG_LEVELstringMinimum recorded level: debug, info, warn, or error; omitted uses info.
log.dirWK_LOG_DIRstringDirectory for rolling log files; empty uses ./logs.
log.max_sizeWK_LOG_MAX_SIZEintMaximum log-file size before rotation, in MB; values at or below 0 use 100.
log.max_ageWK_LOG_MAX_AGEintMaximum days to retain rotated logs; values at or below 0 use 30.
log.max_backupsWK_LOG_MAX_BACKUPSintMaximum rotated files retained per log; values at or below 0 use 10.
log.compressWK_LOG_COMPRESSboolCompresses rotated log files with gzip; enabled when omitted.
log.consoleWK_LOG_CONSOLEboolAdds a standard-output log sink; enabled when omitted.
log.formatWK_LOG_FORMATstringFile encoder format; json emits structured JSON, while other values use console encoding. Omitted uses console.

Migrating removed environment variables

These legacy variables are no longer accepted. Replace them when upgrading configuration:

RemovedReplacement
WK_CLUSTER_GROUP_COUNTWK_CLUSTER_INITIAL_SLOT_COUNT
WK_CLUSTER_GROUP_REPLICA_NWK_CLUSTER_SLOT_REPLICA_N
WK_CLUSTER_HASH_SLOT_MIGRATION_ENABLEDUse the applicable WK_CHANNEL_MIGRATION_* settings

On this page