FileSystem Storage
File-based storage provides durable persistence with good performance.
Configuration
Standard File Storage
{
"Surgewave": {
"StorageMode": "File",
"DataDirectory": "/var/surgewave/data",
"LogSegmentBytes": 1073741824,
"LogRetentionHours": 168
}
}
Zero-Copy WAL
For higher performance with memory-mapped reads:
{
"Surgewave": {
"StorageMode": "ZeroCopyWal",
"DataDirectory": "/var/surgewave/data"
}
}
Characteristics
| Property | File | ZeroCopyWal |
|---|---|---|
| Persistence | Yes | Yes |
| Write Latency | ~100 µs | ~100 µs |
| Read Latency | ~50 µs | ~20 µs |
| Throughput | 286K msg/s | 549K msg/s |
Directory Structure
data/
├── topics/
│ └── my-topic/
│ ├── 0/ # Partition 0
│ │ ├── 00000000000000000000.log
│ │ ├── 00000000000000000000.index
│ │ └── 00000000000000000000.timeindex
│ ├── 1/ # Partition 1
│ └── 2/ # Partition 2
├── __consumer_offsets/ # Consumer group offsets
└── __transaction_state/ # Transaction logs
Segment Management
Messages are stored in segments:
| Setting | Default | Description |
|---|---|---|
LogSegmentBytes |
1 GB | Max segment size before roll |
LogRetentionHours |
168 | Delete segments older than this |
LogRetentionBytes |
-1 | Max bytes per topic partition |
Index Files
Each segment has associated index files:
.log- Message data.index- Offset → position mapping.timeindex- Timestamp → offset mapping
Zero-Copy WAL
The Write-Ahead Log (WAL) backend uses memory-mapped files for optimal read performance:
flowchart TB
subgraph Write["ZeroCopyWal — write path"]
direction TB
W1[Append to WAL buffer] --> W2[fsync on flush] --> W3[Update in-memory index]
end
subgraph Read["ZeroCopyWal — read path"]
direction TB
R1[Lookup offset in index] --> R2[mmap file region] --> R3["Return ISurgewaveBuffer (zero-copy)"]
end
Disk Requirements
Calculate disk requirements:
Storage = (message_rate × avg_size × retention_hours × 3600)
+ (10% index overhead)
Example:
- 10K msg/s × 1KB × 168h × 3600s = 6 TB
- With 3x replication: 18 TB
Performance Optimization
SSD Recommended
{
"Surgewave": {
"DataDirectory": "/ssd/surgewave/data"
}
}
Separate Log Directory
{
"Surgewave": {
"DataDirectory": "/ssd/surgewave/data",
"LogDirectory": "/hdd/surgewave/logs"
}
}
Tune fsync
For maximum durability:
{
"Surgewave": {
"LogFlushIntervalMessages": 1
}
}
For maximum throughput:
{
"Surgewave": {
"LogFlushIntervalMessages": 10000,
"LogFlushIntervalMs": 1000
}
}
Cleanup Policies
Delete (Default)
Remove segments older than retention:
{
"Surgewave": {
"LogRetentionHours": 168,
"LogCleanupPolicy": "delete"
}
}
Compact
Keep only latest value per key:
{
"Surgewave": {
"LogCleanupPolicy": "compact",
"LogCleanerMinCleanableRatio": 0.5
}
}
Ephemeral
Ephemeral topics do not use filesystem storage - they use an in-memory ring buffer (EphemeralPartitionLog). On a file-backed broker, persistent and ephemeral topics coexist: persistent topics use disk while ephemeral topics are ring-buffer only. See Memory Storage - Ephemeral Topics for details.
Monitoring
Check disk usage:
surgewave broker info
du -sh /var/surgewave/data/topics/*
Next Steps
- Apache Arrow - Columnar storage
- Tiered Storage - Offload to cloud
- Performance Tuning - Optimization