Skip to content

tags: - reference - database


Control-plane data model

The AWC control plane stores its state in PostgreSQL. Schema changes apply as forward-only migrations. A version, once applied, cannot be rolled back by the migrator. To revert, restore a database snapshot.

Both the control service and the worker service run migrations on startup before they accept traffic. Applied versions are recorded in the migrations table. Either service advances the schema to the latest version.

Conventions

  • Resource IDs are opaque, prefix-qualified ULIDs stored as text. Common prefixes are ten_, prj_, snap_, ws_, lease_, host_, import_, and mount_.
  • Content digests use the canonical form sha256:<64 hex>.
  • Lifecycle states are stored as text and match the API value.
  • Timestamps are stored as UTC.
  • Labels and structured payloads are stored as JSON.
  • A row is mutable unless its table is append-only.

Identity and tenancy

A tenant is the top-level isolation boundary. Every other row belongs to a tenant.

A project groups snapshots and workspaces inside a tenant. A project carries a name and a lifecycle state.

A principal is a human user or a machine service account. A kind field tells the two apart. Credential material lives outside this row. A project membership binds a principal to a project with a role, such as viewer, developer, operator, admin, or billing viewer.

A host is a registered worker host. The row holds both the registration data and the time of the last heartbeat. A host moves through the states REGISTERED, ACTIVE, DRAINING, and RETIRED.

A token revocation records a bearer token that is denied before its natural expiry. The row is keyed by the JWT ID. Rows past expiry can be purged.

Snapshots and imports

A snapshot is an immutable, content-addressed version of a tree of files. Each snapshot belongs to a tenant and a project. A snapshot can name a parent snapshot to form a history. A snapshot moves through states such as UPLOADING, VALIDATING, READY, DEGRADED, and DELETED. A READY snapshot can be mounted or used as a workspace base.

An import session is a resumable snapshot upload. It reuses the snapshot state names and expires after a set time.

Workspaces and leases

A workspace is the mutable unit a client writes into. It is based on one snapshot and points at a head snapshot that moves as the client publishes checkpoints. A workspace moves through states such as CREATING, IDLE, MOUNTED, CHECKPOINTING, EXPIRING, and DELETED.

Optimistic concurrency guards each workspace. A version counter advances on every update. A writer publishes a checkpoint by comparing the version it read against the current value, then advancing it inside one transaction. If the version changed, the writer retries.

A workspace lease grants one host the right to write to a workspace. At most one lease generation is active for a workspace at a time. The lease moves through ISSUED, ACTIVE, RELEASING, RELEASED, EXPIRED, and REVOKED. This single-active-writer lease is how AWC keeps one writer per workspace.

Mount sessions and tickets

A mount session is one live mount of a workspace on a host. The mode is READ_ONLY or READ_WRITE. A mount session moves through REQUESTED, AUTHORIZED, PREPARING, MOUNTED, UNMOUNTING, CLOSED, and FAILED. A read-write mount holds the active workspace lease.

A mount ticket is a signed authorization to mount a given snapshot on a given host. It carries a nonce, a target policy, and an expiry, and the control plane signs it. A ticket can be revoked before it expires.

Job queue

A job is a unit of background work. Jobs carry a kind, a payload, and a result. A job moves through PENDING, RUNNING, COMPLETED, FAILED, and CANCELLED. Workers claim pending jobs and lock them while the jobs run. Each job retries up to a configured maximum.

A job may carry a dedupe key. At most one active job is kept for a given kind, tenant, and dedupe key. A null dedupe key is never deduped.

Idempotency

An idempotency key caches the outcome of an API call so that a retry returns the same result. The composite key is the tenant, the principal, the operation, and the client-supplied key. An idempotency row is PENDING, COMPLETED, or FAILED, and it expires after a set time.

Garbage collection

Garbage collection runs in epochs of mark-and-sweep.

A GC run is one epoch for a tenant. It records the cutoff, whether the run was a dry run, and counts of roots, marked digests, store inventory, deletion candidates, and deleted objects. It also records the bytes reclaimed.

A GC deletion plan is one candidate digest in an epoch. It records the digest, its kind and size, and whether it was deleted or skipped.

A GC integrity hold pins a digest so that sweep cannot delete it while scrub or recovery is pending.

Retention

A retention policy sets how long the control plane keeps snapshots, checkpoints, failed imports, and exports. A policy is scoped to a tenant or to a project inside a tenant.

Audit

The audit log is append-only. A row records the tenant, the principal, the action, the resource type and id, a request id, and a JSON detail payload. There is no update or delete path on the audit log.