nexus-slot
A high-performance SPSC conflation slot for "latest value wins" scenarios.
Overview
nexus-slot provides a single-value slot optimized for the common pattern where only the most recent value matters: market data snapshots, sensor readings, configuration updates, position state, etc.
- Writer overwrites with newest data (never blocks)
- Reader gets each new value exactly once
- Old values are silently discarded (conflated)
Performance
Benchmarked on Intel Core Ultra 7 155H, pinned to physical cores with turbo disabled:
| Implementation | p50 Latency | Notes |
|---|---|---|
| nexus-slot | 159 cycles (59 ns) | SPSC only |
seqlock crate |
355 cycles (132 ns) | Supports multiple writers |
ArrayQueue(1) |
540 cycles (201 ns) | General-purpose bounded queue |
The 2.2x speedup over seqlock comes from specializing for single-producer:
- No writer contention → no CAS loops
- Cached sequence number → writer avoids atomic load
- No queue machinery → just a sequence counter
Usage
use ;
let = ;
// Writer side (e.g., market data thread)
writer.write;
writer.write; // Overwrites previous
// Reader side (e.g., trading logic thread)
let quote = reader.read; // Gets sequence 2, skipped 1
assert_eq!;
// Already consumed - returns None until next write
assert!;
Semantics
Conflation
Multiple writes before a read result in only the latest value being observed:
writer.write;
writer.write;
writer.write;
// Reader only sees value_3
assert_eq!;
assert!;
Exactly-Once Delivery
Each written value can be read at most once:
writer.write;
assert!; // Consumes it
assert!; // Already consumed
writer.write;
assert!; // New value available
Check Without Consuming
if reader.has_update
The Pod Trait
Types must implement Pod (Plain Old Data) — no heap allocations or drop glue.
Any Copy type automatically implements Pod:
// These work automatically
let = ;
let = ;
let = ;
For non-Copy types that are still just bytes:
use Pod;
// SAFETY: OrderBook is just bytes, no heap allocations
unsafe
let = ;
Pod requirements:
- No
Vec,String,Box,Arc, or other heap types - No
File,TcpStream,Mutex, or other resources std::mem::needs_drop::<T>()must befalse
API
Writer
| Method | Description |
|---|---|
write(value) |
Overwrite with new value (never blocks) |
is_disconnected() |
Returns true if reader was dropped |
Reader
| Method | Description |
|---|---|
read() -> Option<T> |
Get latest value if new, consuming it |
has_update() -> bool |
Check for new data without consuming |
is_disconnected() |
Returns true if writer was dropped |
Use Cases
Good fit:
- Market data distribution (quotes, trades, order book snapshots)
- Sensor data (temperature, position, velocity)
- Configuration/state broadcasting
- Any "latest value wins" SPSC scenario
Not ideal for:
- Multiple writers → use
seqlockor mutex - Multiple readers → use
arc-swaporRwLock - Queue semantics (all values must be delivered) → use
nexus-queue - Async/await → use
tokio::sync::watch
Implementation
Uses a sequence lock (seqlock) internally:
- Writer increments sequence to odd (write in progress)
- Writer copies data
- Writer increments sequence to even (write complete)
- Reader loads sequence, copies data, checks sequence unchanged
- If sequence changed during read, retry
The SPSC constraint allows caching the sequence on the writer side, eliminating an atomic load per write.
Thread Safety
Writer<T>isSend(can move to another thread)Reader<T>isSend(can move to another thread)- Neither is
Sync— each handle is for one thread only
License
MIT OR Apache-2.0