Skip to main content

Logo

Pyroxide

A lock-free, high-concurrency background task broker for Python, powered by Rust.

Rust Python License: MIT/Apache-2.0/Coffee

Explore the Docs »

API Reference · See Examples · Report Bug · Request Feature


Pyroxide (pyro3) is a lightweight, ultra-high-performance background task broker designed to bridge Python and Rust. It allows CPU-bound or blocking workloads to bypass the Python Global Interpreter Lock (GIL) with minimal memory overhead and zero CPU-sleep polling.

💡 Pyroxide is the perfect fit if you want to:

  • Prevent async event loops (like FastAPI) from freezing on heavy CPU calculations.
  • Bypass the GIL without the slow startup and heavy pickling overhead of multiprocessing.
  • Safely run untrusted user plugins in-process using isolated WASM sandboxes.
  • Reuse pre-existing system libraries (.so / .dylib / .dll) GIL-free with zero wrapper code.

Why Pyroxide?

  • 🚀 GIL-Free Performance: Execute CPU-intensive tasks on background threads or isolated processes without holding the Python GIL.
  • ⚡ Microsecond Latency: Dispatch and complete tasks in under 25 microseconds using OS-level signaling (Condvar) instead of polling.
  • 📦 Zero Infrastructure: Run entirely in-process with no Redis, RabbitMQ, or Celery worker daemons to configure or maintain.
  • 💾 Zero-Copy Transport: Route large payloads ($\ge 1\text{MB}$) via OS Shared Memory (SHM) to bypass serialization copying bottlenecks.
  • 🛡️ WASM Sandbox Security: Run untrusted user plugins or SaaS workflows in a secure JIT sandbox with strict CPU/memory limits.
  • 🛠️ Dynamic FFI Compilation: Compile code strings on-the-fly (Rust, C, Zig) into native libraries with persistent binary caching.

Pyroxide vs. Alternatives

Feature / Metric Pyroxide Threading (std) Multiprocessing Celery / RQ
GIL Bypass ✅ Yes (WASM/dylib) ❌ No ✅ Yes ✅ Yes
IPC / Serialization ✅ None (Shared Memory) ✅ None ❌ High (Pickling) ❌ High (Network/Redis)
Infrastructure ✅ None (Embedded) ✅ None ⚠️ Low (Spawns processes) ❌ High (Redis/RabbitMQ)
Best For 🔥 High-perf in-process pipelines I/O-bound Python CPU-heavy Python Distributed tasks

For a detailed analysis, check out the Library Comparison Guide.


Installation

From PyPI

pip install pyro3

Build Locally

Ensure you have Rust, Python (3.8+), and maturin installed:

git clone https://github.com/emivvvvv/pyroxide.git
cd pyroxide
pip install maturin
maturin develop

Quick Start

1. Offload Python Callables

from pyroxide import task

@task
def calculate_square(x: int) -> int:
    return x * x # Runs in background OS threads

# Submit and get a handle immediately
handle = calculate_square(12)
result = handle.result() # Blocks natively (0% CPU) until complete
print(result) # 144

# Or await it non-blockingly inside an async event loop (like FastAPI)
# result = await handle.result_async()

# Pure Python tasks can fully bypass the GIL with `isolated=True`
@task(isolated=True)
def heavy_computation(x: int) -> int:
    return sum(i * i for i in range(x))

2. Batch Submission & Task Groups

Submit tasks in bulk under a single lock acquisition to avoid thread contention, and manage them concurrently:

from pyroxide import task, group

@task
def calculate_square(x: int) -> int:
    return x * x

payloads = [10, 20, 30, 40]

# 1. Batch submit payloads
handles = calculate_square.batch(payloads)

# 2. Bundle into a parallel TaskGroup
tg = group(handles)
print(tg.status) # "Running"

# 3. Retrieve results (consume=False preserves status metadata)
results = tg.result(consume=False)
print(results)   # [100, 400, 900, 1600]
print(tg.status) # "Completed"

3. Sandboxed WebAssembly (GIL-Free)

Run computations GIL-free in a secure, virtual sandbox without compiling native code:

from pyroxide import register_wasm, wasm_task, load_wasm

# 1. Register WebAssembly bytecode
with open("rot13.wasm", "rb") as f:
    register_wasm("rot13", f.read())

# 2. Execute via decorators
@wasm_task("rot13")
def rot13_cipher(payload: str) -> str:
    pass

