MagicStack / MagicStack/uvloop
uvloop may sleep less than `n` for asyncio.sleep(n)
Nobody has claimed this yet.
- Dominant language
- Cython
- Stars
- 11.9k
- Forks
- 616
- PR merge metrics
- No merged PRs in 30d
Description
Bug Description
When calling asyncio.sleep, uvloop sometimes sleeps for fractionally less then the requested sleep time. E.g. await asyncio.sleep(0.1) -> Sleeps for 0.0991.
Expected behavior
Should always sleep for at least the specified time.
Environment
- Operating System:
Fedora 43 - Python Version:
Python 3.13.12 - uvloop Version:
0.22.1
Steps to Reproduce
Run the following script and observe output:
import asyncio
import statistics
import time
async def main():
sleep_times = []
for _ in range(100):
start_time = time.perf_counter()
await asyncio.sleep(0.1)
end_time = time.perf_counter()
sleep_times.append(end_time - start_time)
print(f"Min sleep time: {min(sleep_times):.4f} seconds")
print(f"Max sleep time: {max(sleep_times):.4f} seconds")
print(f"Average sleep time: {statistics.mean(sleep_times):.4f} seconds")
if __name__ == "__main__":
print("With default asyncio event loop:")
asyncio.run(main())
print("With uvloop event loop:")
import uvloop
asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())
asyncio.run(main())
Output:
With default asyncio event loop:
Min sleep time: 0.1001 seconds
Max sleep time: 0.1008 seconds
Average sleep time: 0.1002 seconds
With uvloop event loop:
Min sleep time: 0.0991 seconds
Max sleep time: 0.1011 seconds
Average sleep time: 0.1001 seconds
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by running the provided reproduction with the default asyncio loop and uvloop, then trace how uvloop handles asyncio.sleep timers. Compare the measured duration against the requested delay and add a regression test for the minimum sleep time. Done means asyncio.sleep(n) does not return before n has elapsed.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- backend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100