RocksDB-Sharp

Snapshots

A snapshot is a logical point-in-time view of the database. Reads issued through a snapshot ignore every write made after it was taken. Snapshots are cheap to create — they're just a sequence number plus a reference count — but they pin SST files until they're released.

Upstream reference: Snapshot wiki.


Creating a snapshot

using var snap = db.CreateSnapshot();
var ro = new ReadOptions().SetSnapshot(snap);

db.Put("k", "after");

string v = db.Get("k", readOptions: ro);   // value as of snapshot — may be older

Snapshot implements IDisposable. Always dispose it — every undisposed snapshot prevents the corresponding SST files from being garbage-collected by compaction.


Use cases

Pattern Why a snapshot helps
Consistent multi-key read All reads see the same state, even if writers are concurrent.
Long-running scan An iterator built on a snapshot won't see partial in-flight updates.
Backup / export Walk the entire database without freezing writes.
Replication Stream the state at a specific sequence number to a follower.

Snapshots and iterators

Pass a ReadOptions with the snapshot when creating the iterator:

using var snap = db.CreateSnapshot();
var ro = new ReadOptions().SetSnapshot(snap);

using var it = db.NewIterator(readOptions: ro);
for (it.SeekToFirst(); it.Valid(); it.Next())
{
    // … sees the database as of `snap`
}

Without an explicit snapshot, an iterator captures one implicitly at construction time — so reads through one iterator are still consistent with themselves.


Lifecycle and storage cost

Internally, a snapshot pins every SST file containing writes newer than the next-deleted obsolete file. While the snapshot is alive, compaction can't drop tombstones or older versions in those files, so disk usage stays elevated.

Snapshots aren't free

A snapshot that sits open for hours can pin gigabytes of obsolete data and inflate rocksdb.estimate-pending-compaction-bytes. Open snapshots short, dispose them as soon as the consistent read is done.


Worked example: consistent multi-key read

public static Dictionary<string, string> SnapshotRead(
    RocksDb db,
    IEnumerable<string> keys)
{
    using var snap = db.CreateSnapshot();
    var ro = new ReadOptions().SetSnapshot(snap);

    var result = new Dictionary<string, string>();
    foreach (var k in keys)
    {
        var v = db.Get(k, readOptions: ro);
        if (v is not null) result[k] = v;
    }
    return result;
}

Every key in result was observed at the same sequence number, so cross-key invariants hold.


Pairing snapshots with sequence numbers

db.GetLatestSequenceNumber() is the engine's monotonically-increasing write counter. Combined with a snapshot, you can record exactly which state you observed:

ulong seq;
using (var snap = db.CreateSnapshot())
{
    seq = db.GetLatestSequenceNumber();
    // … do the work …
}

Console.WriteLine($"Backup taken at sequence {seq}");

The Replication guide builds on this: pair a snapshot with GetUpdatesSince(seq) to ship the base state and then stream the diff.

© 2026 RocksDB-Sharp. All rights reserved.