ESP-IDF ships two Bluetooth host stacks on top of the same controller:
| ESP-NimBLE | ESP-Bluedroid | |
|---|---|---|
| Bluetooth LE | yes | yes |
| Bluetooth Classic (A2DP, SPP, HFP, ...) | no | yes |
| Memory use (heap and flash) | smaller | larger |
| Default in ESP-IDF | no | yes |
Recommendation
- BLE-only device (sensor, gateway, provisioning over BLE): switch to NimBLE. The saved heap is often what makes Wi-Fi + BLE + TLS fit on a chip without PSRAM.
- Needs Classic (audio, serial port profile to legacy devices): Bluedroid.
Switching
idf.py menuconfig
Component config → Bluetooth → Host → NimBLE - BLE only
The APIs differ (NimBLE uses the upstream NimBLE host API, Bluedroid the esp_gap_ble_* / esp_gatts_* APIs), so switching means porting your GATT and GAP code. Start from the ESP-IDF NimBLE examples (e.g. the peripheral and central examples) rather than converting line by line.
Measure, don't guess
Record free heap (esp_get_free_heap_size() / heap_caps_get_free_size()) after Wi-Fi, BLE and TLS are all up, with each stack, on your real configuration. Numbers vary a lot with enabled features (number of connections, bonding storage, logging).