Mesh-NOW is configured through compile-time tokens and runtime API calls. Runtime-tunable values (beacon interval, retry and ACK timings, peer expiry) are Kconfig options under the Mesh-NOW menu, exposed through idf.py menuconfig as CONFIG_MESH_NOW_*. Structural limits that affect the wire format or ABI are hard #defines in mesh_now.h.

Compile-Time Constants

Constant Default Defined Description
CONFIG_MESH_NOW_BEACON_INTERVAL_MS 5000 Kconfig Beacon broadcast interval (ms)
CONFIG_MESH_NOW_RETRANSMIT_TIMEOUT_MS 2000 Kconfig Retransmit timeout (ms)
CONFIG_MESH_NOW_MAX_RETRIES 3 Kconfig Maximum retransmission attempts
CONFIG_MESH_NOW_MAX_PENDING_MESSAGES 16 Kconfig Pending message table size
CONFIG_MESH_NOW_MAX_SEEN_MESSAGE_IDS 128 Kconfig Duplicate detection buffer size
CONFIG_MESH_NOW_DEFAULT_ROUTE_TTL 3 Kconfig Default hop limit for messages
CONFIG_MESH_NOW_PEER_EXPIRY_SEC 30 Kconfig Seconds without contact before a peer is expired and compacted out of the active table
CONFIG_MESH_NOW_WIFI_CHANNEL 1 Kconfig 802.11 channel all mesh nodes must share
CONFIG_MESH_NOW_MAX_ROUTES 32 Kconfig Route table size (virtual peers)
CONFIG_MESH_NOW_ROUTE_LIFETIME_SEC 30 Kconfig Seconds an unused route stays valid
CONFIG_MESH_NOW_ROUTE_REQ_TTL 8 Kconfig Hop limit of RREQ discovery floods
CONFIG_MESH_NOW_ROUTE_REQ_TIMEOUT_MS 3000 Kconfig Timeout before an RREQ is retried or dropped
CONFIG_MESH_NOW_MAX_ROUTE_REQ_RETRIES 3 Kconfig RREQ re-broadcasts before giving up
CONFIG_MESH_NOW_MAX_ROUTE_REQUESTS 8 Kconfig Simultaneous in-flight route requests
CONFIG_MESH_NOW_RREQ_CACHE_SIZE 32 Kconfig RREQ dedup cache entries
CONFIG_MESH_NOW_MAX_BEACON_NEIGHBORS 8 Kconfig One-hop peers advertised per beacon
MAX_MESH_MESSAGE_LEN 128 mesh_now.h Maximum payload length in bytes
MAX_PEERS 20 mesh_now.h Maximum number of tracked peers (one-hop)
MAX_ENCRYPTION_KEY 16 mesh_now_internal.h Encryption key length (bytes)

FreeRTOS Task Configuration

Parameter Value
Beacon task stack 8192 bytes
Retransmit task stack 8192 bytes
Task priority 5
Core affinity Core 0

Runtime Settings

Encryption Key

// Set at any time after init. The key must be exactly 16 bytes (AES-128).
uint8_t key[16] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
                   0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10};
mesh_now_set_encryption_key(key, sizeof(key));

Group Membership

// Set at any time after init
mesh_now_set_group(42);

Receive Callback

// Set at any time after init
mesh_now_set_receive_callback(my_callback);

Peer Management

// Optional: peers are auto-discovered via beacons
mesh_now_add_peer(mac);
mesh_now_remove_peer(mac);

Tuning Guide

All of these are Kconfig options, set in idf.py menuconfig under the Mesh-NOW menu (or via sdkconfig.defaults).

Increase Range (Higher Hop Limit)

CONFIG_MESH_NOW_DEFAULT_ROUTE_TTL=5   # 5 hops instead of 3
Trade-off

A higher hop limit reaches farther but costs airtime. Every hop re-broadcasts the message to all neighbors.

Reduce Latency (Faster Beacons)

CONFIG_MESH_NOW_BEACON_INTERVAL_MS=2000   # Beacon every 2 seconds

Faster beacons mean quicker peer discovery at the cost of more airtime.

Increase Capacity (More Peers)

MAX_PEERS is a compile-time #define in mesh_now.h:

#define MAX_PEERS 40  // Track up to 40 peers

Each peer entry uses ~32 bytes of RAM (address, activity flag, 8-byte timestamp, name). 40 peers use ~1280 bytes.

Increase Reliability (More Retries)

CONFIG_MESH_NOW_MAX_RETRIES=5   # 5 retries instead of 3

Increase Throughput (Larger Payload)

ESP-NOW Limit

ESP-NOW frames cap at 250 bytes. A max-length 128-byte payload already encodes to 170 bytes on the wire, 198 when encrypted (32-byte header included). Encryption always adds 28 bytes (12-byte nonce plus 16-byte auth tag). Raising MAX_MESH_MESSAGE_LEN much past 180 pushes encrypted frames over the cap; treat the library as tuned for short chat frames, not bulk transfer.

Platform-Specific Configs

Each ESP32 variant has optimized sdkconfig defaults in the chat app example:

Target Config File Key Differences
ESP32 sdkconfig.defaults.esp32 Dual-core, 520KB RAM
ESP32-S2 sdkconfig.defaults.esp32s2 Single-core, 320KB RAM
ESP32-S3 sdkconfig.defaults.esp32s3 Dual-core, PSRAM support
ESP32-C3 sdkconfig.defaults.esp32c3 RISC-V, BLE support
ESP32-C6 sdkconfig.defaults.esp32c6 RISC-V, 802.15.4 support

Next Steps