Skip to content
Strata is pre-1.0. APIs, protocol, and storage format may change.

Metadata Growth

Strata v1 does not garbage-collect causal metadata automatically. A document with one visible key can still grow as clients edit it.

The installed lattice ORMap uses an ORSet for keys. Each update adds a replica/counter tag. Removes retain tag tombstones, removed CRDT values, and per-key removal bounds until pruning is safe. This is not a separate Strata DotContext, and it is not one new entry for every replica on every edit. The exact encoded growth depends on tags, replica IDs, values, and removals.

The cross-target metadata_growth_test fixture compares 100 and 1000 writes to one key with a fixed value. It also merges ten writers with 100 updates each. Both workloads retain one visible key while encoded state grows. Removing that key does not recover its metadata. Replaying the same state does not itself add tags.

Implemented v1 mitigation: bounded admission

Section titled “Implemented v1 mitigation: bounded admission”

The server defaults to a 16 MiB encoded-document growth budget. Configure STRATA_MAX_DOCUMENT_BYTES, or the embedded max_document_bytes field. The budget applies to merged state, including metadata, and checks all documents changed by create/delete before adopting either change. It rejects growth, not the recovery or exact replay of existing oversized documents. Zero disables the budget.

This is an operational bound, not garbage collection. It prevents one document from accepting unlimited new metadata under the default configuration. It does not bound total store memory, the number of documents, or permanent deleted-ID records. Clients must handle rejection; they must not report an unsaved local edit as accepted.

Monitor byte_size and plan document replacement before reaching the limit. For replacement, stop writers, preserve the old document as a backup, copy the visible application values into a fresh document with a new ID, and update references. Do not copy the old encoded ORMap if the purpose is to discard its history. Keep old and new identities distinct. This is an application migration, not a transparent compaction API; verify references and deletion ownership before deleting the old document.

If an application must accept more edits before migration, increase the budget deliberately. Removing keys can temporarily increase metadata and does not guarantee enough free space for another edit.

Why automatic pruning and ID reuse remain unsafe

Section titled “Why automatic pruning and ID reuse remain unsafe”

Lattice already supplies or_map.prune(map, stable_vv). It requires a valid causal-stability frontier. Strata does not know which offline replicas may return with unacknowledged edits. Connected socket count, presence, and a successful checkpoint do not prove that all replicas observed a removal. Calling prune with an invented frontier can discard valid concurrent work.

Reusing a replica ID from session storage is also insufficient. Cloned tabs can share storage, and a restarted writer can reset its counter before recovering state. Two independent writers must not issue the same causal identity. A stable replica ID alone does not prevent per-edit tag growth.

A later automatic compaction protocol needs replica acknowledgement and retirement rules, or an explicit document generation barrier that rejects stale writes and forces resynchronization. It must be tested with offline edits, reconnects, concurrent removes/re-adds, and crash recovery before it replaces this bounded-admission policy.