Forge Orchestration
Rust-Native Orchestration Platform for Distributed Workloads
A high-performance orchestration platform for Rust, designed to manage distributed workloads at hyper-scale — with intelligent bin-packing, a closed reconcile → schedule → bind → persist control loop, and simulation/agent-native scheduling primitives (gang co-scheduling and tick-deadline ordering).
Performance Benchmarks
Measured on an Intel Core i9-10980XE (18C/36T @ 3.0 GHz), Windows 11, rustc 1.95.0,
release build via Criterion (30 samples, 2 s measurement). These are absolute
throughput numbers on one machine — not a comparison against Kubernetes (Forge does
not benchmark K8s here), and as wall-clock microbenchmarks on a non-isolated machine they
vary run-to-run (≈1.5×). Throughput = workloads ÷ median per-batch time. Reproduce:
Honest bind cycle — OptimizedScheduler, sequential commit path
Each call finds the best node and commits the allocation (decrements capacity in the node and the score cache). This is the number to quote for "how fast can we actually schedule and bind a workload?"
| Cluster | schedule + commit | + persist¹ | batch² (amortized) |
|---|---|---|---|
| 10 nodes | 0.22 µs (~4.6M/s) | 1.12 µs (~890K/s) | — |
| 50 nodes | 0.53 µs (~1.9M/s) | 1.73 µs (~580K/s) | 0.60 µs (~1.7M/s) |
| 100 nodes | 1.05 µs (~950K/s) | 1.95 µs (~510K/s) | 1.10 µs (~910K/s) |
| 500 nodes | 4.78 µs (~210K/s) | — | 4.77 µs (~210K/s) |
¹ adds serde_json serialization of the bind record + a MemoryStore write per
workload (approximates the etcd/state-store write a real control plane pays). The
~510K binds/s at 100 nodes is the most realistic single-workload figure.
² schedule_and_commit_batch over 500 workloads.
Monolithic Scheduler — full affinity / taint / preemption semantics
Fresh cluster, 500 workloads, per-workload median:
| Path | per-workload | throughput |
|---|---|---|
| bin-pack | 1.97 µs | ~507K/s |
| spread | 1.96 µs | ~510K/s |
| GPU-locality (20 nodes × 8 A100, GPU workloads) | 3.12 µs | ~320K/s |
Online LearnedScheduler score + feedback update: ~0.15 µs (~6.8M updates/s).
Resolved: schedule_fast is now sequential (an earlier Rayon path was a pessimization)
OptimizedScheduler::schedule_fast previously switched to Rayon par_iter above 16
nodes. Benchmarks showed that was a 40–300× pessimization for the trivial integer
scoring — the per-call fan-out cost dwarfed the work. The Rayon path (and the rayon
dependency) has been removed; schedule_fast now uses the same sequential scan as
schedule_fast_commit. Measured score_only, before vs after:
| Cluster | score_only before (Rayon) |
score_only now (sequential) |
|---|---|---|
| 50 nodes | 28.9 µs/wl (~35K/s) | 0.57 µs/wl (~1.8M/s) |
| 100 nodes | 36.9 µs/wl (~27K/s) | 1.05 µs/wl (~950K/s) |
| 500 nodes | 56.1 µs/wl (~18K/s) | 4.88 µs/wl (~205K/s) |
It now tracks schedule_commit within noise (scoring without committing does marginally
less work). This also retired the earlier "10–2000× faster than K8s / 1M decisions/sec"
numbers, which came from the non-committing scoring loop and did not reflect a real bind.
Genuine performance properties (confirmed by the numbers above)
- Integer-only scoring — the hot path is allocation-free
u32math, no floating point. - Pre-computed score cache —
schedule_fast_commitreads/decrements a cached view in O(nodes). - Sequential committing bind scales smoothly: ~1 µs/bind at 100 nodes, ~5 µs at 500 (no Rayon).
- First-Fit Decreasing bin-packing for utilization.
Features
| Feature | Description |
|---|---|
| High-Performance Scheduler | Parallel bin-packing / spread / GPU-locality scoring; allocations commit to node state |
| Reconcile Control Loop | Converges desired jobs onto actual assignments: schedule, persist-as-truth, release on scale-down / node loss, execute autoscaling |
| Sim/Agent-Native Scheduling | SimCell (world shard + agent policies as one unit), all-or-nothing gang co-scheduling, tick-deadline (EEVDF-style) ordering |
| Control Plane | Kubernetes-style API server with admission controllers and SSE watch streams |
| Durable State | In-memory / file (default); single-node Raft via openraft (opt-in raft feature). RocksDB/etcd backends are not yet implemented |
| Multi-Region Federation | Geo-aware routing and latency-based failover (cross-region replication is experimental / in-memory) |
| MoE Routing | Intelligent request routing with load-aware, GPU-aware, and version-aware strategies |
| Autoscaling | Threshold-based and target-utilization policies with hysteresis, executed by the reconcile loop |
| Resilience | Circuit breakers and exponential-backoff retry (opt-in on the Nomad client) |
| Game Server SDK | UDP/TCP port allocation, session management, spot instance handling |
| AI/ML Inference | Request batching, SSE streaming for LLM tokens |
Installation
[]
= "0.5"
= { = "1", = ["full"] }
Quick Start
Control Plane
use ;
async
Workload SDK
The SDK is included in the main crate under forge_orchestration::sdk:
use ;
async
Architecture
[User App] --> [Forge SDK] (ready(), allocate(), shutdown())
|
v
[Forge Control Plane]
- Tokio Runtime (async loops)
- Rayon (parallel alloc)
- Raft (single-node consensus, opt-in `raft` feature)
- State: in-memory / file (default), single-node Raft (opt-in); RocksDB + etcd planned
- MoE Router (gating to experts)
|
v
[Nomad Scheduler] (jobs: containers/binaries)
|
v
[Workers/Nodes]
- QUIC/TLS Networking
- Prometheus Metrics
API Reference
Modules
| Module | Description |
|---|---|
job |
Job, Task, TaskGroup, Driver definitions |
moe |
MoERouter trait, DefaultMoERouter, LoadAwareMoERouter, RoundRobinMoERouter |
autoscaler |
Autoscaler, AutoscalerConfig, ScalingPolicy trait |
nomad |
NomadClient for HashiCorp Nomad API |
storage |
StateStore trait, MemoryStore, FileStore |
networking |
HttpServer, QuicTransport |
metrics |
ForgeMetrics, MetricsExporter, MetricsHook trait |
sdk |
Workload SDK: ready(), allocate_port(), graceful_shutdown(), ForgeClient |
MoE Routing
Built-in routers:
DefaultMoERouter: Hash-based consistent routingLoadAwareMoERouter: Routes to least-loaded expert with affinityRoundRobinMoERouter: Sequential distribution
Custom router:
use ;
use async_trait;
;
Autoscaling
use AutoscalerConfig;
let config = default
.upscale_threshold
.downscale_threshold
.hysteresis_secs
.bounds;
Storage
use ;
let memory = new;
let file = open?;
Metrics
use ForgeMetrics;
let metrics = new?;
metrics.record_job_submitted;
metrics.record_scale_event;
let text = metrics.gather_text?;
SDK Functions
| Function | Description |
|---|---|
sdk::ready() |
Signal readiness to orchestrator |
sdk::allocate_port(range) |
Allocate an available port from range |
sdk::release_port(port) |
Release an allocated port |
sdk::graceful_shutdown() |
Install SIGTERM/SIGINT handlers |
sdk::shutdown_signal() |
Async wait for shutdown signal |
sdk::ForgeClient |
HTTP client for Forge API |
Environment Variables
| Variable | Description |
|---|---|
FORGE_API |
Forge API endpoint for SDK |
FORGE_ALLOC_ID |
Allocation ID (set by orchestrator) |
FORGE_TASK_NAME |
Task name (set by orchestrator) |
Builder Configuration
use ForgeBuilder;
new
.with_nomad_api
.with_nomad_token
.with_store_path
.with_node_name
.with_datacenter
.with_autoscaler
.with_metrics
.build?
License
Apache 2.0