The Role of `incrementRev()` in the Cloudflare Computer Sync Protocol: Atomic Revision Control Explained
incrementRev() is an atomic, monotonic revision counter that assigns a unique integer to every filesystem mutation, enabling the Cloudflare Computer sync protocol to track changes incrementally and perform deterministic synchronization between distributed peers.
In the cloudflare/computer repository, the distributed virtual filesystem relies on strict ordering of all mutations to support efficient incremental sync. The incrementRev() function provides the backbone of this revision-based synchronization mechanism by generating global revision numbers that create a total order of every change to the database.
Why incrementRev() Exists: Total Ordering of Mutations
Every mutation to the virtual filesystem—whether mkdir, writeFile, rm, or rename—must be observable by the sync driver so remote peers can fetch only the changes that occurred after the last successful sync. incrementRev() provides a single, ever-increasing integer that uniquely orders all mutations, ensuring that no two operations share the same revision number.
Without this atomic sequencer, the protocol could not guarantee consistency during concurrent modifications or support the incremental fetching that minimizes bandwidth usage between peers.
How incrementRev() Works: Atomic SQLite Transactions
The implementation resides in packages/dofs/src/rev.ts (lines 11-20). The function runs inside a SQLite transaction and performs an UPDATE … RETURNING statement on the vfs_meta table:
// Conceptual implementation from packages/dofs/src/rev.ts
export function incrementRev(db: Database): number {
// UPDATE vfs_meta SET rev = rev + 1 RETURNING rev
// Implementation details handle the atomic bump in a single round-trip
return db.prepare(`UPDATE vfs_meta SET rev = rev + 1 RETURNING rev`).pluck().get();
}
This approach atomically bumps the stored rev value and returns the new number in a single database round-trip. Because the update and read happen in the same statement, the implementation guarantees that no two mutations receive the same revision, even during high-concurrency scenarios.
Integration with the Cloudflare Computer Sync Protocol
Current Revision Tracking with currentRev()
The currentRev() function, defined in packages/dofs/src/watermarks.ts (lines 13-22), reads the latest revision from vfs_meta.rev. The sync driver uses this value to advertise the current state of the database during pull and push operations, allowing peers to determine exactly how far behind they are.
Watermark Management
The protocol maintains two critical watermarks in the database:
pushRev: The highest revision that has been successfully pushed to the remote peer.- Fetch cursor (
rev, path): Marks the last entry the local side has pulled from the remote.
After each successful push, the driver updates pushRev to the revision that was just transmitted. When a pull completes, the fetch cursor advances to the revision of the last processed entry. These watermarks enable the protocol to resume interrupted syncs without retransmitting already-processed changes.
Change Generation and Revision Stamping
When a filesystem operation occurs, the code path (e.g., src/fs/writeFile.ts) calls incrementRev(db) and stamps the returned revision into the newly created vfs_nodes row:
import { incrementRev } from "../rev.js";
async function writeFile(db: Database, path: string, data: Uint8Array) {
const rev = incrementRev(db); // ← atomically bumps global rev
await db.run(
`INSERT INTO vfs_nodes (path, data, rev) VALUES (?, ?, ?)`,
[path, data, rev]
);
}
The sync layer later reads those rows, packages them as ChangeEntry objects that carry the revision number, and streams them to the remote side. Each entry’s revision allows the receiving peer to apply changes in the correct order and detect gaps in the synchronization stream.
Recovery and Consistency Guarantees
During a pull operation, the driver compares the remote’s currentCursor.rev with the locally stored fetch cursor. If the remote’s log is shorter than the local cursor (a "fetch divergence"), or if the remote’s appliedPushCursor.rev is behind the local pushRev, the driver resets the relevant watermarks to 0 and retries.
Because every mutation is tagged with a revision generated by incrementRev(), the reset-and-replay logic can safely resend all missing changes without risking gaps or duplicate applications. The monotonic nature of the revision counter ensures that replaying history from revision 0 always produces a consistent state.
Practical Implementation Examples
The pull driver in packages/rpc/src/sync-driver.ts demonstrates how watermarks coordinate with incrementRev() to manage synchronization windows:
import { readFetchCursor, writeFetchCursor, readWatermark, writeWatermark } from "@cloudflare/dofs";
async function pullOnce(db: Database, remote: SyncRPC) {
const after = readFetchCursor(db); // last rev we pulled
const { currentCursor, appliedPushCursor } = await remote.fetchChanges({ after });
// Handle divergence if remote is behind...
// After applying batch:
writeFetchCursor(db, currentCursor); // advance cursor to new rev
}
This pattern ensures that the local peer only requests changes it has not yet seen, using the revision numbers as opaque cursors into the global mutation log.
Key Files in the Revision System
| File | Role |
|---|---|
packages/dofs/src/rev.ts |
Implements incrementRev() – the atomic revision counter |
packages/dofs/src/watermarks.ts |
Provides currentRev(), cursor read/write, and watermark handling |
packages/dofs/src/sync/apply.ts |
Calls incrementRev() for each mutation during the apply phase |
packages/rpc/src/sync-driver.ts |
Pull/push driver that uses revision watermarks to coordinate synchronization |
packages/dofs/README.md |
High-level description of the revision sequencer and its place in the sync protocol |
Summary
incrementRev()is an atomic, monotonic counter implemented via SQLiteUPDATE … RETURNINGinpackages/dofs/src/rev.ts.- It assigns unique integers to every filesystem mutation, creating a total order required for distributed consistency.
currentRev()and revision watermarks (pushRev, fetch cursor) enable the protocol to track which changes have been synchronized.- The reset-and-replay recovery logic relies on the strict ordering guarantees of
incrementRev()to safely handle divergence scenarios. - Revision numbers are stamped into
vfs_nodesrows and transmitted asChangeEntryobjects during sync operations.
Frequently Asked Questions
What is the primary purpose of incrementRev() in the Cloudflare Computer sync protocol?
incrementRev() generates a unique, ever-increasing integer for every filesystem mutation. This provides the total ordering necessary for the sync protocol to determine which changes a remote peer has missed and to transmit only the incremental delta rather than the full filesystem state.
How does incrementRev() prevent duplicate revisions during concurrent mutations?
The function uses a single SQLite statement with UPDATE … RETURNING on the vfs_meta table, which atomically increments and returns the new value in one database round-trip. This atomicity ensures that even with concurrent writers, each call receives a distinct revision number without race conditions.
What happens to revision watermarks when the sync protocol detects divergence?
When the driver detects fetch divergence (the remote's log is shorter than the local cursor) or that the remote's appliedPushCursor is behind local pushRev, it resets the relevant watermarks to 0 and retries. Because every change is permanently tagged with its revision from incrementRev(), the protocol can safely replay the entire history without creating gaps or duplicates.
How does incrementRev() differ from currentRev() in the sync protocol?
While incrementRev() mutates the global revision counter and returns a new unique number for stamping changes, currentRev() simply reads the latest value from vfs_meta.rev without modifying it. The sync driver uses currentRev() to advertise state during negotiations, whereas incrementRev() is called by filesystem operations to mark new mutations.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →