Soft-Delete Recovery
This page is part of the documentation for Orleans.Lattice 9.9.0 (release line 9.9), built 2026-10-04. It is also published as markdown, with every table and list, at README.md, and llms.txt lists every page.What it shows
DeleteTreeAsync is a soft delete: the tree is immediately made
inaccessible (reads and writes throw InvalidOperationException) but its data
is retained for a configurable grace window. During that window
RecoverTreeAsync brings the tree - and all its data - back. This sample
deletes a populated tree, shows reads are blocked, recovers it with data intact,
then contrasts that with PurgeTreeAsync, which destroys the data immediately
and makes recovery impossible.
Run it
dotnet run --project samples/SoftDeleteRecovery
Expected output
Silo starting... ready.
Seeding tree 'customers' with 5 keys...
accessible = True, count = 5
Soft-deleting the tree (DeleteTreeAsync)...
accessible after delete = False (expected False)
attempting a read... blocked: This tree has been deleted and is no longer accessible.
Recovering the tree (RecoverTreeAsync)...
accessible after recover = True (expected True)
count after recover = 5 (expected 5)
customer:3 = "name-3" (data intact)
Now permanently destroying the tree (DeleteTreeAsync + PurgeTreeAsync)...
attempting RecoverTreeAsync after purge... refused: Cannot recover a tree whose data has already been purged.
Done: soft-delete blocked access and was reversible; purge was permanent.
When to use
- Guarding against accidental deletion: a soft delete with a retention window
(
LatticeOptions.SoftDeleteDuration, default 72 hours) gives operators time to undo a mistakenDeleteTreeAsync. - Decommissioning a tree while keeping a safety net until you are certain the data is no longer needed.
- Use
RecoverTreeAsyncany time before the grace window elapses and purge begins.
When not to use
- When you must reclaim storage immediately and are certain recovery will never
be needed:
PurgeTreeAsync(shown at the end) bypasses the grace window and destroys the data now - the call waits a bounded time, and a tree too large to purge in that time finishes purging in the background. It is irreversible - recovery after purge is refused, as it is while a purge is still running. - Per-key removal - use
DeleteAsync/DeleteRangeAsync; tree deletion is for disposing of an entire tree.