wake_loop Moved from Socket Component into Core
wake_loop_threadsafe() and related wake primitives have moved from the socket component into core. The require_wake_loop_threadsafe() opt-in is deprecated (now a no-op) — wake works unconditionally on all platforms.
This is a breaking change for external components in ESPHome 2026.4.0 and later.
Background
PR #15446: Move wake_loop out of socket component into core
The wake mechanism originally lived in the socket component because the first implementation used a UDP loopback socket. Since then, every platform has moved to nearly-free primitives (FreeRTOS task notifications, esp_schedule(), ARM __sev()), and the socket dependency was unnecessary complexity: 12 components needed to call require_wake_loop_threadsafe(), #ifdef USE_WAKE_LOOP_THREADSAFE guards were needed at every call site, and platforms without networking had silent degradation (up to ~16ms latency).
Now it just works — no opt-in, no defines, no guards.
Platform wake mechanisms
| Platform | Mechanism |
|---|---|
| ESP32 | FreeRTOS task notifications (ISR-safe) |
| LibreTiny | FreeRTOS task notifications |
| ESP8266 | esp_schedule() (IRAM-safe) |
| RP2040 | __sev() / __wfe() (ARM CPU instructions) |
| Host | UDP loopback socket + select() |
What's Changing
Removed defines
USE_WAKE_LOOP_THREADSAFE— no longer needed, wake is always availableUSE_SOCKET_SELECT_SUPPORT— replaced byUSE_HOSTwhere needed
Deprecated Python function
socket.require_wake_loop_threadsafe() (Python codegen helper) is deprecated (warns, no-op). Remove calls to it.
No more #ifdef guards
// Before
#if defined(USE_SOCKET_SELECT_SUPPORT) && defined(USE_WAKE_LOOP_THREADSAFE)
App.wake_loop_threadsafe();
#endif
// After
App.wake_loop_threadsafe();
Socket dependency no longer needed for wake
Components no longer need to declare socket as a dependency just for wake functionality:
# Before
AUTO_LOAD = ["socket"] # just for wake_loop
# After — remove if socket was only needed for wake
# AUTO_LOAD = []
Who This Affects
- External components calling
socket.require_wake_loop_threadsafe()in Python codegen — remove the call - External components using
#ifdef USE_WAKE_LOOP_THREADSAFE— remove the guard - External components with socket in
AUTO_LOADonly for wake — remove it - External components checking
USE_SOCKET_SELECT_SUPPORT— useUSE_HOSTinstead
Migration Guide
C++ — remove #ifdef guards
// Before
void some_background_thread() {
#if defined(USE_SOCKET_SELECT_SUPPORT) && defined(USE_WAKE_LOOP_THREADSAFE)
App.wake_loop_threadsafe();
#endif
}
// After
void some_background_thread() {
App.wake_loop_threadsafe();
}
Python codegen — remove opt-in call and socket AUTO_LOAD
# Before
from esphome.components import socket
AUTO_LOAD = ["socket"]
async def to_code(config):
socket.require_wake_loop_threadsafe()
# ... rest of codegen
# After — remove socket AUTO_LOAD and require call
async def to_code(config):
# ... rest of codegen (no wake opt-in needed)
Timeline
- ESPHome 2026.4.0 (April 2026): Wake moved to core,
require_wake_loop_threadsafe()deprecated USE_WAKE_LOOP_THREADSAFEandUSE_SOCKET_SELECT_SUPPORTdefines removed immediately
Finding Code That Needs Updates
# Find require_wake_loop_threadsafe calls
grep -rn 'require_wake_loop_threadsafe' your_component/
# Find #ifdef guards
grep -rn 'USE_WAKE_LOOP_THREADSAFE' your_component/
# Find USE_SOCKET_SELECT_SUPPORT
grep -rn 'USE_SOCKET_SELECT_SUPPORT' your_component/
Questions?
If you have questions about migrating your external component, please ask in:
- ESPHome Discord - #devs channel
- ESPHome GitHub Discussions
Related Documentation
Comments
Feel free to leave a comment here to discuss this post wth others. You can ask questions, share your experience, or suggest improvements. If you have a question about a specific feature or issue, please consider using the ESPHome Discord. Stick to English and follow ESPHome's code of conduct. These comments exist on a discussion on GitHub, so you can also comment there directly if you prefer.