xRPC-rs
Local-first async RPC and IPC library for Rust with a consistent interface across in-process, shared-memory, Unix socket, and TCP transports.
Designed primarily for communication between threads and processes on the same machine, while allowing the same RPC model to extend over TCP to trusted networks and small-scale service deployments.
Start locally with Channel, Arc, shared memory, or Unix sockets, then move the same RPC interface to TCP when services need to span multiple hosts.
Status: Actively developed. Core features are available, and the API may change between releases.
Quick Start
This single-process example uses an in-process channel pair. The same RPC layer can run across local processes over shared memory or Unix sockets, or across hosts over TCP, by replacing the frame transport. Transport configuration and deployment lifecycle differ, but application-level handlers and RPC calls keep the same model.
use ;
use ;
async
Calling try_start() is required before making RPCs. Retaining its handle is optional for ordinary calls, but it enables explicit receive-task joining and forced shutdown. This example retains it for strict cleanup confirmation.
Ordinary unary calls use the client's response timeout. To wait without an application-level response deadline, use explicit call options:
use CallOptions;
let response: AddResponse = client
.call_with_options
.await?;
This disables only the RPC response deadline; configured transport I/O timeout policies remain in effect. Client close, terminal connection failure, and dropping the call future still end the local wait, but they do not cancel work already running on the server.
Installation
[]
= "0.3.1"
= { = "1", = ["derive"] }
= { = "1", = ["macros", "rt-multi-thread"] }
To enable an optional codec, replace the xrpc-rs dependency above with, for example:
= { = "0.3.1", = ["codec-messagepack"] }
Available codec features are codec-messagepack, codec-cbor, codec-postcard, and codec-all. Bincode and JSON support are available without optional features.
xrpc-rs 0.3 requires Rust 1.85 or newer.
Status
| Feature | Status |
|---|---|
| FrameTransport Layer (TCP, Unix, SharedMemory, Channel, Arc) | ✅ Completed |
| MessageChannel with compression | ✅ Completed |
| RPC Client/Server | ✅ Completed |
| Streaming | ✅ Completed |
| Connection Pooling | ✅ Completed |
| Service Discovery & Load Balancing | ✅ Completed |
| Docs & Examples | In Progress |
| Python Bindings | Under Consideration |
Architecture
xRPC follows a layered architecture:
| Layer | Trait/Module | Description |
|---|---|---|
| Layer 1 | FrameTransport |
Low-level byte transmission with framing |
| Layer 2 | MessageChannel |
Message-aware channel with compression |
| Layer 3 | RpcClient/RpcServer |
RPC with method dispatch, streaming |
| Layer 4 | LoadBalancer |
Service discovery, load balancing |
Application
↓
LoadBalancedClient (Layer 4)
↓
RpcClient/RpcServer (Layer 3)
↓
MessageChannel (Layer 2)
↓
FrameTransport (Layer 1)
↓
In-process / Local IPC / TCP
Transport Comparison
| Transport | Typical Use | Cross-Process | Cross-Host | Serialization |
|---|---|---|---|---|
ChannelFrameTransport |
Same-process async communication / testing | No | No | Yes |
ArcFrameTransport |
Same-process typed fast path | No | No | Frame/RPC: Yes; ZeroCopyTransport: No |
SharedMemoryFrameTransport |
Low-latency local IPC, one client per named server | Yes | No | Yes |
UnixFrameTransport |
Local IPC on Unix systems | Yes | No | Yes |
TcpFrameTransport |
Loopback, trusted LAN, small-scale services | Yes | Yes | Yes |
TCP transport does not provide TLS, authentication, or authorization. Use it within a trusted network or behind an appropriate security boundary.
Load Balancing
Distribute requests across local worker processes or small service instances:
use ;
use async_trait;
use Arc;
;
// Setup load balancer
let endpoints = vec!;
let discovery = new;
let lb = new;
let client = new;
client.init.await?;
// Calls are distributed across workers or service instances.
// Setup failures can fail over before invocation.
let response: Response = client.call.await?;
client.close.await?;
Strategies: RoundRobin, Random, LeastConnections, WeightedRoundRobin, ScoreBased
Features:
- Failover for endpoint selection, connection creation, and startup failures
- No automatic retry after RPC invocation, preventing duplicate non-idempotent calls
- Stream affinity (streaming calls stay on same server)
- Failure-based health tracking with configurable thresholds
- DNS-based discovery; periodic refresh and discovery watching are started explicitly
Documentation
Reference
- Message Protocol - binary framing and payload encoding
- Client Lifecycle - start, close, join, and forced shutdown
- Transport Shutdown - close and terminal error contract
Migration
- Migrating to 0.3 - lifecycle, error matching, and wire compatibility changes
Planned:
- Transport layer guide
- Client/Server usage guide
- Streaming guide
- Discovery & load balancing guide
- Codec guide (Bincode, JSON, MessagePack, CBOR, Postcard)
- Architecture overview & getting started
Examples
RPC Client/Server
# Terminal 1
# Terminal 2
SharedMemory Transport
# Terminal 1
# Terminal 2
Byte-level Transports
Planned:
examples/load_balancing.rs- Discovery and load-balanced RPCexamples/streaming.rs- Server streaming RPCexamples/compression.rs- LZ4/Zstd compressionexamples/custom_codec.rs- JSON/MessagePack codec usage
Used In
- quant-system — A modular workspace for algorithmic trading — real-time market data, strategy execution, and analysis.
License
MIT License - see LICENSE for details.