Hello,
I am experiencing severe and repeatable asymmetric Wi-Fi packet loss with Seeed Studio XIAO ESP32-S3 boards.
The ESP32-S3 receives UDP packets from my Linux PC reliably, but a large percentage of packets transmitted from the ESP32-S3 to the PC are lost.
A Seeed Studio XIAO ESP32-C6 tested with the same UDP test achieved 0% packet loss in both directions.
Hardware and software
- Board: Seeed Studio XIAO ESP32-S3
- Comparison board: Seeed Studio XIAO ESP32-C6
- Computer: Linux PC
- Wi-Fi network: 2.4 GHz home router
- Arduino networking API:
WiFiandNetworkUDP - Wi-Fi mode: station mode
- Wi-Fi sleep: disabled with
WiFi.setSleep(false) - RSSI: about -48-50 dBm
- Wi-Fi channel: channel 6
- Distance from router: 2m
- Number of XIAO ESP32-S3 boards tested: 6 XIAO ESP32 S3
Test method
I use two independent numbered UDP streams.
XIAO ESP32-S3 to PC
The ESP32-S3 sends one small UDP report every second.
Each report contains:
tx_sequence rx_count rx_last_sequence tx_failures last_error
The PC checks the ESP32 sequence numbers to detect missing packets.
PC to XIAO ESP32-S3
The Linux PC sends one numbered UDP packet every 100 ms.
The ESP32-S3 counts received packets and includes that count in its outgoing reports.
Test timing
Each normal test includes:
- 60 seconds of bidirectional UDP traffic
- 10 additional seconds receiving ESP32 reports after PC transmission stops
The drain period allows the final ESP32 receive counter to reach the PC and avoids falsely counting packets near the end of the test as lost.
Main symptom
The packet loss is strongly asymmetric.
| Direction | Typical result |
|---|---|
| XIAO ESP32-S3 to PC | Approximately 50% to 75% loss |
| PC to XIAO ESP32-S3 | Usually 0% to 1% loss |
| ESP32 local UDP send failures | Usually 0 |
The packet rate is extremely low, so this does not appear to be UDP buffer overload or a throughput limitation.
Example result 1
=== device -> PC (ESP32 transmit path) ===
sequence span: 32..101 (70 attempts)
unique packets received by PC: 31
missing packets: 39
overall device -> PC loss: 55.7%
rejected locally by ESP32 sendto(): 0
accepted by ESP32 network stack: 70
loss after local socket acceptance: 55.7%
=== PC -> device (ESP32 receive path) ===
PC send attempts: 601
PC sendto() successes: 601
PC sendto() errors: 0
device received after baseline: 598
PC -> device missing packets: 3
PC -> device loss: 0.5%
Example result 2
=== device -> PC (ESP32 transmit path) ===
sequence span: 10..79 (70 attempts)
unique packets received by PC: 27
missing packets: 43
overall device -> PC loss: 61.4%
rejected locally by ESP32 sendto(): 0
accepted by ESP32 network stack: 70
loss after local socket acceptance: 61.4%
=== PC -> device (ESP32 receive path) ===
PC send attempts: 601
PC sendto() successes: 601
PC sendto() errors: 0
device received after baseline: 601
PC -> device missing packets: 0
PC -> device loss: 0.0%
Repeated 60-second results
| Test | ESP32-S3 to PC loss | PC to ESP32-S3 loss |
|---|---|---|
| 1 | 55.7% | 0.5% |
| 2 | 61.4% | 0.0% |
| 3 | 78.0% | 18.3% |
| 4 | 36.2% | 0.0% |
| 5 | 70.6% | 0.0% |
| 6 | 63.6% | 0.0% |
| 7 | 77.3% | 0.0% |
| 8 | 67.6% | 0.3% |
| 9 | 54.4% | 5.2% |
| 10 | 67.2% | 0.2% |
| 11 | 53.1% | 1.2% |
| 12 | 64.3% | 0.0% |
| 13 | 63.8% | 0.0% |
The ESP32-S3 transmit direction is consistently much worse than its receive direction.
600-second test
I also ran a longer test to rule out short-test timing effects.
=== device -> PC (ESP32 transmit path) ===
sequence span: 469..1076 (608 attempts)
unique packets received by PC: 238
missing packets: 370
overall device -> PC loss: 60.9%
rejected locally by ESP32 sendto(): 0
accepted by ESP32 network stack: 608
loss after local socket acceptance: 60.9%
=== PC -> device (ESP32 receive path) ===
PC send attempts: 6001
PC sendto() successes: 6001
PC sendto() errors: 0
device received after baseline: 5773
PC -> device missing packets: 228
PC -> device loss: 3.8%
The long test confirms that the problem is persistent.
XIAO ESP32-C6 control test
I ran the same bidirectional UDP test with a Seeed Studio XIAO ESP32-C6.
=== device -> PC (ESP32 transmit path) ===
sequence span: 66..135 (70 attempts)
unique packets received by PC: 70
missing packets: 0
overall device -> PC loss: 0.0%
rejected locally by ESP32 sendto(): 0
accepted by ESP32 network stack: 70
loss after local socket acceptance: 0.0%
=== PC -> device (ESP32 receive path) ===
PC send attempts: 601
PC sendto() successes: 601
PC sendto() errors: 0
device received after baseline: 601
PC -> device missing packets: 0
PC -> device loss: 0.0%
The C6 result was:
- XIAO ESP32-C6 to PC: 0.0% loss
- PC to XIAO ESP32-C6: 0.0% loss
- Local UDP send failures: 0
This control test indicates that:
- the Python measurement script works;
- the Linux PC can receive UDP correctly;
- the PC firewall is not generally blocking this traffic;
- the packet rate is not too high;
- the problem appears to be specific to the XIAO ESP32-S3, its external antenna/RF path, or its Wi-Fi configuration.
Important observation about local send failures
The ESP32-S3 usually reports zero local UDP send failures.
This means that NetworkUDP.endPacket() or sendto() accepted the packet locally. I understand that this does not guarantee successful over-the-air delivery.
The loss could therefore occur in:
- the ESP32-S3 Wi-Fi driver;
- the RF transmit path;
- the external antenna or U.FL/I-PEX connector;
- 802.11 transmission and retries;
- access-point forwarding.
Because the PC-to-ESP32 direction is usually almost lossless, the problem appears to be mainly associated with the ESP32-S3 transmit direction.
Troubleshooting already performed
- Disabled Wi-Fi sleep with
WiFi.setSleep(false) - Used very small UDP packets
- Reduced the ESP32-S3 transmission rate to one packet per second
- Added sequence numbers in both directions
- Added a 10-second drain period
- Recorded local UDP send failures
- Repeated the test many times
- Ran a 600-second test
- Tested a XIAO ESP32-C6 as a control
- Confirmed that the C6 has 0% loss using the same test method
- Used the Arduino
WiFiandNetworkUDPAPIs - Confirmed that the external antenna is connected
Questions
- Is severe asymmetric packet loss a known issue on some XIAO ESP32-S3 boards?
- Has Seeed reproduced cases where the S3 receives normally but transmits very poorly?
- Is there a recommended transmit-power setting for the XIAO ESP32-S3?
- Should I test lower power settings such as 8.5, 11, 13, or 15 dBm?
- Can a damaged, poorly connected, or poorly matched antenna cause good reception but severe transmission loss?
- Are there specific Arduino-ESP32 Core versions recommended for this board?
- Are there known production batches with RF or antenna-connector problems?
- Would these results be sufficient to consider the board defective and request a replacement?
I can provide:
- the complete Arduino sketch;
- the Python UDP test script;
- complete test logs;
- RSSI and channel information;
- photographs of the antenna connector;
- results from multiple antennas or additional XIAO ESP32-S3 boards.
Thank you in advance.
Andy