curl DNS 2026: threaded resolver gets a thread pool in 8.20.0

April 13, 2026
Intricate close-up of dark spiral metal shavings with a textural and abstract feel.
Photo by Tomás Asurmendi on Pexels

What happened

It has been reported that libcurl 8.20.0 replaces the old per-request resolver threads with a pooled, multi-owned threaded resolver. Previously, each easy handle that needed getaddrinfo() spawned its own thread and socketpair; add 50 parallel hosts and you got 50 threads and 50 socketpairs. Ouch. The new design moves the pool to the multi handle, uses one socketpair per multi for notifications, and queues inbound and outbound resolve requests instead of tying threads to individual easy handles.

New controls and behavior

The pool is sized on demand and can shrink after idle periods. Applications can cap concurrency with the new CURLMOPT_RESOLVE_THREADS_MAX option — the default is now 20 — and control shutdown behavior with CURLMOPT_QUICK_EXIT, which can detach pool threads on multi cleanup. Because easy handles no longer “own” resolver threads, they can be removed immediately; any late DNS results for gone handles are simply discarded.

Why it matters

Less resource churn. Fewer ephemeral threads and socketpairs. That should reduce memory, syscalls and latency in many deployments — especially in places where libcurl runs thousands of transfers, not just the command line. Sounds like a win, right? There’s a trade-off: if stalled resolves occupy the pool, they can block other lookups. The maintainers prefer predictable resource limits over unbounded thread growth.

Risks and next steps

There’s a fair bit of new code here, so it has been reported that bugs are expected — hopefully minor, but human developers make mistakes. Feedback is being solicited, and defaults (like the 20-thread cap) may change based on real-world use. Want to gripe or praise the change? The author invites issues on curl’s GitHub or a note on Mastodon.

Sources: eissing.org, Lobsters