print(rot13_cipher("hello").result()) # "uryyb"

# 3. Or load as an Object-Oriented Proxy!
cipher = load_wasm("rot13")
print(cipher.run("hello").result()) # "uryyb"

4. Dynamic Shared Libraries (On-the-Fly Compilation)

Compile and load native code strings on-the-fly. Rust (compile_rust), C (compile_c), and Zig (compile_zig) are supported:

from pyroxide import compile_rust, dylib_task, load_dylib

RUST_SRC = """
#[no_mangle]
pub unsafe extern "C" fn pyroxide_plugin_run(ptr: *const u8, len: usize, out_len: *mut usize) -> *mut u8 {
    let input = std::slice::from_raw_parts(ptr, len);
    let s = std::str::from_utf8(input).unwrap_or("");
    let result = s.to_uppercase().into_bytes();
    *out_len = result.len();
    let boxed = result.into_boxed_slice();
    Box::into_raw(boxed) as *mut u8
}

#[no_mangle]
pub unsafe extern "C" fn pyroxide_plugin_free(ptr: *mut u8, len: usize) {
    let _ = Box::from_raw(std::slice::from_raw_parts_mut(ptr, len));
}
"""

# Compile, register and load the Rust library on-the-fly!
compile_rust("rust_upper", RUST_SRC)

# 1. Execute via decorators
@dylib_task("rust_upper")
def to_upper_rust(payload: str) -> str:
    pass

print(to_upper_rust("hello from rust").result())  # "HELLO FROM RUST"

# 2. Or load as an Object-Oriented Proxy to call any custom C-ABI symbol directly!
rust_upper = load_dylib("rust_upper")
print(rust_upper.pyroxide_plugin_run("hello from rust").result())  # "HELLO FROM RUST"

5. Universal FFI (Reusing Precompiled Libraries)

Load standard precompiled system libraries natively without compiling custom code:

import sys
from pyroxide import load_dylib

# Load system math library natively - no pyroxide_plugin_free required for primitives!
libm_name = "libm.dylib" if sys.platform == "darwin" else "libm.so.6"
libm = load_dylib(libm_name, signatures={
    "cos": {"args": ["f64"], "ret": "f64"}
})
print(libm.cos(3.1415926535).result())  # -1.0

6. Programmatic Sandbox Configuration

Configure WebAssembly memory limits, execution timeouts, and queue block/drop timeouts thread-safely:

import pyroxide

# Set global default sandbox parameters
pyroxide.config.set_wasm_limits(memory_limit_bytes=50 * 1024 * 1024, timeout_ms=500)
pyroxide.config.set_queue_timeout(timeout_ms=100)

# Apply context-specific overrides (thread-safe, ideal for multi-tenant SaaS)
with pyroxide.config.scoped(wasm_timeout_ms=50, wasm_memory_limit_bytes=10 * 1024 * 1024):
    handle = rot13_cipher("hello")

7. Static Stub Compilation CLI

Avoid runtime filesystem writes during application startup (which triggers FastAPI reload loops) by statically building type stubs:

# Scan Python files recursively to generate proxy .pyi stubs
pyroxide build-stubs --scan --scan-dir . --out-dir .

# Or read declarative configuration from pyproject.toml
pyroxide build-stubs

8. Environment Variable Reference

Configure Pyroxide dynamically using the following environment variables:

  • PYROXIDE_WORKERS: Number of background worker threads in the Rust thread pool (default: available CPU cores).
  • PYROXIDE_SHM_THRESHOLD: Payload size threshold in bytes above which data uses Shared Memory (SHM) instead of the local socket (default: 1048576 = 1MB).
  • PYROXIDE_WASM_TICK_MS: Granularity of the WASM epoch timeout tick loop in milliseconds (default: 10ms).
  • PYROXIDE_WASM_MEMORY_LIMIT_BYTES: Maximum memory allowed for a single WASM instance in bytes (default: 104857600 = 100MB).
  • PYROXIDE_WASM_TIMEOUT_MS: Timeout for WASM execution in milliseconds (default: 1000 = 1s).
  • PYROXIDE_MAX_TASKS_PER_WORKER: Maximum number of tasks an isolated process worker runs before it is recycled to prevent memory leaks (default: 100).
  • PYROXIDE_WORKER_STARTUP_TIMEOUT_SEC: Timeout in seconds for a new worker process to start up and connect (default: 5 seconds).
  • PYROXIDE_IDLE_TIMEOUT_SEC: Idle time in seconds before an inactive isolated worker process is terminated (default: 60 seconds).
  • PYROXIDE_MIN_WORKERS: Minimum number of warm worker processes to keep alive at all times (default: 0).
  • PYROXIDE_DISABLE_COMPILATION: Set to 1 or true to disable runtime compilation of C/Zig/Rust plugins for strict security compliance.

