Skip to main content

High-performance asyncio event loop for Python using io_uring - 36% faster than asyncio

Project description

uringcore

CI License Python Rust

A high-performance asyncio event loop for Linux using io_uring.

Introduction

uringcore provides a drop-in replacement for Python's asyncio event loop, built on the io_uring interface available in Linux kernel 5.11+. The project targets use cases where low-latency I/O and high throughput are critical requirements.

The implementation leverages a completion-driven architecture rather than the traditional readiness-based model used by epoll. This design eliminates syscalls from the hot path, resulting in measurable performance improvements for network-intensive applications.

Use Cases

  • High-frequency trading systems requiring sub-millisecond latency
  • Real-time data pipelines processing millions of messages per second
  • API gateways handling high concurrent connection counts
  • WebSocket servers with persistent connections
  • Database connection pools with intensive query workloads

Requirements

  • Linux kernel 5.11+ (for IORING_OP_PROVIDE_BUFFERS)
  • Python 3.10+
  • Rust 1.70+

Optional:

  • SQPOLL mode requires CAP_SYS_ADMIN or kernel 5.12+ with unprivileged SQPOLL

Installation

From PyPI (when published)

pip install uringcore

From Source

git clone https://github.com/ankitkpandey1/uringcore.git
cd uringcore

# Create virtual environment
python3 -m venv .venv
source .venv/bin/activate

# Install build dependencies
pip install maturin

# Build and install
maturin develop

Quick Start

Replace the default asyncio event loop with uringcore:

import asyncio
import uringcore

# Set the event loop policy
asyncio.set_event_loop_policy(uringcore.EventLoopPolicy())

async def main():
    # Standard asyncio code works unchanged
    await asyncio.sleep(1)
    print("Hello from uringcore!")

asyncio.run(main())

With FastAPI

import asyncio
import uringcore
from fastapi import FastAPI

asyncio.set_event_loop_policy(uringcore.EventLoopPolicy())

app = FastAPI()

@app.get("/")
async def root():
    return {"message": "Powered by uringcore"}

With Starlette

import asyncio
import uringcore
from starlette.applications import Starlette
from starlette.responses import JSONResponse
from starlette.routing import Route

asyncio.set_event_loop_policy(uringcore.EventLoopPolicy())

async def homepage(request):
    return JSONResponse({"hello": "world"})

app = Starlette(routes=[Route("/", homepage)])

Performance

Verified benchmark results against standard asyncio and uvloop:

Metric uringcore asyncio uvloop
Throughput 15,394 req/s 11,317 req/s 11,721 req/s
p50 Latency 58 µs 83 µs 78 µs
p99 Latency 121 µs 181 µs 182 µs
vs asyncio +36% baseline +4%

See BENCHMARK.md for methodology and detailed analysis.

Features

  • Pure io_uring - No fallback to epoll for core I/O
  • TCP Support - create_server, create_connection, start_server
  • UDP Support - create_datagram_endpoint
  • Unix Sockets - create_unix_server, create_unix_connection
  • Subprocess - subprocess_exec, subprocess_shell
  • Signal Handlers - add_signal_handler, remove_signal_handler
  • Executor Integration - run_in_executor for blocking calls
  • Reader/Writer Callbacks - add_reader, add_writer for 3rd-party compatibility
  • Connection Timeouts - IORING_OP_LINK_TIMEOUT support

Project Structure

uringcore/
├── src/                    # Rust core implementation
│   ├── lib.rs              # PyO3 module entry point
│   ├── buffer.rs           # Zero-copy buffer pool
│   ├── ring.rs             # io_uring wrapper with LINK_TIMEOUT
│   ├── state.rs            # FD state machine
│   └── error.rs            # Error types
├── python/                 # Python layer
│   └── uringcore/
│       ├── __init__.py
│       ├── loop.py         # UringEventLoop
│       ├── policy.py       # EventLoopPolicy
│       ├── transport.py    # Socket transport
│       ├── datagram.py     # UDP transport
│       ├── subprocess.py   # Subprocess transport
│       └── ssl_transport.py # SSL/TLS wrapper
├── tests/                  # Test suites
│   ├── test_basic.py       # Unit tests
│   ├── test_stress.py      # Concurrent stress tests
│   ├── test_asyncio_compat.py  # asyncio API tests
│   └── e2e/
│       ├── starlette/
│       └── fastapi/
└── benchmarks/             # Performance benchmarks

Documentation

Development

Running Tests

# Rust tests
cargo test

# Python tests
source .venv/bin/activate
pytest tests/ -v

# All tests including e2e
pytest tests/ tests/e2e/ -v

Code Quality

# Rust formatting and linting
cargo fmt
cargo clippy --all-targets -- -D warnings

# Python linting (if ruff/black installed)
ruff check .

License

SPDX-License-Identifier: Apache-2.0
Copyright 2024 Ankit Kumar Pandey <ankitkpandey1@gmail.com>

Licensed under the Apache License, Version 2.0. See LICENSE for details.

Author

Ankit Kumar Pandey - ankitkpandey1@gmail.com

Acknowledgments

  • The io_uring subsystem maintainers, particularly Jens Axboe
  • The PyO3 project for Rust-Python bindings
  • The uvloop project for demonstrating high-performance event loop implementation

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

uringcore-0.9.0.tar.gz (59.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

uringcore-0.9.0-cp313-cp313-manylinux_2_34_x86_64.whl (263.1 kB view details)

Uploaded CPython 3.13manylinux: glibc 2.34+ x86-64

File details

Details for the file uringcore-0.9.0.tar.gz.

File metadata

  • Download URL: uringcore-0.9.0.tar.gz
  • Upload date:
  • Size: 59.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: maturin/1.10.2

File hashes

Hashes for uringcore-0.9.0.tar.gz
Algorithm Hash digest
SHA256 38b8dba0a1c83d0c58133d087a18edbae45ca7b91a721908db8b5f24716a6c65
MD5 770a988071baae027219f487c9596820
BLAKE2b-256 8e2b8af9f47e591362a953e370cd9469af46e7bb7cf08bfa2aac299daaab13b0

See more details on using hashes here.

File details

Details for the file uringcore-0.9.0-cp313-cp313-manylinux_2_34_x86_64.whl.

File metadata

File hashes

Hashes for uringcore-0.9.0-cp313-cp313-manylinux_2_34_x86_64.whl
Algorithm Hash digest
SHA256 8656ae81eaef24d23789999ad04c2f362a7902c01aee459c35e6da35124ef086
MD5 018730d3194727e72486ffa155c8af96
BLAKE2b-256 955f0322b2f888d78562e2c8678390060428487d7f59010f907f9a9e2e9bc0c4

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page