4 releases
Uses new Rust 2024
| 0.2.0 | Dec 27, 2025 |
|---|---|
| 0.1.2 | Dec 20, 2025 |
| 0.1.1 | Dec 20, 2025 |
| 0.1.0 | Dec 20, 2025 |
#942 in Filesystem
28KB
515 lines
syncless: Ordered, atomic storage without durability guarantees.
syncless provides crash-safe, append-style storage where:
- individual writes are atomic
- writes are observed in order
- previously visible data is never corrupted
- fsync is rarely used (only on creation, and when file gets too large)
Recent writes may be lost on OS crash or power failure.
When to use this
Use syncless when:
- durability is not required
- corruption is unacceptable
- synchronous
fsyncis too expensive
Examples: browser history, bookmarks, caches, indexes.
When not to use this
Do not use syncless when you need:
- durability guarantees
- multi-writer isolation
- cross-process coordination
Try sqlite3 for that.
Documentation
Full API documentation: https://docs.rs/syncless
lib.rs:
syncless: ordered, atomic storage without durability guarantees.
Many times you don't want to pay the cost of continuous fsyncs, and are ok with losing the latest updates if an OS crash/power outage were to happen and the user is unlucky - but it's not acceptable to corrupt older data. Think of cases like "browser bookmarks" or "history": synchronous requirements are overkill for these (and stressful on the entire system).
Once syncless has opened a file (except for hardware errors or bugs)
writes are atomic and consistently ordered: if you see a write you
will see all of it, and all prior writes.
Writes are not isolated (a single reader/writer is assumed) and not durable: data may remain buffered in memory and be lost on crash or power failure. However, crash recovery will never expose torn writes or corrupt earlier data.
Guarantees
- Atomic visibility of individual writes
- Ordered visibility of writes
- Crash-safe recovery of previously visible data
Non-guarantees
- Durability (recent writes may be lost)
- Isolation (single writer assumed)
- Multi-process coordination
Example: atomically storing a JSON file
This saves a JSON blob (perhaps your program's config?) using syncless so it either gets the old or new one, never a corrupted version. In practice you would probably keep the Store object around, as reloading it can be expensive if it has many changes.
use syncless::{open, Store, Writable, Error};
pub fn save_config(
store: &mut Store<syncless::Writable>,
json: &str,
) -> Result<(), Error> {
store.write(0, json.as_bytes())
}
pub fn load_config(
store: &mut Store<syncless::ReadOnly>
) -> Result<String, Error> {
let mut buf = vec![0u8; store.size() as usize];
store.read(0, &mut buf)?;
let s = std::str::from_utf8(&buf)
.map_err(|e| Error::CorruptRecord)?;
Ok(s.to_owned())
}
Dependencies
~125KB