| Crates.io | nexus-slot |
| lib.rs | nexus-slot |
| version | 0.1.2 |
| created_at | 2026-01-02 02:29:08.202013+00 |
| updated_at | 2026-01-02 17:54:05.280033+00 |
| description | High-performance SPSC conflation slot for latest-value-wins scenarios |
| homepage | |
| repository | https://github.com/Abso1ut3Zer0/nexus |
| max_upload_size | |
| id | 2017836 |
| size | 71,360 |
A high-performance SPSC conflation slot for "latest value wins" scenarios.
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.
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:
use nexus_slot::{slot, Pod};
#[derive(Copy, Clone, Default)]
struct Quote {
bid: f64,
ask: f64,
sequence: u64,
}
let (mut writer, mut reader) = slot::<Quote>();
// Writer side (e.g., market data thread)
writer.write(Quote { bid: 100.0, ask: 100.05, sequence: 1 });
writer.write(Quote { bid: 100.1, ask: 100.15, sequence: 2 }); // Overwrites previous
// Reader side (e.g., trading logic thread)
let quote = reader.read(); // Gets sequence 2, skipped 1
assert_eq!(quote.unwrap().sequence, 2);
// Already consumed - returns None until next write
assert!(reader.read().is_none());
Multiple writes before a read result in only the latest value being observed:
writer.write(value_1);
writer.write(value_2);
writer.write(value_3);
// Reader only sees value_3
assert_eq!(reader.read(), Some(value_3));
assert!(reader.read().is_none());
Each written value can be read at most once:
writer.write(value);
assert!(reader.read().is_some()); // Consumes it
assert!(reader.read().is_none()); // Already consumed
writer.write(another_value);
assert!(reader.read().is_some()); // New value available
if reader.has_update() {
// New data available, but not consumed yet
let value = reader.read(); // Now consumed
}
Pod TraitTypes must implement Pod (Plain Old Data) — no heap allocations or drop glue.
Any Copy type automatically implements Pod:
// These work automatically
let (w, r) = slot::<u64>();
let (w, r) = slot::<[f64; 4]>();
let (w, r) = slot::<(i32, i32)>();
For non-Copy types that are still just bytes:
use nexus_slot::Pod;
#[repr(C)]
struct OrderBook {
bids: [f64; 20],
asks: [f64; 20],
sequence: u64,
}
// SAFETY: OrderBook is just bytes, no heap allocations
unsafe impl Pod for OrderBook {}
let (mut writer, mut reader) = slot::<OrderBook>();
Pod requirements:
Vec, String, Box, Arc, or other heap typesFile, TcpStream, Mutex, or other resourcesstd::mem::needs_drop::<T>() must be false| Method | Description |
|---|---|
write(value) |
Overwrite with new value (never blocks) |
is_disconnected() |
Returns true if reader was dropped |
| 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 |
Good fit:
Not ideal for:
seqlock or mutexarc-swap or RwLocknexus-queuetokio::sync::watchUses a sequence lock (seqlock) internally:
The SPSC constraint allows caching the sequence on the writer side, eliminating an atomic load per write.
Writer<T> is Send (can move to another thread)Reader<T> is Send (can move to another thread)Sync — each handle is for one thread onlyMIT OR Apache-2.0