Firq — Multi-tenant Scheduler for Rust Services
Firq is an in-process scheduler for Rust backends that need stable tail latency under contention.
Key capabilities:
- Fair scheduling across tenants (DRR).
- Explicit backpressure and bounded memory behavior.
- Deadline-aware dequeue (
DropExpiredsemantics). - Metrics for queue saturation, drops, rejections, and queue-time percentiles.
firq-core is runtime-agnostic. firq-async adds Tokio support. firq-tower integrates with Tower/Axum.
Install
From crates.io
[]
= "0.1"
Tokio integration:
[]
= "0.1"
= "0.1"
Tower/Axum integration:
[]
= "0.1"
= "0.1"
= "0.1"
From source
Quick start
How to choose parameters
Use these as starting points, then tune with real traffic and stats() metrics.
shards: Start withmin(physical_cores, 8). Increase when many tenants are hot concurrently and enqueue lock contention is visible.max_globalandmax_per_tenant: Size from memory budget first. Approximate memory asmax_global * avg_task_size. Keepmax_per_tenantlow enough that one tenant cannot monopolize memory.quantumandcost: Treatcostas "work units" per task, andquantumas work units granted per round. If heavy jobs are starving, increasequantumor lower heavy-jobcostcalibration.deadlines: Use when stale work should be discarded (timeouts/SLO breaches). Expired items are removed lazily and should not permanently consume queue limits.- backpressure policy:
Rejectfor strict admission control,DropOldestPerTenant/DropNewestPerTenantfor lossy workloads,Timeoutwhen producers can wait briefly for capacity.
Queue limits are enforced against live pending work. Cancelled/expired entries are compacted lazily on dequeue and enqueue maintenance passes.
Core usage (firq-core)
Use this when workers are synchronous (threads) or when direct control over dequeue loops is required.
use ;
use HashMap;
use Instant;
let scheduler = new;
let tenant = from;
let task = Task ;
match scheduler.enqueue
match scheduler.dequeue_blocking
let stats = scheduler.stats;
println!;
Async usage (firq-async, Tokio)
Use this when producers/consumers are async and run under Tokio.
use ;
use Arc;
use Instant;
let core = new;
let scheduler = new;
let tenant = from;
let task = Task ;
match scheduler.enqueue
match scheduler.dequeue_async.await
// Dedicated worker alternative (avoids spawn_blocking per dequeue call).
let mut receiver = scheduler.receiver_with_worker;
while let Some = receiver.recv.await
Axum usage (firq-tower)
firq-tower provides a Tower layer that handles scheduling, cancellation before turn, in-flight gating, and rejection mapping.
use ;
use ;
let firq_layer = new
.with_shards
.with_max_global
.with_max_per_tenant
.with_quantum
.with_in_flight_limit
.
.build;
let app = new
.route
.layer;
Default rejection mapping:
TenantFull->429GlobalFull->503Timeout->503
Actix-web usage (manual scheduling gate)
Firq does not currently provide a first-party firq-actix crate.
Use firq-async in handlers or middleware to gate work before executing heavy logic:
use ;
use ;
use Instant;
;
async
Runnable Actix example in this repository:
crates/firq-examples/src/bin/actix_web.rs
Benchmarks
Run reproducible scenarios:
Scenarios:
hot_tenant_sustainedburst_massivemixed_prioritiesdeadline_expirationcapacity_pressure
Smoke run expectation:
hot_tenant_sustained: cold tenants should continue making progress (fairness).deadline_expiration: expired counter should increase when work misses deadlines.capacity_pressure: rejections/drops should rise as configured limits are reached.
Use these runs to compare parameter sets; do not treat a single run as a universal baseline.
Repository layout
crates/firq-core: scheduler engine.crates/firq-async: Tokio adapter.crates/firq-tower: Tower layer.crates/firq-examples: runnable examples (publish = false).crates/firq-bench: benchmark runner (publish = false).
Community and governance
- Contribution guide:
CONTRIBUTING.md - Security policy:
SECURITY.md - Support channels:
SUPPORT.md - Release process:
RELEASING.md
Local quality gates
Release dry-runs:
# after firq-core is published on crates.io:
# after firq-async is published on crates.io:
License
This project is dual-licensed under:
- MIT (
LICENSE-MIT) - Apache-2.0 (
LICENSE-APACHE)