ESPHome 2026.2.0: Faster builds, leaner runtime

Release Overview
Section titled “Release Overview”ESPHome 2026.2.0 is a performance and stability release. The focus is on making your devices compile faster, run leaner, and stay reliable over months of uptime.
Faster builds, smaller firmware. ESP32 Arduino builds compile 36% faster and produce 44% less flash and 50% less static RAM. ESP-IDF compiles are ~22% faster. A streamlined certificate bundle saves another 51KB of flash.
More stable, more responsive devices. CPU usage is down across the board: the BLE tracker loop uses ~85% less CPU, MQTT consolidation saves ~6.5% total device CPU, and the scheduler is 25% smaller. Unnecessary memory allocations have been eliminated from dozens of components, and ESP8266 devices recover significant RAM by moving strings to flash.
This release also introduces 3 new components (DLMS smart meter, CH423 I/O expander, SY6970 battery management), adds 7 new display models including ESP32-P4 Waveshare panels, expands the Zigbee platform, and hardens security with constant-time authentication and cryptographic random generation.
Upgrade Checklist
Section titled “Upgrade Checklist”- If you use
bmp581, update your configuration to usebmp581_i2cas the platform - If you use
on_openin cover automations, rename it toon_opened - If you have DSMR
fw_core_versionorfw_module_versionundersensor:, move them totext_sensor: - If you call Arduino library APIs directly in lambdas (e.g.,
Preferences,WiFi), add them toesphome: libraries: - If you connect to HTTPS servers using uncommon CAs, add
use_full_certificate_bundle: trueunderesp32: framework: advanced: - If you use BL0942 sensors, expect readings to change after recalibration to match corrected reference values
ESP32 Build Size and Compile Time Optimizations
Section titled “ESP32 Build Size and Compile Time Optimizations”ESP32 builds are faster and produce smaller firmware in this release, meaning shorter compile times and more room on your devices.
| Improvement | Savings | Details |
|---|---|---|
| Arduino selective compilation (#13623) | 36% faster builds, 44% less flash, 50% less static RAM | Unused Arduino libraries are no longer compiled or linked |
| ESP-IDF component exclusion (#13610, #13664) | ~22% faster ESP-IDF compiles | Unused ESP-IDF components are excluded at build time instead of compiled and discarded by the linker |
| Streamlined certificate bundle (#13574) | ~51KB flash saved | Default switched to Common CAs (~99% of websites); full bundle available via config |
| Skip precompiled Arduino libs (#13775) | ~40% faster first build, ~2GB disk saved | Stub replaces the ~270MB precompiled library download that isn’t needed when building from source |
| sdkconfig defaults (#13611) | Additional flash savings | Unused ESP-IDF features (debug stubs, PKCS#7, FAT) disabled by default |
Arduino numbers measured on an ESP32 Arduino build comparing before and after this release. ESP-IDF compile time measured across multiple optimization PRs. Actual savings depend on your configuration.
How it works: ESPHome now only compiles the parts of Arduino and ESP-IDF that your configuration actually uses. Built-in components automatically re-enable the libraries they need, so most users get these savings with zero configuration changes.
Who benefits most? Everyone on ESP32. If your firmware was close to flash limits, this may free enough space to add more components. If you were waiting on long compiles, expect noticeably faster builds. Users on ESP-IDF see the ~22% compile time improvement automatically. Arduino users see all three improvements.
External components that call cg.add_library() in their code generation work automatically. If you use external components or lambdas that rely on Arduino libraries without declaring them, you can add them to esphome: libraries:. See Breaking Changes for details.
Runtime Memory and Performance
Section titled “Runtime Memory and Performance”Your devices should be more responsive and more stable after this update. Across all platforms, we’ve reduced CPU usage, freed up RAM, and eliminated sources of memory fragmentation that can cause crashes after weeks or months of uptime.
ESP8266 RAM Recovery
Section titled “ESP8266 RAM Recovery”ESP8266 devices have only 80KB of RAM, so every byte matters. This release moves constant strings and lookup tables from RAM to flash across 19+ components, freeing up heap for actual device operation. Components updated include web_server (#13315), light (#13314), mqtt (#13546), wifi (#13349), debug (#13352), and 13 more via a new flash-based string table pattern (#13659) applied to uart (#13805), sprinkler (#13806), ssd1306 (#13814), and others.
Long-Term Stability
Section titled “Long-Term Stability”Devices that run for months can crash when repeated memory allocations fragment the heap. This release eliminates unnecessary runtime memory allocations across the codebase, including api (#13399), mqtt (#13434), thermostat (#13692), sprinkler (#13705), voice_assistant (#13689), and many others. On ESP8266, format strings are also moved to flash as part of these changes (#13258).
UART Batch Reads
Section titled “UART Batch Reads”16 UART-based components now read all available serial data at once instead of one byte per loop, reducing CPU overhead. Updated components include modbus (#13822), nextion (#13823), tuya (#13827), ld2410 (#13820), dsmr (#13826), and ld2450 (#13818).
CPU and Loop Optimizations
Section titled “CPU and Loop Optimizations”The esp32_ble_tracker loop uses ~85% less CPU thanks to state change tracking (#13337). Components like status (#13342) and globals (#13345) no longer run every loop iteration. The api (#13901) and core loop (#13900) were also tightened up, and mDNS polling was throttled on ESP8266 and RP2040 (#13917).
Scheduler Improvements
Section titled “Scheduler Improvements”The scheduler runs on every device and drives all timers and intervals. This release makes it smaller and more efficient: the core timer code is 25% smaller (#13899), memory allocations were removed from cleanup operations (#13837), and flash usage was reduced (#13214). Timer IDs are now type-safe to prevent collisions between components (#13882), and the set_retry API was deprecated in favor of set_interval/set_timeout (#13845).
MQTT Optimizations
Section titled “MQTT Optimizations”If you use MQTT, your devices will use noticeably less CPU and memory. Previously, every MQTT entity ran its own loop and rebuilt topic strings every iteration, causing thousands of unnecessary memory allocations per minute. This has been consolidated so entities are processed centrally (#13356), saving roughly 6.5% total device CPU with savings scaling with entity count.
Memory allocations were also removed from discovery messages (#13216), publish paths (#13372), topic building (#13434, #13812), and log forwarding (#13809).
Who benefits most? Users running MQTT instead of the native API, especially devices with many entities. The more entities you expose over MQTT, the bigger the improvement. If you’ve noticed high CPU usage or instability on MQTT devices, this update should help.
Security Hardening
Section titled “Security Hardening”Our first internal security audit in 2025.10.0 led to several deprecations, most of which were completed in 2026.1.0. This release started a new review cycle. No issues requiring deprecation were found, but we identified several additional hardening opportunities.
- Constant-time authentication - The dashboard (#13865) and web server (#13868) now use constant-time string comparisons for Basic Auth credential checks, preventing timing-based side-channel attacks
- Cryptographic random generation - The OTA component (#13863) and setup wizard (#13864) now use Python’s
secretsmodule for generating authentication nonces and fallback AP passwords, replacing less secure random sources - Protobuf parsing hardening - The API protobuf parser now guards against overlong varint encodings (#13870)
- Download path validation - The dashboard binary download handler now uses
Path.resolve()andrelative_to()for path validation instead of string replacement (#13867) - Auth header validation - The dashboard gracefully handles malformed Basic Auth headers instead of raising exceptions (#13866)
New Components
Section titled “New Components”DLMS/COSEM Smart Meter
Section titled “DLMS/COSEM Smart Meter”The new dlms_meter component adds support for smart meters using the DLMS/COSEM protocol, commonly used by European energy providers (#8009). The component connects via UART to an M-Bus adapter and supports encrypted communication with configurable decryption keys. Available sensors include voltage, current, and active power per phase, as well as energy totals and timestamps. Multiple provider-specific configurations are supported, including Netz NOE and EVN.
CH423 I/O Expander
Section titled “CH423 I/O Expander”The new ch423 component provides support for the CH423 I/O expander with 24 GPIO pins: 8 bidirectional I/O pins and 16 output-only pins (#13079). Based on the CH422G driver architecture, it communicates over I2C and can be used with standard GPIO binary sensors, switches, and outputs.
SY6970 Battery Management IC
Section titled “SY6970 Battery Management IC”The new sy6970 component supports the SY6970 battery management IC, commonly found in devices like the LilyGo T-Display S3 Pro (#13311). It provides:
- Voltage sensors - VBUS, battery, and system voltage monitoring
- Current sensors - Charge and precharge current measurement
- Binary sensors - Charging status, VBUS connection, and charge completion
- Text sensors - Bus status, charge status, and NTC temperature status
- Configurable charging - Set charge voltage, current limits, and enable/disable charging
Expanded Display Support
Section titled “Expanded Display Support”This release adds support for 7 new display models across multiple display platforms, with a particular focus on ESP32-P4 displays.
MIPI DSI displays:
- Waveshare ESP32-P4-WIFI6-TOUCH-LCD-7B - 7” touchscreen for the ESP32-P4 (#13608)
- Waveshare ESP32-P4-WIFI6-TOUCH-LCD-3.4C - 800x800 circular display (#13840)
- Waveshare ESP32-P4-WIFI6-TOUCH-LCD-4C - 720x720 circular display (#13840)
- Guition JC8012P4A1 - An affordable display panel (#13241)
- M5Stack Tab5 V2 - Updated revision using the ST7123 integrated display-touch driver (#12074)
MIPI SPI displays:
- ESP32-2432S028 variants - Added support for ILI9342, ILI9342A, and ST7789V driver chip variants of the popular Sunton board (#13340)
HUB75 LED matrix:
- Huidu HD-WF1 - Added pin configuration for the WF1 version of the Huidu board (#13341)
E-Paper:
- Waveshare 1.54-G - 4-color e-paper display based on the JD79660 controller (#13758)
Zigbee and nRF52 Platform Enhancements
Section titled “Zigbee and nRF52 Platform Enhancements”The Zigbee integration on nRF52 receives several important improvements in this release.
- Time synchronization - Zigbee end devices can now synchronize their clocks from the Zigbee coordinator, enabling time-based automations on battery-powered devices (#12236)
- Number component support - ESPHome number entities can now be exposed over Zigbee, expanding the set of entity types available for Zigbee-connected devices (#13581)
- Custom vendor OUI - Configure the IEEE 802.15.4 Vendor Organizationally Unique Identifier to replace Nordic Semiconductor’s default company ID with your own, or use a random address during development (#13580)
- Thread-safe task log buffer - A new
TaskLogBufferimplementation for nRF52/Zephyr using Zephyr’s nativempsc_pbufenables reliable multi-threaded logging, matching the capabilities already available on ESP32, Host, and LibreTiny (#13862)
LibreTiny Platform Update
Section titled “LibreTiny Platform Update”LibreTiny has been updated from v1.10.x to v1.12.1 (#13512, #13851), bringing new board support (WBR3, generic RTL8720CM, CR3L), a refactored Serial library with dynamic RX/TX pin changes, static IP support for Realtek AMB WiFi, improved OTA for Realtek AMBZ2, Beken BDK 3.0.78 support, and several WiFi stability fixes including watchdog resets during connection attempts on BK72xx.
Cover Component: Operation-Based Triggers and Conditions
Section titled “Cover Component: Operation-Based Triggers and Conditions”The cover component gains new triggers that fire based on movement state, making cover automations much more natural to write (#13471).
New triggers:
on_opening- Fires when the cover starts openingon_closing- Fires when the cover starts closingon_idle- Fires when the cover stops moving
New conditions:
cover.is_open- Check if a cover is fully opencover.is_closed- Check if a cover is fully closed
The existing on_open trigger has been renamed to on_opened (the old name is deprecated until 2026.8.0). Additionally, on_opened and on_closed now only fire on transitions to the fully open/closed state, fixing unintended repeated trigger firing that occurred on every state update.
New Sensor Features and Hardware Support
Section titled “New Sensor Features and Hardware Support”New hardware support:
- Plantower PMS1003, PMS3003, PMS9003M - Three additional particle sensor models are now supported by the pmsx003 component (#13640)
- Resol DeltaSol BS/2 - The vbus component now supports this solar controller with temperature, pump speed, heat quantity, and error sensors (#13762)
- BMP581 I2C/SPI split - The BMP581 pressure sensor has been split into
bmp581_baseandbmp581_i2ccomponents, preparing the way for future SPI support. Existing users will need to update their platform frombmp581tobmp581_i2c(#12485)
Sensor filter improvements:
max_deltafilter - A new filter that rejects measurement differences exceeding a configurable threshold, effectively removing outliers from sensor readings (#12605)
Debug component:
min_freeheap sensor - Reports the minimum free heap size since boot for ESP32 and LibreTiny platforms, useful for detecting memory high-water-mark usage (#13231)fragmentationsensor - Now available on ESP32 in addition to ESP8266 (#13231)
Additional Component Enhancements
Section titled “Additional Component Enhancements”- HTTP request custom CA certificates - ESP32 devices can now use
ca_certificate_pathto specify a PEM file for SSL verification, enabling HTTPS connections to servers with self-signed or custom CA certificates (#13552) - BTHome encrypted beacons - The bthome_mithermometer component now supports decrypting encrypted BTHome beacons from PVVX firmware using a bindkey, preventing spoofing with fake data over the air (#13428)
- Ethernet
on_connect/on_disconnecttriggers - The ethernet component now supports connection triggers, matching the functionality already available for WiFi (#13677) - HeatpumpIR ESP-IDF support - The heatpumpir component now works with the ESP-IDF framework, not just Arduino (#13042)
- Select condition - A new
select.iscondition allows checking the value of a select entity in automations (#13267) - MQTT cover JSON state payload - Covers can now publish position, tilt, and state as a single JSON payload on one topic, reducing MQTT message volume (#12639)
- Key collector text sensor - The key_collector component now supports a text sensor platform and accepts multiple key input sources (#13617)
- Template water heater improvements - Added
target_temperaturelambda (#13661) and On/Off and Away mode support (#13839) - Nextion configurable timeouts - The
startup_override_msandmax_queue_ageconstants are now configurable via YAML, allowing users to tune timing for their specific displays (#11098) - Voice assistant timer optimization - Timer storage switched from
unordered_maptovector, eliminating per-tick heap allocation and string copies for the hot path that runs every second (#13857)
Looking Ahead
Section titled “Looking Ahead”This release continues the work that began in 2025.10.0 and accelerated in 2026.1.0: making ESPHome leaner and more reliable on every platform. Fewer heap allocations, smaller firmware, and lower CPU usage all contribute to devices that stay stable for months and years. That focus on memory discipline and long-term stability will continue in future releases as we extend these improvements to more components and platforms.
On the documentation side, esphome.io has migrated from Hugo to Starlight, bringing faster page loads, improved search, and a modern documentation framework that will make it easier to maintain and contribute to the docs going forward.
Breaking Changes
Section titled “Breaking Changes”Most users can update without any configuration changes. The items below are grouped by whether you need to take action.
Action required (if you use these components)
Section titled “Action required (if you use these components)”-
BMP581: Update your platform from
bmp581tobmp581_i2c. The component has been split to prepare for future SPI support. #12485 -
Cover triggers: Rename
on_opentoon_openedin your cover automations (the old name is deprecated until 2026.8.0). Additionally,on_openedandon_closednow only fire on transitions to the fully open/closed state, not on every state update. Automations that relied on repeated firing will need to be adjusted. #13471 -
DSMR: Move
fw_core_versionandfw_module_versionfromsensor:totext_sensor:. The meter returns version strings (e.g.,(ER11)), not numbers. #13780 -
Arduino library APIs in lambdas: If you directly call Arduino library APIs in lambdas (e.g.,
Preferences,WiFi,Wire), add them to your config. ESPHome’s built-in components handle this automatically, so this only affects custom lambda code. #13623esphome:libraries:- Preferences # Add any Arduino libraries you use directly -
Voice Assistant timers: If you use lambdas that iterate timers with map pair semantics (
.second), update them to accessTimerfields directly. See the PR description for before/after examples. #13857
Most users unaffected
Section titled “Most users unaffected”These changes improve correctness or save resources. They only require action if you depend on the previous behavior.
-
ESP32 certificate bundle: The default TLS bundle now includes only Common CAs (~99% of websites), saving ~51KB of flash. If you connect to HTTPS services using uncommon CAs, add
use_full_certificate_bundle: trueunderesp32: framework: advanced:. #13574 -
BL0942: Calibration reference values have been corrected to match datasheet formulas. Sensor readings will change. Users with custom calibration may need to re-calibrate. #12867
-
Sensor clamp filter: The
clampfilter now handles infinity and NaN instead of passing them through. #13457 -
Water Heater: On/Off and Away state control now requires both Home Assistant 2026.3.0 and ESPHome 2026.2.0. #13892
Breaking Changes for Developers
Section titled “Breaking Changes for Developers”- ESP32 Arduino selective compilation: Arduino libraries are now disabled by default. External components that use Arduino libraries must call
cg.add_library("LibraryName", None)in theirto_code()to enable them. #13623 - Voice Assistant
get_timers()return type:get_timers()now returnsconst std::vector<Timer> &instead ofconst std::unordered_map<std::string, Timer> &. Code using map pair semantics (.second) must be updated to iterateTimerdirectly. Theon_timer_tickautomation arg type is nowconst std::vector<Timer> &. #13857 - Cover
on_openrenamed toon_opened: TheCoverOpenTriggernow tracks transitions instead of firing on every state update. The oldon_openname is deprecated until 2026.8.0. #13471 - Water Heater API:
WATER_HEATER_COMMAND_HAS_STATEis deprecated in favor ofWATER_HEATER_COMMAND_HAS_ON_STATEandWATER_HEATER_COMMAND_HAS_AWAY_STATEfor granular on/off and away control. #13892
For detailed migration guides and API documentation, see the ESPHome Developers Documentation.
Release 2026.2.1 - February 20
Section titled “Release 2026.2.1 - February 20”- [esp32_ble_server] fix infinitely large characteristic value esphome#14011 by @Rapsssito
- [udp] Register socket consumption for CONFIG_LWIP_MAX_SOCKETS esphome#14068 by @bdraco
- [web_server] Double socket allocation to prevent connection exhaustion esphome#14067 by @bdraco
- [pulse_counter] Fix compilation on ESP32-C6/C5/H2/P4 esphome#14070 by @bdraco
- [web_server] Fix water_heater JSON key names and move traits to DETAIL_ALL esphome#14064 by @bdraco
- [ld2420] Use constexpr for compile-time constants esphome#14079 by @bdraco
- [e131] Fix E1.31 on ESP8266 and RP2040 by restoring WiFiUDP support esphome#14086 by @bdraco
- [socket] Fix IPv6 compilation error on host platform esphome#14101 by @swoboda1337
- [ethernet] Improve clk_mode deprecation warning with actionable YAML esphome#14104 by @swoboda1337
- [pulse_counter] Fix build failure when use_pcnt is false esphome#14111 by @swoboda1337
- [esp32_ble] Enable CONFIG_BT_RELEASE_IRAM on ESP32-C2 esphome#14109 by @bdraco
- [safe_mode] Log brownout as reset reason on OTA rollback esphome#14113 by @swoboda1337
- [wifi] Sync output_power with PHY max TX power to prevent brownout esphome#14118 by @swoboda1337
- [uart] Always call pin setup for UART0 default pins on ESP-IDF esphome#14130 by @bdraco
- [pulse_counter] Fix PCNT glitch filter calculation off by 1000x esphome#14132 by @swoboda1337
- [ld2450] Add frame header synchronization to readline_() esphome#14135 by @swoboda1337
- [ld2410] Add frame header synchronization to readline_() esphome#14136 by @swoboda1337
- [ld2420] Increase MAX_LINE_LENGTH to allow footer-based resync esphome#14137 by @swoboda1337
- [ld2410/ld2450] Replace header sync with buffer size increase for frame resync esphome#14138 by @swoboda1337
Release 2026.2.2 - February 26
Section titled “Release 2026.2.2 - February 26”- [max7219digit] Fix typo in action names esphome#14162 by @swoboda1337
- [mipi_dsi] Disallow swap_xy esphome#14124 by @clydebarrow
- [dsmr] Add deprecated std::string overload for set_decryption_key esphome#14180 by @bdraco
- [api] Fix build error when lambda returns StringRef in homeassistant.event data esphome#14187 by @bdraco
- [haier] Fix uninitialized HonSettings causing API connection failures esphome#14188 by @bdraco
- [bme68x_bsec2] Fix compilation on ESP32 Arduino esphome#14194 by @bdraco
- [network] Improve IPAddress::str() deprecation warning with usage example esphome#14195 by @bdraco
- [water_heater] Fix device_id missing from state responses esphome#14212 by @bdraco
- [mipi_dsi] Allow transform disable; fix warnings esphome#14216 by @clydebarrow (new-feature)
- [http_request.ota] Percent-encode credentials in URL esphome#14257 by @swoboda1337
- Don’t get stuck forever on a failed component can_proceed esphome#14267 by @jesserockz
- [pid] Fix deadband threshold conversion for Fahrenheit esphome#14268 by @swoboda1337
- [ld2420] Fix sizeof vs value bug in register memcpy esphome#14286 by @swoboda1337
- [rtttl] Fix speaker playback bugs esphome#14280 by @swoboda1337
- [hmc5883l] Fix wrong gain for 88uT range esphome#14281 by @swoboda1337
- [sensor] Fix delta filter percentage mode regression esphome#14302 by @swoboda1337
Release 2026.2.3 - March 3
Section titled “Release 2026.2.3 - March 3”- [mqtt] Remove broken ESP8266 ssl_fingerprints option esphome#14182 by @bdraco (breaking-change)
- [sprinkler] Fix millis overflow and underflow bugs esphome#14299 by @swoboda1337
- [cc1101] Transition through IDLE in begin_tx/begin_rx for reliable state changes esphome#14321 by @swoboda1337
- [zigbee] Fix codegen ordering for basic/identify attribute lists esphome#14343 by @swoboda1337
- [uart] Revert UART0 default pin workarounds (fixed in ESP-IDF 5.5.2) esphome#14363 by @bdraco
- [mipi_dsi] Fix Waveshare P4 7B board config esphome#14372 by @clydebarrow
- [core] Defer entity automation codegen to prevent sibling ID deadlocks esphome#14381 by @swoboda1337
- [improv_serial] Add missing USE_IMPROV_SERIAL define to fix WiFi scan filtering esphome#14359 by @bdraco
- [uart] Fix flow_control_pin inverted flag ignored on ESP-IDF esphome#14410 by @swoboda1337
Release 2026.2.4 - March 3
Section titled “Release 2026.2.4 - March 3”- [wifi] Revert cyw43_wifi_link_status change for RP2040 esphome#14424 by @bdraco
Full List of Changes
Section titled “Full List of Changes”For the complete list of every merged pull request in this release, see the full 2026.2.0 changelog.




Comments