Skip to main content
Beta / release candidate. Local replicas are in Replication RC1. Package APIs, limitations, and release versions may change; do not treat this as a stable contract.
A local replica is a durable, read-only copy of the latest values under one KV prefix. Sync it while online, then read that prefix from the device while offline. It is not offline writes, and it is not a replica of SQL data.

Requirements

  • The TinyCloud node must advertise kv-sync-v1 in its /info response. The production node at tee.node.tinycloud.xyz advertises this feature.
  • Install the beta CLI:
  • CLI replicas need Node.js 22.13 or newer, or Bun. SQLite rejects older Node versions; Bun supplies its own SQLite runtime.
  • For browser apps, install and pin an explicit replica package version. For example, use @tinycloud/[email protected]. The @tinycloud/replica@beta dist-tag currently points to an older build, so do not depend on it.
  • A device needs a grant that covers its configured KV prefix and includes get and sync. list and metadata are optional.

CLI: grant, sync, and read offline

1. Grant the device access to one prefix

Create or select a device profile and make it request access to the narrowest prefix it needs. For example, the device profile requests get and sync access to notes/:
The space owner reviews and grants that request, then the device imports the grant. Run the owner command in the owner’s profile; import the resulting artifact in the device profile:
sync is an explicit capability: a grant for ordinary KV reads alone is not enough. The replica stores only its configured prefix, which must be covered by the grant; the grant may cover a broader prefix.

2. Sync the prefix

Run the first sync with the desired prefix. The CLI creates a local replica named after that prefix unless you supply --replica:
Later, run tc --profile device replica sync again to poll for updates and deletes. The configured source host, space, and prefix are fixed for that replica. Use a different --replica name if you need a different scope.

3. Read while offline

get and list read only from local replica storage; they never fall back to a host KV request. Stop the network or disconnect, then run:
Use --raw to write the value bytes to standard output, or -o file to save them to a file. Sync must have completed the initial prefix coverage before you can rely on reads of keys that have not yet been observed.

4. Inspect or reset local data

status reports the replica’s scope, sync state, authority, counts, and failures. reset clears entries, content, and the cursor but keeps the replica configuration and grant, so sync can populate it again. Add --purge to remove that replica entirely:

Command options

Pass the global --host <url> when creating a replica if the profile has no default host; the chosen source is pinned to that replica. For example, after confirming that storing encrypted secret material locally is acceptable:
This flag only opts in to copying ciphertext. It does not grant decrypt access.

Retaining reads after grant expiry

By default, local reads are allowed only while the device’s sync grant is valid. An owner may separately issue a tinycloud.kv/retain grant to authorize a bounded retention window for already-synced local reads after that sync grant expires. Supply the retention grant’s CID during a sync:
The node attests the permitted retention window. This does not extend the sync grant or allow new syncs after it expires. A learned revocation still blocks reads. Omit the option to use the default policy.

Error codes and next steps

The CLI prints a machine-readable error code alongside the message. Common replica errors: Other errors identify configuration, grant, storage, or node failures: Exit codes: 0 success; 1 busy/runtime/storage error; 2 usage or NOT_COVERED / SECRETS_OPT_IN_REQUIRED; 3 missing or invalid grant; 4 absent, deleted, missing-content, or incomplete-coverage key; 5 expired, revoked, or not-yet-valid grant; 6 network; 7 node, protocol, or integrity error; 10 local storage full.

Browser: open, grant, sync, and read locally

The browser API is exported by @tinycloud/replica/browser; @tinycloud/web-sdk does not wrap or re-export replica operations. It does expose owner delegation methods used here: requestPermissions() obtains the explicit KV authority and delegateTo() issues it to the replica’s device DID. The owner below is an authenticated TinyCloudWeb instance configured with the app manifest needed for permission requests.
principal is the signed-in user’s identity DID and partitions data for users sharing a browser origin; it is not an authorization check. The grant and the node authorize sync. Browser data is stored in IndexedDB through a dedicated worker. Browser get and list are explicitly local; call sync() to poll for updates. Browser sync requires Web Locks (navigator.locks); without it, sync() rejects with RUNTIME_UNSUPPORTED, but an existing replica can still be read. If a browser does not support IndexedDB, opening the replica fails instead of silently switching to non-durable in-memory storage.

Security model

  • A replica stores only its configured KV prefix, and the grant must cover that prefix; the grant may be broader. Out-of-scope names and bytes are not fetched into replica storage.
  • By default, local reads stop when the node-attested grant window expires. A retention window attested by the node can allow reads after expiry. An offline device cannot discover an online revocation until it reconnects; once the replica learns that its serving grant was revoked, reads are blocked and content purge begins. If physical cleanup is pending, the next open retries it.
  • CLI replica files use mode 0600 under directories with mode 0700. Protect the device account and backups as well; file permissions do not protect against the same operating-system user.
  • Sync grants do not grant decryption. Replicating the secrets space or a prefix overlapping the vault namespace (including bare vault) requires explicit opt-in: tc replica sync --allow-secrets on the CLI, or openReplica({ allowSecrets: true }) in the browser. It copies encrypted secret material to the device. If you separately grant decrypt, note that decrypt authority is network-wide today, not limited to one secret name. Do not use it unless that scope is acceptable.
  • Since CLI 1.1.0-beta.22: tc auth logout deletes local replicas for that CLI profile by default; pass --keep-replicas to keep them. Logout does not revoke the profile’s grants on the node. To revoke node-side authority, use tc delegation revoke <cid>. Logout refuses to remove replicas if a sync is running or the replicas directory is a symlink.

Known limitations

  • Known node limitations being tracked (TC-737): a quiet prefix in a busy space can make each poll scan newer changes outside that prefix, increasing sync work and potentially latency even when the prefix has no updates.
  • Known node limitations being tracked (TC-735): on Postgres, blob uploads run inside the per-space write lock, so uploads can slow other writes in that space.
  • Remote refresh is polling through sync(); there is no remote push or watch API. In the browser, onCommitted reports only local commits from other tabs.
  • Replicas are read-only. Offline writes are not supported.