# ESP-Hosted Performance Optimization Guide
Quick reference for optimizing ESP-Hosted performance across co-processors and different transport interfaces.
Table of Contents
1. [Quick Start - High Performance Config](#1-quick-start---high-performance-config)
1.1 [ESP32-C6 as Co-Procesor](#11-esp32-c6-as-co-procesor)
1.2 [ESP32-C5 as Co-Processor](#12-esp32-c5-as-co-processor)
1.3 [ESP32-C61 as Co-Processor](#13-esp32-c61-as-co-processor)
1.4 [ESP32-C2 as Co-Processor](#14-esp32-c2-as-co-processor)
1.5 [ESP32-S2 as Co-Processor](#15-esp32-s2-as-co-processor)
1.6 [ESP32-C3 as Co-Processor](#16-esp32-c3-as-co-processor)
2. [Transport Optimization](#2-transport-optimization)
2.1 [SDIO (Highest Performance)](#21-sdio-highest-performance)
2.2 [SPI Full-Duplex](#22-spi-full-duplex)
2.3 [2.3 SPI Half-Duplex](#23-spi-half-duplex)
2.4 [UART (Lowest Performance)](#24-uart-lowest-performance)
3. [Memory Optimization](#3-memory-optimization)
4. [Hardware Guidelines](#4-hardware-guidelines)
4.1 [Critical Requirements](#41-critical-requirements)
4.2 [PCB Design Checklist](#42-pcb-design-checklist)
4.3 [Development Workflow](#43-development-workflow)
## 1 Quick Start - High Performance Config
For immediate performance gains, add these to your host's `sdkconfig.defaults.esp32XX` file based on the co-processor you are using.
> [!NOTE]
> Adjust the values based on your MCU host's and co-processor memory capacity. These values may change when more testing shows better performance figures.
Test conditions for throughput numbers using the performance settings:
- raw: data transferred from sender to receiver over transport
- iPerf used to measure TCP and UDP throughput
A diagram showing the setup used to get the throughput numbers.
```mermaid
flowchart TB
%% floating IP labels — above their boxes, faint leader line
ipAP["192.168.1.1"]:::ip
ipP4["192.168.1.2"]:::ip
ipHost["192.168.1.88 · test
10.0.0.1 · control"]:::ip
ipDev["10.0.0.2"]:::ip
subgraph SB["Shield Box"]
AP["📶 AP / Router"]
subgraph EVB["ESP32-P4-Function-EV-Board 1.2+"]
direction LR
C6["ESP32-C6
Wi-Fi slave"]
P4["ESP32-P4
iperf app"]
C6 ---|"SDIO"| P4
end
AP -.-|"Wi-Fi"| C6
HOST["AP-backend
iperf host"]
AP ===|"LAN cable"| HOST
P4 ---|"USB / UART"| HOST
end
DEV["Dev machine"]
HOST ---|"control"| DEV
%% faint leaders from IP labels to devices
ipAP -.- AP
ipP4 -.- P4
ipHost -.- HOST
ipDev -.- DEV
style SB fill:#fff7ec,stroke:#e8a33d,color:#333
style EVB fill:#efeaf8,stroke:#8a7bbd,color:#333
classDef node fill:#ffffff,stroke:#99aabb,color:#111
classDef ip fill:none,stroke:none,color:#555
class AP,C6,P4,HOST,DEV node
linkStyle 0 stroke:#e8762d,stroke-width:2.5px
linkStyle 1 stroke:#e8762d,stroke-width:2.5px
linkStyle 2 stroke:#e8762d,stroke-width:2.5px
linkStyle 3 stroke:#888888,stroke-width:1.5px,stroke-dasharray:5
linkStyle 4 stroke:#0e9488,stroke-width:2px
linkStyle 5 stroke:#cccccc,stroke-width:1px,stroke-dasharray:2 2
linkStyle 6 stroke:#cccccc,stroke-width:1px,stroke-dasharray:2 2
linkStyle 7 stroke:#cccccc,stroke-width:1px,stroke-dasharray:2 2
linkStyle 8 stroke:#cccccc,stroke-width:1px,stroke-dasharray:2 2
```
> [!NOTE]
> The diagram shows the router and ESP board in a shield box. The performance numbers here were obtained from an 'Open Air' configuration, without using a shield box.
### 1.1 ESP32-C6 as Co-Procesor
```
### sdkconfig for ESP32-P4 + C6 as co-processor
# Let P4 know, C6 is attached as slave
CONFIG_SLAVE_IDF_TARGET_ESP32C6=y
CONFIG_ESP_HOSTED_CP_TARGET_ESP32C6=y
# Wi-Fi Performance
CONFIG_WIFI_RMT_STATIC_RX_BUFFER_NUM=16
CONFIG_WIFI_RMT_DYNAMIC_RX_BUFFER_NUM=64
CONFIG_WIFI_RMT_DYNAMIC_TX_BUFFER_NUM=64
CONFIG_WIFI_RMT_AMPDU_TX_ENABLED=y
CONFIG_WIFI_RMT_TX_BA_WIN=32
CONFIG_WIFI_RMT_AMPDU_RX_ENABLED=y
CONFIG_WIFI_RMT_RX_BA_WIN=32
# TCP/IP Performance
CONFIG_LWIP_TCP_SND_BUF_DEFAULT=65534
CONFIG_LWIP_TCP_WND_DEFAULT=65534
CONFIG_LWIP_TCP_RECVMBOX_SIZE=64
CONFIG_LWIP_UDP_RECVMBOX_SIZE=64
CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=64
CONFIG_LWIP_TCP_SACK_OUT=y
```
**Throughput using the settings.**
Using SDIO Transport, 4-bits, running at 40MHz, connected to a 2.4GHz network over the air
| Type | Direction | MBits/s |
|------------|---------------|--------:|
| Raw | P4 to C6 | 72 |
| Raw | C6 to P4 | 80 |
| iPerf, TCP | P4 to Test PC | 32 |
| iPerf, UDP | P4 to Test PC | 50 |
| iPerf, TCP | Test PC to P4 | 30 |
| iPerf, UDP | Test PC to P4 | 49 |
### 1.2 ESP32-C5 as Co-Processor
```
### sdkconfig for ESP32-P4 + C5 as co-processor
# Let P4 know, C5 is attached as slave
CONFIG_SLAVE_IDF_TARGET_ESP32C5=y
CONFIG_ESP_HOSTED_CP_TARGET_ESP32C5=y
# Optional PCB selection: Uncomment if you are using Pre designed PCB P4_C5_CORE_BOARD (to use correct GPIOs on that PCB)
# CONFIG_ESP_HOSTED_P4_C5_CORE_BOARD=y
# Wi-Fi Performance
CONFIG_WIFI_RMT_STATIC_RX_BUFFER_NUM=10
CONFIG_WIFI_RMT_DYNAMIC_RX_BUFFER_NUM=32
CONFIG_WIFI_RMT_DYNAMIC_TX_BUFFER_NUM=32
CONFIG_WIFI_RMT_AMPDU_TX_ENABLED=y
CONFIG_WIFI_RMT_TX_BA_WIN=32
CONFIG_WIFI_RMT_AMPDU_RX_ENABLED=y
CONFIG_WIFI_RMT_RX_BA_WIN=16
# TCP/IP Performance
CONFIG_LWIP_TCP_SND_BUF_DEFAULT=11520
CONFIG_LWIP_TCP_WND_DEFAULT=32768
CONFIG_LWIP_TCP_RECVMBOX_SIZE=48
CONFIG_LWIP_UDP_RECVMBOX_SIZE=48
CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=48
CONFIG_LWIP_TCP_SACK_OUT=y
```
**Throughput using the settings.**
Using SDIO Transport, 4-bits, running at 40MHz, connected to a 5GHz network over the air
| Type | Direction | MBits/s |
|------------|---------------|--------:|
| Raw | P4 to C5 | 72 |
| Raw | C5 to P4 | 81 |
| iPerf, TCP | P4 to Test PC | 23 |
| iPerf, UDP | P4 to Test PC | 67 |
| iPerf, TCP | Test PC to P4 | 32 |
| iPerf, UDP | Test PC to P4 | 68 |
### 1.3 ESP32-C61 as Co-Processor
```
### sdkconfig for ESP32-P4 + C61 as co-processor
# Let P4 know, C61 is attached as slave
CONFIG_SLAVE_IDF_TARGET_ESP32C61=y
CONFIG_ESP_HOSTED_CP_TARGET_ESP32C61=y
# Optional PCB selection: Uncomment if you are using Pre designed PCB P4_C61_CORE_BOARD (to use correct GPIOs on that PCB)
# CONFIG_ESP_HOSTED_P4_C61_CORE_BOARD=y
# Wi-Fi Performance
CONFIG_WIFI_RMT_STATIC_RX_BUFFER_NUM=10
CONFIG_WIFI_RMT_DYNAMIC_RX_BUFFER_NUM=16
CONFIG_WIFI_RMT_DYNAMIC_TX_BUFFER_NUM=16
CONFIG_WIFI_RMT_AMPDU_TX_ENABLED=y
CONFIG_WIFI_RMT_TX_BA_WIN=16
CONFIG_WIFI_RMT_AMPDU_RX_ENABLED=y
CONFIG_WIFI_RMT_RX_BA_WIN=16
# TCP/IP Performance
CONFIG_LWIP_TCP_SND_BUF_DEFAULT=12930
CONFIG_LWIP_TCP_WND_DEFAULT=22488
CONFIG_LWIP_TCP_RECVMBOX_SIZE=48
CONFIG_LWIP_UDP_RECVMBOX_SIZE=64
CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=48
CONFIG_LWIP_IP_REASS_MAX_PBUFS=15
CONFIG_LWIP_TCP_SACK_OUT=y
CONFIG_LWIP_TCPIP_CORE_LOCKING=y
CONFIG_LWIP_TCPIP_CORE_LOCKING_INPUT=y
```
**Throughput using the settings.**
Using SPI-FD Transport, running at 40MHz, connected to a 2.4GHz network over the air
| Type | Direction | MBits/s |
|------------|---------------|--------:|
| Raw | P4 to C61 | 25 |
| Raw | C61 to P4 | 26 |
| iPerf, TCP | P4 to Test PC | 12 |
| iPerf, UDP | P4 to Test PC | 18 |
| iPerf, TCP | Test PC to P4 | 15 |
| iPerf, UDP | Test PC to P4 | 23 |
### 1.4 ESP32-C2 as Co-Processor
```
# Let P4 know, C2 is attached as slave
CONFIG_SLAVE_IDF_TARGET_ESP32C2=y
CONFIG_ESP_HOSTED_CP_TARGET_ESP32C2=y
### sdkconfig for ESP32-P4 + C2 as co-processor
# Wi-Fi Performance
CONFIG_WIFI_RMT_STATIC_RX_BUFFER_NUM=10
CONFIG_WIFI_RMT_DYNAMIC_RX_BUFFER_NUM=32
CONFIG_WIFI_RMT_DYNAMIC_TX_BUFFER_NUM=32
CONFIG_WIFI_RMT_AMPDU_TX_ENABLED=y
CONFIG_WIFI_RMT_TX_BA_WIN=6
CONFIG_WIFI_RMT_AMPDU_RX_ENABLED=y
CONFIG_WIFI_RMT_RX_BA_WIN=6
# TCP/IP Performance
CONFIG_LWIP_TCP_SND_BUF_DEFAULT=16384
CONFIG_LWIP_TCP_WND_DEFAULT=32768
CONFIG_LWIP_TCP_RECVMBOX_SIZE=20
CONFIG_LWIP_UDP_RECVMBOX_SIZE=20
CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=20
CONFIG_LWIP_TCP_SACK_OUT=y
```
**Throughput using the settings.**
Using SPI-FD Transport, running at 40MHz, connected to a 2.4GHz network over the air
| Type | Direction | MBits/s |
|------------|---------------|--------:|
| Raw | P4 to C2 | 25 |
| Raw | C2 to P4 | 26 |
| iPerf, TCP | P4 to Test PC | 12 |
| iPerf, UDP | P4 to Test PC | 18 |
| iPerf, TCP | Test PC to P4 | 13 |
| iPerf, UDP | Test PC to P4 | 15 |
### 1.5 ESP32-S2 as Co-Processor
```
### sdkconfig for ESP32-P4 + S2 as co-processor
# Let P4 know, S2 is attached as slave
CONFIG_SLAVE_IDF_TARGET_ESP32S2=y
CONFIG_ESP_HOSTED_CP_TARGET_ESP32S2=y
# Wi-Fi Performance
CONFIG_WIFI_RMT_STATIC_RX_BUFFER_NUM=8
CONFIG_WIFI_RMT_DYNAMIC_RX_BUFFER_NUM=24
CONFIG_WIFI_RMT_DYNAMIC_TX_BUFFER_NUM=24
CONFIG_WIFI_RMT_AMPDU_TX_ENABLED=y
CONFIG_WIFI_RMT_TX_BA_WIN=16
CONFIG_WIFI_RMT_AMPDU_RX_ENABLED=y
CONFIG_WIFI_RMT_RX_BA_WIN=16
# TCP/IP Performance
CONFIG_LWIP_TCP_SND_BUF_DEFAULT=17280
CONFIG_LWIP_TCP_WND_DEFAULT=28000
CONFIG_LWIP_TCP_RECVMBOX_SIZE=32
CONFIG_LWIP_UDP_RECVMBOX_SIZE=32
CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=32
CONFIG_LWIP_TCP_SACK_OUT=y
```
### 1.6 ESP32-C3 as Co-Processor
```
### sdkconfig for ESP32-P4 + C3 as co-processor
# Let P4 know, C3 is attached as slave
CONFIG_SLAVE_IDF_TARGET_ESP32C3=y
CONFIG_ESP_HOSTED_CP_TARGET_ESP32C3=y
# Wi-Fi Performance
CONFIG_WIFI_RMT_STATIC_RX_BUFFER_NUM=20
CONFIG_WIFI_RMT_DYNAMIC_RX_BUFFER_NUM=40
CONFIG_WIFI_RMT_DYNAMIC_TX_BUFFER_NUM=40
CONFIG_WIFI_RMT_AMPDU_TX_ENABLED=y
CONFIG_WIFI_RMT_TX_BA_WIN=32
CONFIG_WIFI_RMT_AMPDU_RX_ENABLED=y
CONFIG_WIFI_RMT_RX_BA_WIN=32
# TCP/IP Performance
CONFIG_LWIP_TCP_SND_BUF_DEFAULT=40960
CONFIG_LWIP_TCP_WND_DEFAULT=40960
CONFIG_LWIP_TCP_RECVMBOX_SIZE=64
CONFIG_LWIP_UDP_RECVMBOX_SIZE=64
CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=64
```
**Throughput using the settings.**
Using SPI-FD Transport, running at 40MHz, connected to a 2.4GHz network over the air
| Type | Direction | MBits/s |
|------------|---------------|--------:|
| Raw | P4 to C3 | 26 |
| Raw | C3 to P4 | 26 |
| iPerf, TCP | P4 to Test PC | 19 |
| iPerf, UDP | P4 to Test PC | 25 |
| iPerf, TCP | Test PC to P4 | 18 |
| iPerf, UDP | Test PC to P4 | 20 |
**Throughput using the settings.**
Using SPI-FD Transport, running at 40MHz, connected to a 2.4GHz network over the air
| Type | Direction | MBits/s |
|------------|---------------|--------:|
| Raw | P4 to S2 | 25 |
| Raw | S2 to P4 | 26 |
| iPerf, TCP | P4 to Test PC | 8 |
| iPerf, UDP | P4 to Test PC | 11 |
| iPerf, TCP | Test PC to P4 | 12 |
| iPerf, UDP | Test PC to P4 | 15 |
## 2 Transport Optimization
### 2.1 SDIO (Highest Performance)
- **Clock Speed**: Start at 20 MHz, optimize up to 50 MHz
- **Bus Width**: Use 4-bit mode
- **Hardware**: Use PCB with controlled impedance, external pull-ups (51kΩ)
- **Checksum**: Optional (SDIO hardware handles verification)
```
CONFIG_ESP_HOSTED_SDIO_CLOCK_FREQ_KHZ=40000
CONFIG_ESP_HOSTED_SDIO_BUS_WIDTH=4
```
> [!NOTE]
> See [Performance and Memory Usage](sdio.md#9-performance-and-memory-usage) on the trade-off between SDIO Performance and Memory Use
### 2.2 SPI Full-Duplex
- **Clock Speed**: ESP32: ≤10 MHz, Others: ≤40 MHz
- **Hardware**: Use IO_MUX pins, short traces (≤10cm for jumpers)
- **Checksum**: Mandatory (SPI hardware lacks error detection)
```
CONFIG_ESP_HOSTED_SPI_CLK_FREQ=40
```
### 2.3 SPI Half-Duplex
- **Data Lines**: Use 4-line (Quad SPI) mode
- **Similar optimizations as SPI Full-Duplex**
### 2.4 UART (Lowest Performance)
- **Baud Rate**: Use 921600 (highest stable rate)
- **Best for**: Low-throughput applications, debugging
## 3 Memory Optimization
- Reduce memory footprint for resource-constrained applications:
```
# Reduce queue sizes
CONFIG_ESP_HOSTED_SDIO_TX_Q_SIZE=10 # Default: 20
CONFIG_ESP_HOSTED_SDIO_RX_Q_SIZE=10 # Default: 20
# Enable memory pooling
CONFIG_ESP_HOSTED_USE_MEMPOOL=y
```
- Disable the not-in-use features
- For example, disable bluetooth if not needed
- Use external RAM, for higher memory (PSRAM is supported)
- Optimise internal RAM using [ESP-IDF iram optimization tricks](https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-guides/performance/ram-usage.html)
## 4 Hardware Guidelines
### 4.1 Critical Requirements
1. **Signal Integrity**: Use PCB designs for production, jumpers only for prototyping
2. **Power Supply**: Stable 3.3V, proper decoupling capacitors
3. **Trace Length**: Match lengths, especially clock vs data lines
4. **Pull-ups**: Required for SDIO (51kΩ) on CMD, D0-D3 lines
### 4.2 PCB Design Checklist
- [ ] Equal trace lengths for communication signals
- [ ] Ground plane for signal stability
- [ ] Controlled impedance traces (50Ω typical)
- [ ] Series termination resistors for high-speed signals
- [ ] Extra GPIOs reserved for future features (deep sleep, etc.)
### 4.3 Development Workflow
1. **Proof of Concept**: Start with jumper wires, low clock speeds
2. **Incremental Optimization**: Increase transport clock step by step
3. **Hardware Validation**: Move to PCB for final validation
4. **Performance Tuning**: Optimize buffers and configurations
5. **Disable features**: Any unused components from ESP-IDF or
ESP-Hosted-MCU features could be disabled for more memory
availability.