clockworklabs/SpacetimeDB · error · io::Error
StorageFull
StorageFull
Error message
no space left on device
What it means
The in-memory repo simulates a disk with a fixed budget (Memory::new(total_space)); segments allocate space from that budget, and when a write needs more than remains you get ErrorKind::StorageFull with the classic ENOSPC message. This is the memory backend's disk-full simulation, not a real filesystem condition.
Source
Thrown at crates/commitlog/src/repo/mem/segment.rs:252
if *avail == 0 {
return Err(enospc());
}
let want = size.next_multiple_of(PAGE_SIZE as u64) - storage.alloc;
let have = want.min(*avail);
storage.alloc += have;
*avail -= have;
if want > have {
return Err(enospc());
}
Ok(())
}
}
fn enospc() -> io::Error {
io::Error::new(io::ErrorKind::StorageFull, "no space left on device")
}
#[cfg(feature = "streaming")]
mod async_impls {
use super::*;
use std::{
io::{Read as _, Seek as _, Write as _},
pin::Pin,
task::{Context, Poll},
};
use tokio::io::{self, AsyncRead, AsyncSeek, AsyncWrite, ReadBuf};
use crate::stream::{AsyncFsync, AsyncLen, IntoAsyncWriter};
impl IntoAsyncWriter for Segment {
type AsyncWriter = tokio::io::BufWriter<Self>;View on GitHub (pinned to 524b4487d9)
Solutions
- Increase the budget: Memory::new(total_space) sized for max_segment_size times the expected segment count
- Free budget by removing/compacting old segments once their data is no longer needed
- Catch StorageFull at the producer and pause/shed load instead of crashing
Example fix
// before let repo = Memory::new(1024 * 1024); // 1 MiB budget, exhausts quickly // after let opts = Options::default(); let budget = opts.max_segment_size * 4; // room for 4 full segments let repo = Memory::new(budget);
Defensive patterns
Strategy: try-catch
Validate before calling
// budget the memory repo for the segments you expect let opts = Options::default(); let expected_segments = 4; let repo = Memory::new(opts.max_segment_size * expected_segments + (1 << 20));
Type guard
fn is_storage_full(e: &io::Error) -> bool {
e.kind() == io::ErrorKind::StorageFull
} Try / catch
match log.commit(batch) {
Ok(committed) => { /* ... */ }
Err(e) if is_storage_full(&e) => {
// shed load: pause producers, compact/remove old segments, then resume
backpressure_and_compact();
}
Err(e) => return Err(e),
} Prevention
- Size Memory::new(total_space) for max_segment_size times the maximum segment count
- Remove or compact segments once their data is durably consumed elsewhere
- Treat StorageFull as backpressure, never as a crash
When it happens
Trigger: Committing until total allocated segment space exceeds the total_space passed to Memory::new; a single large commit arriving when the budget is nearly exhausted; tests that never remove old segments.
Common situations: Unit/soak tests with a small Memory budget; fuzz setups deliberately simulating out-of-disk conditions.
Related errors
- AlreadyExists
- NotFound
- InvalidInput
- error reading commit header: {e}
- failed to read {} bytes of commit payload: {}
AI-assisted analysis of clockworklabs/SpacetimeDB@524b4487d9 (2026-08-16).
Data as JSON: /api/errors/44919e148ecc3de1.
Report an issue: GitHub.