Dive Deeper (Documentation Book)

Detailed documentation, guides, and implementation examples are available in our Documentation Book:

  • Asynchronous Event Loops: Non-blockingly await tasks using await handle.result_async() in FastAPI/asyncio. Read Chapter.
  • Isolated Worker Processes: Sandbox tasks in separate OS processes for crash safety and GIL bypass. Read Chapter.
  • Batch Submissions: Submit multiple tasks under a single lock acquisition to avoid thread contention. Read Chapter.
  • Task Cancellation: Gracefully abort long-running background tasks mid-flight. Read Chapter.
  • Traceback Preservation: Capture stack traces on background worker threads and propagate them to the main thread. Read Chapter.
  • Memory Footprint & GC: Learn how Slab memory is reclaimed automatically using GC destructors. Read Chapter.

Performance At-a-Glance

We benchmarked Pyroxide against CPython's standard concurrency pools using identical compute payloads (recursive Fibonacci 20 workload) on Apple M1 Pro (8 cores, 16GB RAM):

Metric (100 Tasks) Pyroxide @dylib_task Pyroxide @task(isolated=True) Pyroxide @task Threading (std) Multiprocessing
Execution Time 0.0034 s 0.0157 s 0.0842 s 0.0751 s 2.1925 s
  • Bypassing the Multiprocessing Bottleneck: While Python's ProcessPoolExecutor takes over 2.1 seconds due to slow process spawning and heavy pickle IPC serialization, Pyroxide's @task(isolated=True) executes in just 15 milliseconds—offering a 140x speedup with optimized single-pass pickling and zero-copy shared memory.

Real-World Odoo Enterprise Arrow Ledger Audit Benchmark

