Skip to main content

Fast zero-copy config file loading using rkyv

Project description

snapconfig banner

Superfast config loader for Python, powered by Rust + rkyv.
See benchmarks below.

PyPI Python 3.9+ License CI

What it does

  • Parses JSON / YAML / TOML / INI / .env, compiles once, then memory‑maps the cache
  • Zero-copy reads via Rust rkyv + mmap, so repeated loads stay fast and page-shared across processes
  • Dict-like access in Python ([], .get, in, len, iteration) plus dot-notation lookup
  • Cache freshness check on load; caches are written atomically to avoid torn files

Inspiration

  • Need for superfast loading of large JSON files and other configs across processes/workers in AI workflow orchestrators.
  • uv package manager, which uses rkyv to deserialize cached data without copying.

Installation

pip install snapconfig

Quick start

import snapconfig

# Load any config format, automatically cached on first load
config = snapconfig.load("config.json")
config = snapconfig.load("config.yaml")
config = snapconfig.load("pyproject.toml")
config = snapconfig.load("settings.ini")

# Access values like a dict
db_host = config["database"]["host"]
db_port = config.get("database.port")  # dot notation supported

# Load .env files
env = snapconfig.load_env(".env")
snapconfig.load_dotenv(".env")  # populates os.environ

How it works

First load:    config.json → parse → compile → config.json.snapconfig (cached)
                                                    ↓
Subsequent:                              mmap() → zero-copy access (~30µs)
  1. First load: Parses source file and compiles to optimized binary cache
  2. Subsequent loads: Memory-maps the cache file for instant zero-copy access

The cache file is automatically regenerated when the source file changes.

Benchmarks (local run)

Benchmark chart
Benchmark table

Numbers from running pipenv run python benchmark.py on an M3 Pro (see benchmark.py for exact scenarios).

Takeaways:

  • Cached reads stay in the low milliseconds down to tens of microseconds; big files benefit most.
  • Cold loads beat YAML/ENV/TOML parsers; Python’s json still wins cold, but cached loads dominate.

When snapconfig shines

  • CLI tools that start frequently
  • Serverless functions with cold starts
  • Multiple worker processes reading the same config
  • Large config files (package-lock.json, monorepo configs)

Cold vs cached

Scenario What Happens vs JSON vs YAML/TOML/ENV
Cold (first load) Parse + compile + write cache Slower 3-170x faster
Cached (subsequent) mmap() only 3-5,000x faster 50-7,000x faster

Cold loads are slower than Python's json module (it's highly optimized C code), but faster than pyyaml, tomllib, and python-dotenv. The real payoff comes on cached loads.

Supported formats

Format Extensions Parser
JSON .json simd-json
YAML .yaml, .yml serde_yaml
TOML .toml toml
INI .ini, .cfg, .conf rust-ini
dotenv .env, .env.* custom

API Reference

Loading

# Load with automatic caching (recommended)
config = snapconfig.load("config.json")
config = snapconfig.load("config.json", cache_path="custom.snapconfig")
config = snapconfig.load("config.json", force_recompile=True)

# Load directly from cache (skips freshness check)
config = snapconfig.load_compiled("config.json.snapconfig")

# Parse string content (no caching)
config = snapconfig.loads('{"key": "value"}', format="json")
config = snapconfig.loads("key: value", format="yaml")

dotenv support

# Load .env with caching
env = snapconfig.load_env(".env")
env = snapconfig.load_env(".env.production")

# Load into os.environ
count = snapconfig.load_dotenv(".env")
count = snapconfig.load_dotenv(".env", override_existing=True)

# Parse .env string
env = snapconfig.parse_env("KEY=value\nDEBUG=true")

Cache management

# Pre-compile config (e.g., during Docker build)
snapconfig.compile("config.json")
snapconfig.compile("config.json", "config.snapconfig")

# Check cache status
info = snapconfig.cache_info("config.json")
# {'source_exists': True, 'cache_exists': True, 'cache_fresh': True, ...}

# Clear cache
snapconfig.clear_cache("config.json")

SnapConfig object

config = snapconfig.load("config.json")

# Dict-like access
config["database"]["host"]
config["database"]["port"]

# Dot notation for nested access
config.get("database.host")
config.get("database.port", default=5432)

# Iteration
for key in config:
    print(key, config[key])

# Membership
"database" in config  # True

# Info
len(config)           # Number of keys
config.keys()         # List of keys
config.to_dict()      # Convert to Python dict
config.root_type()    # "object", "array", etc.

Cross-process benefits

When multiple processes load the same cached config:

# Worker 1, Worker 2, Worker 3...
config = snapconfig.load("config.json")  # All share same memory pages

The operating system's virtual memory system ensures all processes share the same physical memory pages via mmap(). This is particularly useful for:

  • Prefect/Celery workers
  • Gunicorn/uWSGI workers
  • Multiprocessing pools
  • Serverless function instances

Pre-compilation

For production deployments, pre-compile configs during build:

# Dockerfile
RUN python -c "import snapconfig; snapconfig.compile('config.json')"
# CI/CD
- run: python -c "import snapconfig; snapconfig.compile('config.json')"

This ensures the first load in production is already cached.

Acknowledgements

snapconfig is built on:

  • rkyv - Zero-copy deserialization framework for Rust
  • PyO3 - Rust bindings for Python
  • simd-json - SIMD-accelerated JSON parser
  • maturin - Build and publish Rust Python extensions

License

MIT

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

snapconfig-0.5.0.tar.gz (320.1 kB view details)

Uploaded Source

Built Distribution

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

snapconfig-0.5.0-cp312-cp312-macosx_12_0_arm64.whl (607.2 kB view details)

Uploaded CPython 3.12macOS 12.0+ ARM64

File details

Details for the file snapconfig-0.5.0.tar.gz.

File metadata

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

File hashes

Hashes for snapconfig-0.5.0.tar.gz
Algorithm Hash digest
SHA256 745df330bdb79a1ae761e84e0c5c2e7ab2857759fa30afc1d5470c383aaa23dd
MD5 ec93d7b8abad3b2f879919f160784648
BLAKE2b-256 04473a00f58c6775c8ba6cab9116468292482b1aa6a9ee4f0e0e6747fc0668bd

See more details on using hashes here.

File details

Details for the file snapconfig-0.5.0-cp312-cp312-macosx_12_0_arm64.whl.

File metadata

File hashes

Hashes for snapconfig-0.5.0-cp312-cp312-macosx_12_0_arm64.whl
Algorithm Hash digest
SHA256 45e2c08554382cb7d84b4810859dc192c262800e39e0c0f43040239cf998e56a
MD5 f96310eb1f2e59f40101a808e1a916c5
BLAKE2b-256 1aa16e3a9d87c76b6efb455b88cae96a4d4dea4d5444bd86a5f4a29450613cef

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