Skip to main content

Resource Semaphore

License Python Python Coverage

Resource Semaphore is a typed, high-level synchronization library for managing multiple constrained resources within a single process. It applies backpressure to prevent resource exhaustion.

Standard semaphores guard a single counter of "slots." resource-semaphore extends this to multiple, heterogeneous resources: such as CPU cores, available RAM, disk I/O bandwidth, or worker slots: with a single, atomic acquire/release operation. When capacity is exhausted, callers block until resources become available.

Installation

pip install resource-semaphore

Quick Start

import asyncio
from resource_semaphore import AsyncResourceSemaphore

semaphore = AsyncResourceSemaphore(resources={"db_conn": 2, "ram_mb": 4096})


async def process(data_size_mb: int):
    async with semaphore.claim({"db_conn": 1, "ram_mb": data_size_mb}):
        await do_work()


async def main():
    # Three tasks compete for 2 DB connections: one will wait automatically
    await asyncio.gather(
        process(1024),
        process(1024),
        process(1024),
    )

Features

  • Multi-resource: atomically acquire multiple named resources (e.g. DB connections, RAM, workers) in one call
  • Sync + Async: ResourceSemaphore (threading) and AsyncResourceSemaphore (asyncio) share the same API
  • Fair and Greedy variants: Fair semaphores wake the earliest-arrived request that can currently be satisfied, and let smaller later requests bypass a blocked larger one — see Docs: Fairness and Trade-offs for the starvation trade-off this implies. Greedy semaphores skip ordering entirely and grant to whichever caller wins the race; this can starve a specific waiter indefinitely under sustained contention (see Docs: Fairness and Trade-offs).
  • Timeouts: acquire()/claim() accept an optional timeout argument and raise TimeoutError
  • Safe releases: opaque Ticket objects; releasing an unknown or already-released ticket raises ValueError
  • Typed: generic over resource key types via Literal for compile-time safety
  • No-op variants: NoopResourceSemaphore and AsyncNoopResourceSemaphore for tests that don't need real limits
  • Graceful shutdown: shutdown() wakes all blocked callers with SemaphoreError; further acquire() calls raise immediately
  • Zero dependencies in core
  • Optional system utilities: resource-semaphore[utils] wraps psutil for CPU/RAM/disk capacity discovery (CPU and RAM only — no GPU support)
  • Performance: Fair and Greedy variants show no measurable throughput difference in our benchmarks (see .benchmarks/); Greedy trades ordering guarantees for a simpler code path, not raw speed.

Limitations

  • Single-process only: Manages concurrency within a single Python process (threads or asyncio tasks). It is not a distributed or cross-process semaphore.
  • Resource discovery limits: Built-in utilities (resource-semaphore[utils]) only discover basic CPU, memory, and disk metrics via psutil. There is no automatic discovery for GPUs, network interfaces, or custom external hardware (though any named resource can be managed by manually specifying integer capacities).
  • No deadlock prevention: Does not detect or prevent application-level deadlocks resulting from improper lock acquisition ordering across multiple semaphores or code paths.
  • Evolving API: The API is subject to refinement; minor version updates may introduce breaking changes as feature needs evolve.

Documentation

For a comprehensive guide on core concepts, initialization, and API usage (including both synchronous and asynchronous context managers), please refer to our documentation:

Examples

We provide runnable scripts demonstrating real-world usage scenarios:

Roadmap

To see what features are planned for future releases and what has already been accomplished, check out our TODO.md tracker.

Metadata

Release files for resource-semaphore 1.4.0

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

Source distribution (sdist)

Source distribution for resource-semaphore 1.4.0
File Size Uploaded Provenance
resource_semaphore-1.4.0.tar.gz 13.2 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for resource-semaphore 1.4.0
File Interpreter ABI Platform
resource_semaphore-1.4.0-py3-none-any.whl Python 3 none any Details

Total release size: 28.8 kB

Release files / resource_semaphore-1.4.0.tar.gz

Download URL resource_semaphore-1.4.0.tar.gz
Size 13.2 kB
Tags Source
SHA-256 checksum
How to use checksums
7b572556487fdfdabc60e2aefbcd522365eca46774244436a67f143d9104aaf2
BLAKE2b-256 checksum
How to use checksums
803a26490ced8ace54f41ffe1127dc5be2dd495025d8c386686c25d5da624d9e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.13.5 {"installer":{"name":"uv","version":"0.13.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / resource_semaphore-1.4.0-py3-none-any.whl

Download URL resource_semaphore-1.4.0-py3-none-any.whl
Size 15.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
117b42495eccb3b8f227e9969d5f59c39775ec79fd871e5b6f169d53de266432
BLAKE2b-256 checksum
How to use checksums
194d3e4a79dd4cc5370bb203ed0e715b02a3d46a94f580e877c8b301da23552a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.13.5 {"installer":{"name":"uv","version":"0.13.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Security for resource-semaphore 1.4.0

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