Scepter
Composable Rust primitives for large-scale time-series routing, indexing, aggregation, and query planning.
scepter is a small library for building observability, metrics, stream
processing, and distributed query systems. It packages the kinds of low-level
building blocks described in the public Monarch paper into independent Rust
APIs: ordered keys, range assignment, field-hint indexes, histogram-like
distributions, collection aggregation, ingest routing, pushdown planning, and
standing-query sharding.
The crate is inspired by Monarch-style system design, but it is not Google Monarch and does not depend on any Google service or internal API. The name keeps the theme without claiming ownership: a scepter is the control instrument of a monarch; this crate focuses on control-plane and data-plane primitives for distributed time-series systems.
Use Cases
- Route metric writes to shards by lexicographic target ranges.
- Prune distributed query fanout with compact field-hint indexes.
- Represent and merge distribution-valued metrics with exemplars.
- Turn cumulative points into delta windows.
- Aggregate ingestion streams before storage.
- Finalize bucketed delta aggregates behind an admission window.
- Select query replicas by coverage, density, completeness, and recovery state.
- Attach partial-result health metadata to degraded distributed queries.
- Export hot-path data as Apache Arrow batches behind an optional feature.
- Use Roaring-backed numeric field hints for compressed postings.
- Encode compact CBOR/Zstd wire payloads behind optional features.
- Split logical query plans into leaf, zone, and root execution fragments.
- Shard periodic standing queries across evaluator workers.
Install
Or add it manually:
[]
= "0.1"
Quick Example
use ;
let mut ranges = new;
ranges.assign?;
ranges.assign?;
assert_eq!;
let mut index = new;
index.insert_value;
let candidates = index.candidates;
assert!;
# Ok::
Distribution Metrics
use ;
let layout = fixed_width?;
let mut latency = from_layout;
latency.record?;
latency.record?;
assert_eq!;
assert!;
# Ok::
Collection Aggregation
use ;
let mut iops =
with_reducer?;
iops.ingest?;
iops.ingest?;
let finalized = iops.advance_to;
assert_eq!;
assert_eq!;
assert_eq!;
# Ok::
Query Reliability
use ;
let resolved = with_max_fallbacks.resolve;
assert_eq!;
assert_eq!;
let mut health = with_expected_children;
health.record_completed;
health.push_issue;
assert!;
assert_eq!;
Primitive Families
scepter is organized by concern:
key: ordered key encoding withLexicographicKeyandKeyEncoder.model: schema-rich time-series types such asTargetSchema,MetricSchema,TimeSeriesKey,MetricKind, andLocationResolver.shard: range assignment, range load scoring, worker lookup, reassignment, and range splitting.hint: compact field-hint indexing with trigrams, n-grams, full-string excerpts, predicates, intersections, and unions.distribution: bucket layouts, distribution values, exemplars, cumulative points, percentile estimates, and delta windows.aggregate: distributed aggregation traits,Sum, andCollectionAggregator.collect: bucketed delta aggregation with admission windows, finalized buckets, load-smearing offsets, and pluggable reducers.ingest: write envelopes, stale-write drop policy, and range-based ingest routing.query: logical plans, execution levels, fanout plans, and pushdown fragments.reliability: replica quality ranking, primary/fallback replica resolution, and partial-result query health metadata.standing: periodic standing queries and stable evaluator sharding.
Performance Features
The default crate has no runtime dependencies. Optional features enable interchange and compression formats for high-volume paths:
[]
= { = "0.1", = ["arrow", "compressed-postings", "wire"] }
arrow: Apache ArrowRecordBatchexporters for finalized buckets, replica candidates, and query-health issues.compressed-postings:NumericFieldHintIndex, a Roaring-backed field-hint index for stableu32child ordinals and dense set operations. The genericFieldHintIndexremains faster for tiny singleton-style candidate lookups.cbor: compact CBOR helpers for wire payloads.zstd: Zstandard compression helpers.wire: convenience feature enablingcborandzstdtogether.
Design Principles
- No runtime dependencies for the library itself.
- Recoverable invalid input is returned as
Result, not exposed as public API panics. unsafeis forbidden.- Public API documentation is required by
#![deny(missing_docs)]. - Public error types implement
std::error::Error. - APIs are small and composable instead of tied to one database runtime.
- Tests include unit tests, property tests, and mutation-regression tests.
What This Crate Is Not
scepter is not a complete time-series database. It does not provide storage,
replication, networking, persistence, query parsing, or a hosted service. It is
the reusable primitive layer you can use while building those systems.
Test Strategy
Scepter uses three layers of tests:
- Example-sized unit tests live beside each module.
- Property tests in
tests/properties.rscheck invariants over generated inputs. - Mutation-regression tests in
tests/mutation_regression.rslock down behavior that mutation testing has proven easy to under-specify.
The current mutation suite catches every viable mutant reported by
cargo-mutants.
Quality gates used before publishing:
Benchmarking
Critical-path benchmarks live in benches/critical_paths.rs and use
Criterion. They cover:
- sortable key encoding
- range assignment lookup and splitting
- field-hint indexing and candidate pruning
- distribution record, merge, percentile, and delta operations
- collection aggregation and bucketed delta finalization
- query pushdown planning
- replica resolution
- standing-query evaluator sharding
Run them with:
The first benchmark pass exposed a slow field-hint candidate path. Switching candidate intersection to start from the smallest posting list improved exact trigram lookup from millisecond-scale to low-microsecond-scale in the 10k-value benchmark.
Worked Example
The mini_engine example wires the primitives together into a small
observability-engine flow: route an encoded write, index field hints, prune
query fanout, split a logical query into pushdown fragments, and merge
distribution-valued leaf results.
Run it with:
Book
The mdBook guide is published at https://copyleftdev.github.io/scepter/.
Local docs workflow:
License
Licensed under either of:
- Apache License, Version 2.0
- MIT license
at your option.