Railscale
High-performance Rust HTTP reverse proxy built on zero-cost abstractions. All generics are monomorphized — no trait objects or vtable dispatch in the hot path.
Workspace Structure
| Crate | Role |
|---|---|
| train_track | Core framework: protocol-agnostic traits, Pipeline orchestrator, routing, error types |
| carriages | Protocol implementations: HTTP parsing/rewriting, TCP source/destination/router |
poc | Python proof-of-concept (historical) |
conductor | Future orchestration layer (stub) |
Architecture
Client -> TcpSource::accept()
-> FrameParser::parse() (async Stream<ParsedData>)
-> FramePipeline::process() (header rewriting)
-> DestinationRouter::route() (concurrent with parsing)
-> StreamDestination::write() (forward bytes)
-> StreamDestination::relay_response() (pipe back to client)
Concurrent Pipeline
Once the first routing frame arrives,
do_connectionusestokio::join!to route (connect upstream) in parallel with continued frame parsing. See Railscale Connection Lifecycle.
Key Design Decisions
- Protocol-agnostic destinations:
StreamDestinationwritesBytes, notFrame. Protocol knowledge stays in the parser/pipeline layer. - First-class routing:
DestinationRoutertrait is an async factory that produces connected destinations from routing keys (&[u8]). - SIMD domain matching:
MatchStrategyuses memchr/memmem for Exact/Suffix/Prefix/Contains matching. - Parallel header rewriting:
HttpPipelineuses rayon for concurrent header matching across rules. - Monomorphized generics:
Pipeline<Src, Par, Pip, Rtr>— compiler generates specialized code per concrete type combination.
Performance
At 500 req/s against a local upstream (2-byte response):
- p50: ~436us
- p99: ~2.5ms
- 99.98% success rate
Feature Flags
metrics-minimal— OpenTelemetry counters and histogramsmetrics-full— Per-request sampler with detailed timing breakdown