To test performance under realistic enterprise data movement workloads, we ran a simulated Odoo Ledger Audit benchmark processing a 9.62 MB Apache Arrow serialized transaction recordset (200,000 journal items) across 10 concurrent requests comparing different concurrency strategies:

  • CPython ThreadPoolExecutor (GIL-Locked): 0.3453 s
  • Pyroxide Threaded @task (GIL-Locked): 0.3239 s (matches Python's native scheduling overhead perfectly)
  • ProcessPoolExecutor (Python, Pickled Pipes): 0.2625 s
  • Pyroxide SHM Isolated @task (Zero-Copy SHM): 0.3241 s
  • Pyroxide @dylib_task (C-compiled, GIL-Free): 0.0095 s (bypasses GIL entirely)

Key Takeaway: By offloading the audit logic to a dynamically compiled C/Rust plugin running on Pyroxide's background thread pool, we achieve a 36.3x speedup over CPython's standard ThreadPoolExecutor by completely bypassing the GIL.

To run the Odoo simulation suite locally:

PYTHONPATH=python:. python3 examples/odoo_poc/odoo_complex_simulation.py

To run the comparative and basic benchmark suites locally:

# 1. Run detailed comparative benchmarks against CPython concurrency pools
PYTHONPATH=python:examples/benchmarks python3 examples/benchmarks/benchmark_vs_alternatives.py

# 2. Run basic scheduling latency and asyncio benchmarks
PYTHONPATH=python python3 examples/benchmarks/benchmark.py

Contributing

Contributions are welcome! If you'd like to improve Pyroxide or add support for additional features, feel free to open an issue or submit a pull request on GitHub.

License

Pyroxide is licensed under any of:

at your option.

Metadata

Release files for pyro3 0.8.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pyro3 0.8.3
File Size Uploaded Provenance Actions
pyro3-0.8.3.tar.gz 122.2 kB Without provenance Details for pyro3-0.8.3.tar.gz

Built distributions (wheels)

Table of built distributions (wheels) for pyro3 0.8.3
File Actions
pyro3-0.8.3-cp38-abi3-win_amd64.whl CPython 3.8 abi3 Windows x86-64 Details for pyro3-0.8.3-cp38-abi3-win_amd64.whl
pyro3-0.8.3-cp38-abi3-manylinux_2_39_x86_64.whl CPython 3.8 abi3 Linux glibc 2.39+ x86-64 Details for pyro3-0.8.3-cp38-abi3-manylinux_2_39_x86_64.whl
pyro3-0.8.3-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl CPython 3.8 abi3 Linux glibc 2.17+ ARM64 Details for pyro3-0.8.3-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
pyro3-0.8.3-cp38-abi3-macosx_11_0_arm64.whl CPython 3.8 abi3 macOS 11.0+ ARM64 Details for pyro3-0.8.3-cp38-abi3-macosx_11_0_arm64.whl
pyro3-0.8.3-cp38-abi3-macosx_10_12_x86_64.whl CPython 3.8 abi3 macOS 10.12+ x86-64 Details for pyro3-0.8.3-cp38-abi3-macosx_10_12_x86_64.whl

Total release size: 19.5 MB

Release files / pyro3-0.8.3.tar.gz

Download URL pyro3-0.8.3.tar.gz
Size 122.2 kB
Tags Source
SHA-256 checksum
How to use checksums
cd76eb482bd9f6cc97f1dcba1a57ff90d6bea813c9d8bf439fa364fb98abedf0
BLAKE2b-256 checksum
How to use checksums
626b23eb670cef5d975b4007cc68ef7704ce7039b548093166e4c18503210693
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via maturin/1.14.1

Release files / pyro3-0.8.3-cp38-abi3-win_amd64.whl

Download URL pyro3-0.8.3-cp38-abi3-win_amd64.whl
Size 3.4 MB
Tags CPython 3.8 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
98982b58df845f84acf0611d1c45ad0f9b8ded160ff7ad4c90c0e78cc38c9a43
BLAKE2b-256 checksum
How to use checksums
05de6374f7f50ab429466d9af0f17f776954f87cd5de5093f23c472df209bd52
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via maturin/1.14.1

Release files / pyro3-0.8.3-cp38-abi3-manylinux_2_39_x86_64.whl

Download URL pyro3-0.8.3-cp38-abi3-manylinux_2_39_x86_64.whl
Size 4.2 MB
Tags CPython 3.8 Linux glibc 2.39+ x86-64 abi3
SHA-256 checksum
How to use checksums
d3cb10065ee466d60e0bc21fefe4aff53bfe111b6ef59f4d9dac6ca9088d718e
BLAKE2b-256 checksum
How to use checksums
03f2ad3f499d2fedd752d2cbfadacf25c5a10af604de3e01aeb8a83fe23b9085
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via maturin/1.14.1

Release files / pyro3-0.8.3-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl

Download URL pyro3-0.8.3-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Size 4.1 MB
Tags CPython 3.8 Linux glibc 2.17+ ARM64 abi3
SHA-256 checksum
How to use checksums
26bbffbfb12f45ed33f37708e03d54252b45381b02bb491e103699722ab2040c
BLAKE2b-256 checksum
How to use checksums
8c4104f4f8690eedf803e0318becfa8be693def32b4b4438a51f92483ac8e5f6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via maturin/1.14.1

Release files / pyro3-0.8.3-cp38-abi3-macosx_11_0_arm64.whl

Download URL pyro3-0.8.3-cp38-abi3-macosx_11_0_arm64.whl
Size 3.8 MB
Tags CPython 3.8 abi3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
499f77a4ead584ec2b766934407dc1c89fdfb6222ebf47cd11342c1c6a82ef0d
BLAKE2b-256 checksum
How to use checksums
a4ea09b576f75486e178f75c2d19d13fedecea0995a0f136ce84706208242c5e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via maturin/1.14.1

Release files / pyro3-0.8.3-cp38-abi3-macosx_10_12_x86_64.whl

Download URL pyro3-0.8.3-cp38-abi3-macosx_10_12_x86_64.whl
Size 3.8 MB
Tags CPython 3.8 abi3 macOS 10.12+ x86-64
SHA-256 checksum
How to use checksums
a2ac8f6264bf4c10c32daf36486f19a1ffa41a6edb32aec31048fc98a9466281
BLAKE2b-256 checksum
How to use checksums
c13193db1fecf7df89c7e02930edf9d310ead3dac08eb7616431753c1d018248
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via maturin/1.14.1

Security for pyro3 0.8.3

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page