An ordinary HTTPS request from an ESPHome device has so far stopped everything else on it. The http_request.get, http_request.post and http_request.send actions ran the whole request in one go, and the main loop waited until it finished. On an ESP32-S3 that meant 2.5 to 3.6 seconds without reading sensors, refreshing a display or answering Home Assistant. A pull request merged on 24 October 2026 changes this, and it comes with a breaking change for scripts. It is in the development branch, so it should ship in ESPHome 2026.11.

How it works now

The action hands the request to the http_request component, which drives it a step at a time from its own loop. The actions that follow it in an automation still run only after the response has arrived, so existing logic keeps its order.

The author measured the longest loop stall on a T-Display S3 Pro (ESP32-S3, ESP-IDF 5.5.6):

  • HTTPS GET: 2397-2519 ms before, 296-356 ms after;
  • HTTPS POST: 1733-2726 ms before, 297-306 ms after;
  • HTTPS with a 20 KB body: 2222-2442 ms before, 688-727 ms after;
  • a 70 KB download over the local network at 20 KB/s: 3557-3580 ms before, 13-39 ms after.

The total time of a request is the same as before. Some steps still block on ESP-IDF: the first connection to each host (DNS and TCP, about 235 ms in the tests), about 300 ms of CPU for the TLS handshake, and reading HTTPS bodies, because the TLS library waits for complete records. An unreachable host still blocks for the full timeout. The socket checks need ESP-IDF 5.5.3 or newer. Arduino and host builds behave as before.

Queue and limits

Each http_request component now runs one request at a time, in the order they were triggered, with up to four more waiting. Anything beyond that fires on_error and logs Too many requests waiting; request dropped. Each TLS client needs about 40 kB of RAM, which is why requests are not allowed to pile up. A new max_concurrent_requests option (1 to 4, default 1) allows more of them to run at once.

script.stop can now cancel a request in progress. A reboot or deep sleep drops waiting and running requests, but requests made from on_shutdown automations are still sent. A response that never arrives still fires on_response with status -1. On the CI test configuration for ESP32 with ESP-IDF, firmware grew by 2.9 kB of flash and 8 bytes of RAM.

The breaking change

A script containing one of these actions is now in the running state for as long as the request takes. Scripts use mode: single by default, so a second trigger in that time logs Script 'x' is already running! (mode: single) and is skipped. Before, the script always finished at once. If a script that sends requests can be triggered again quickly, for example from a button or a sensor that updates often, switch it to mode: queued or mode: parallel before updating.

The documentation describing how requests run alongside the main loop is still an open pull request.