Skip to content

gh-160760: asyncio: run newly scheduled callbacks eagerly before polling for I/O - #145149

Draft
asvetlov wants to merge 1 commit into
python:mainfrom
asvetlov:eager-loop
Draft

asvetlov wants to merge 1 commit into
python:mainfrom
asvetlov:eager-loop

Conversation

@asvetlov

@asvetlov asvetlov commented Feb 23, 2026 •

Copy link
Copy Markdown
Contributor

Run callbacks that are scheduled during an event loop iteration eagerly, within a small budget, instead of always waiting for the next I/O poll. This removes one select()/epoll_wait() call per hop in code that resolves futures or wakes tasks in chains.

  • New asyncio.EventLoopSettings(eager_max_time, eager_max_callbacks) and loop.get_settings() / loop.set_settings(). The defaults are 100 µs and 100 callbacks; eager_max_time=0 turns eager processing off.
  • Eager processing ends early on asyncio.sleep(0), which still guarantees an I/O poll, and on loop.stop(), which keeps its documented "current batch only" behaviour.
  • Callbacks still run in first-in, first-out order. Only the number of I/O polls changes.

Benchmarks (release build): a call_soon() chain is 38% faster, Queue ping-pong 25% faster, and a task awaiting a child task 33% faster. Servers with many connections are unchanged. While a long run of callbacks keeps going, timers and I/O can be delayed by up to about 100–200 µs.

A few tests that assumed "one task hop = one I/O poll" were adjusted.

@github-actions

This comment was marked as outdated.

@github-actions github-actions Bot added the stale Stale PR or inactive for long period of time. label May 7, 2026
@asvetlov asvetlov changed the title Implement eager loop runner #160760: Implement eager loop runner Oct 27, 2026
@asvetlov asvetlov added topic-asyncio and removed stale Stale PR or inactive for long period of time. labels Oct 27, 2026
@asvetlov asvetlov changed the title #160760: Implement eager loop runner gh-160760: asyncio: run newly scheduled callbacks eagerly before polling for I/O Oct 27, 2026
@bedevere-app bedevere-app Bot added the type-feature A feature request or enhancement label Oct 27, 2026
@read-the-docs-community

read-the-docs-community Bot commented Oct 27, 2026 •

Copy link
Copy Markdown

@asvetlov
asvetlov force-pushed the eager-loop branch 5 times, most recently from f3f2dfe to 2950322 Compare October 28, 2026 14:53
…e polling for I/O

After running the ready callbacks, BaseEventLoop._run_once() now keeps
running the callbacks they schedule, in batches, before it polls for I/O
again.  This saves one I/O poll per hop of a callback chain, for example
when a completed future wakes up a task.

Eager processing is bounded by the new asyncio.EventLoopSettings,
set with loop.set_settings() and read with loop.get_settings():
eager_max_time (default 100 microseconds) and eager_max_callbacks
(default 100).  asyncio.sleep(0) ends eager processing, so that the
task resumes only after the next I/O poll.  When stop() is called
during eager processing, run_forever() runs one more iteration, which
polls for I/O and runs what the loop would have run without eager
processing.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

topic-asyncio type-feature A feature request or enhancement

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant