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

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.1.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.1-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.1.tar.gz.

File metadata

  • Download URL: uringcore-0.9.1.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.1.tar.gz
Algorithm Hash digest
SHA256 727d26341ba3fe9f0ecba23f35e8e0c76489c8fd7d45db81337510190d172256
MD5 a571afe09c65b190090ca731f4ea82af
BLAKE2b-256 3196d4f1107b907bc2c49a14fbc09858ba877320894cfbdeb0cac4d7e57d151c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for uringcore-0.9.1-cp313-cp313-manylinux_2_34_x86_64.whl
Algorithm Hash digest
SHA256 c8556d9e27f0dade7b500b56632fba30daf18ba47130442dced760dc06cc8f1d
MD5 e728d22f1aff0425de0b9344d36f15e5
BLAKE2b-256 6fae494a8ceb9b1167918e4098339566088e5a90f26836cc738651a19cb1ff0a

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