[api] Increase log Nagle coalescing on ESP32 and RP2040

Increase LOG_NAGLE_COUNT from 2 to 3 on ESP32 and RP2040, which have
larger TCP send buffers (64KB and 11.7KB respectively). This coalesces
4 log messages per Nagle cycle instead of 3, reducing the number of
individual write() calls and significantly reducing EWOULDBLOCK hits
on the log subscriber connection.

Tested on ESP32 and RP2040: buffered writes dropped from ~15% to near
zero with this change. ESP8266 and LibreTiny remain at LOG_NAGLE_COUNT=2
due to tighter buffer constraints.
This commit is contained in:
J. Nick Koston
2026-03-12 16:48:07 -10:00
parent 920af91db6
commit c04335d21d
+16 -6
View File
@@ -134,12 +134,16 @@ class APIFrameHelper {
//
// For log messages: Use Nagle to coalesce multiple small log packets into
// fewer larger packets, reducing WiFi overhead. However, we limit batching
// to 3 messages to avoid excessive LWIP buffer pressure on memory-constrained
// devices like ESP8266. LWIP's TCP_OVERSIZE option coalesces the data into
// shared pbufs, but holding data too long waiting for Nagle's timer causes
// buffer exhaustion and dropped messages.
// to avoid excessive LWIP buffer pressure on memory-constrained devices.
// LWIP's TCP_OVERSIZE option coalesces the data into shared pbufs, but
// holding data too long waiting for Nagle's timer causes buffer exhaustion
// and dropped messages.
//
// Flow: Log 1 (Nagle on) -> Log 2 (Nagle on) -> Log 3 (NODELAY, flush all)
// ESP32 (TCP_SND_BUF=64KB) / RP2040 (8×MSS): 4 logs per cycle
// ESP8266 / LibreTiny: 3 logs per cycle (tighter buffers)
//
// Flow (ESP32/RP2040): Log 1 (Nagle on) -> Log 2 -> Log 3 -> Log 4 (NODELAY, flush)
// Flow (other): Log 1 (Nagle on) -> Log 2 -> Log 3 (NODELAY, flush all)
//
void set_nodelay_for_message(bool is_log_message) {
if (!is_log_message) {
@@ -255,10 +259,16 @@ class APIFrameHelper {
uint8_t tx_buf_tail_{0};
uint8_t tx_buf_count_{0};
// Nagle batching state for log messages. NODELAY_ON (-1) means NODELAY is enabled
// (immediate send). Values 1-2 count log messages in the current Nagle batch.
// (immediate send). Values 1..LOG_NAGLE_COUNT count log messages in the current Nagle batch.
// After LOG_NAGLE_COUNT logs, we switch to NODELAY to flush and reset.
// ESP32 and RP2040 have larger TCP send buffers and can coalesce more;
// ESP8266 and LibreTiny have tighter buffers.
static constexpr int8_t NODELAY_ON = -1;
#if defined(USE_ESP32) || defined(USE_RP2040)
static constexpr int8_t LOG_NAGLE_COUNT = 3;
#else
static constexpr int8_t LOG_NAGLE_COUNT = 2;
#endif
int8_t nodelay_state_{NODELAY_ON};
// Internal helper to set TCP_NODELAY socket option