hotswap-config
A high-performance, hot-reloadable configuration store with wait-free reads and transactional updates for Rust applications.
Core Features
- Wait-free reads via atomic pointer swap (
ArcSwappattern) - readers never block - File watching (cross-platform,
notifycrate) with automatic reload - Subscribers: Register callbacks for async/sync notifications on config changes
- Validation + atomic rollback: Invalid configs are rejected; readers never see partial state
Advanced Features (Optional)
- Partial updates: RFC 6902 JSON Patch for surgical field changes (feature:
partial-updates) - Versioned history: Point-in-time rollback with timestamps (feature:
rollback) - Gradual rollout / A/B testing: Percentage-based, key-scoped canary deployment (feature:
gradual-rollout) - Remote HTTP sources: Fetch config from HTTP(S) endpoints with Bearer/Basic auth (feature:
remote) - OpenTelemetry metrics: Track reload success/failures, latency, config age (feature:
metrics)
Performance (Benchmarked)
Test System: Apple MacBook Pro (M3 Pro, 12-core, 18GB unified memory), macOS 26.0.1, Rust 1.87.0
Build: cargo bench --release (LTO=true, opt-level=3, codegen-units=1)
Methodology: Criterion 0.5, 100 samples, warm L3 cache
| Metric | Result | Notes |
|---|---|---|
| Read latency (median) | 7.16 ns/read | Single-threaded, warm cache |
| Read latency (mean) | 7.43 ns/read | Sub-10ns target achieved |
| Throughput (1 thread) | 206M reads/sec | = 206 million operations/sec |
| Throughput (16 threads) | 229M reads/sec total | = 14.4M reads/sec/thread |
| Config clone | 7.86 ns | Cheap Arc clone |
| Reload under load | 0 dropped reads | Zero downtime validated |
Readers are wait-free:
ArcSwap::load()is a single atomic read. Writers build new config off-to-the-side, validate, then atomically swap. Old readers continue using the previousArcuntil dropped.
See benches/README.md for full methodology, CPU governor settings, and raw criterion reports.
Quick Start
Add to Cargo.toml:
[]
= "0.1"
= { = "1.0", = ["derive"] }
= { = "1.0", = ["full"] }
10-line working example:
use *;
use Deserialize;
async
With partial updates (JSON Patch):
// Feature: partial-updates
config.update_field.await?; // Atomic update with validation
Feature Flags
| Feature | Description | Dependencies |
|---|---|---|
file-watch |
Auto-reload on file changes (default) | notify, tokio |
validation |
Config validation trait (default) | - |
yaml |
YAML file format support | serde_yaml |
toml |
TOML file format support | toml |
json |
JSON file format support | serde_json |
all-formats |
Enable all formats | - |
partial-updates |
JSON Patch (RFC 6902) | json-patch, tokio |
rollback |
Version history & rollback | chrono, tokio |
gradual-rollout |
A/B testing & canary | fastrand, tokio |
remote |
HTTP(S) config sources | reqwest, tokio |
metrics |
OpenTelemetry metrics | opentelemetry |
Default features: file-watch, validation
Enable features in Cargo.toml:
[]
= { = "0.1", = ["partial-updates", "rollback", "yaml"] }
Configuration Sources & Precedence
Config sources are merged by priority (highest wins):
- Environment variables (priority: 300) -
APP_SERVER__PORT=8080 - Remote HTTP sources (priority: 250, if enabled)
- Environment-specific files (priority: 110+) -
config/production.yaml - Default files (priority: 100) -
config/default.yaml
Supported Formats
- YAML (.yaml, .yml) - Feature:
yaml - TOML (.toml) - Feature:
toml - JSON (.json) - Feature:
json
Format detected automatically by file extension.
Safety & Failure Modes
Validation
- When: Before initial load and before every update/reload
- What: Custom validation functions (
Fn(&T) -> Result<(), ValidationError>) - Failure: Validation errors reject the update; readers continue using old config
- Guarantee: Readers never see invalid or partial config state
Remote HTTP Sources (feature: remote)
- TLS: Supports HTTPS with native TLS roots (
rustls,native-certs) - Authentication: Bearer token or Basic auth
- Retry/backoff: On network errors, keeps last-known-good config
- Security: Does not currently support certificate pinning or config signatures (planned for v0.2.0)
File Watching
- Cross-platform: Uses
notifycrate (inotify/kqueue/FSEvents) - Debouncing: 500ms default (configurable) to avoid rapid reloads
- Error handling: File watch errors log but don't crash; manual
reload()still works
Testing & QA
- ✅ 80+ unit & integration tests - All feature combinations covered
- ✅ Concurrency tests - Validated with Tokio test framework
- ✅ Property-based tests - Using
proptestfor validation logic - ✅ CI Matrix - GitHub Actions on Linux, macOS (ARM64)
- ✅ 6 runnable examples -
examples/directory with full scenarios
Running Tests
# All tests with all features
# Specific feature combinations
# No default features
Running Examples
# Service configuration (comprehensive example with validation)
# Hot reload demonstration
# Subscriber notifications
# Partial updates
# Rollback demonstration
# Gradual rollout
# Remote HTTP source
Documentation
- API Documentation: docs.rs/hotswap-config
- Examples:
examples/directory - Design Document:
DESIGN.md - Contributing:
CONTRIBUTING.md - Changelog:
CHANGELOG.md
Comparison with Other Crates
| Feature | hotswap-config | config | figment | confy |
|---|---|---|---|---|
| Wait-free reads | ✅ (ArcSwap) | ❌ | ❌ | ❌ |
| Hot reload | ✅ | ❌ | ❌ | ❌ |
| File watching | ✅ | ❌ | ❌ | ❌ |
| Validation | ✅ | Limited | ✅ | ❌ |
| Atomic updates | ✅ | ❌ | ❌ | ❌ |
| Rollback | ✅ | ❌ | ❌ | ❌ |
| Partial updates | ✅ | ❌ | ❌ | ❌ |
| Remote sources | ✅ | ❌ | Limited | ❌ |
| Metrics | ✅ | ❌ | ❌ | ❌ |
| Type-safe | ✅ | ✅ | ✅ | ✅ |
Platform Support
- Platforms: Linux, macOS, Windows (via
notifycrate) - MSRV: Rust 1.87.0 (edition 2024)
- no_std: Not supported (requires
std::sync::Arc, tokio runtime)
License
Licensed under either of:
- Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
at your option.
Contribution
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.
Acknowledgments
- Built on the excellent
arc-swapcrate for lock-free atomic updates - Configuration parsing via
configcrate - File watching via
notifycrate - Pattern proven at scale in production microservices handling 1M+ permission checks/second
Status: v0.1.0 - Production-ready, API stable
Built with ❤️ by Daniel Curtis