Problem
Your ESP32 esp_http_server works for a while, then new connections time out — curl hangs, the browser can’t load the web UI — even though the device still responds to ping and earlier connections work fine.
Cause
esp_http_server limits concurrent sockets with max_open_sockets (default: 7). Browsers and keep-alive clients leave sockets open; clients that disappear without a clean close leave them lingering. Once all 7 slots are occupied by stale connections, new connections are accepted by TCP but never serviced — they just time out.
Solution
Enable LRU purging so the server evicts the least-recently-used idle socket when it needs a slot for a new connection, and raise the handler/stack limits while you’re at it:
httpd_config_t conf = HTTPD_DEFAULT_CONFIG();
// Evict stale/idle sockets instead of starving new connections
conf.lru_purge_enable = true;
// Default is 8 — far too low if you have many endpoints
conf.max_uri_handlers = 128;
// Complex handlers (files, JSON) need more than the default 4 KiB
conf.stack_size = 16 * 1024;
httpd_start(&server, &conf);Additional tips
- Close your sockets properly in handlers. A handler that returns without calling
httpd_resp_send*can leave the session in a weird state. Always send a response (even an empty one). - Bounded timeouts: consider
conf.recv_wait_timeoutandconf.send_wait_timeout(default 5 s) if clients on lossy networks stall mid-request. - Check with netstat on the client side: many
CLOSE_WAIT/ESTABLISHEDentries to the ESP32 confirm socket exhaustion.
After enabling lru_purge_enable, lingering browser connections no longer starve new clients — no reboot required.