Skip to content

Managed storage

Managed storage is the default. CAVS runs the bucket and everything around it; you push and pull. In production it runs on Cloudflare R2.

Concern Handled by CAVS
Bucket and credentials provisioned and rotated by CAVS
Encryption at rest R2 server-side encryption
Durability and backups provider durability plus CAVS-side integrity checks
Lifecycle and retention CAVS policy
Garbage collection unreferenced chunks reclaimed by the worker
Repack and compaction worker-driven, see Lifecycle
Egress included up to your plan’s limit, then metered
Integrity verification per-chunk BLAKE3, per-object SHA-256, Merkle roots

You get none of the bucket-administration work and none of the bucket configuration risk. The trade is that the bytes live in CAVS’s account — if that matters for your compliance posture, use Bring Your Own S3 instead.

Every repository has a storage namespace, and two sub-trees live under it:

<namespace>/objects/<oid[0:2]>/<oid[2:4]>/<oid> whole objects
<namespace>/cas/<tree-relative path> the CAVS chunk tree
  • objects/… holds whole objects, written by upload sessions and by standard Git LFS transfers. Two-level sharding on the oid keeps any one prefix from getting hot.
  • cas/… holds the content-addressed chunk tree produced by the CAVS transfer agent: asset manifests, chunk maps and immutable packfiles.

Both are content-addressed, so a write of identical bytes lands on the same key and costs nothing extra.

Managed storage is never proxied through the API. Every transfer runs against a presigned URL valid for 15 minutes:

Operation Path
Upload POST …/uploads/{session}/objects → presigned PUT
Download POST …/downloads/authorize → presigned GET
Git LFS POST …/lfs/objects/batch → presigned PUT/GET per object
CAVS chunk tree GET/PUT/HEAD …/lfs/* — proxied, with Range support

The chunk-tree path is the exception: those requests do pass through the API, because the agent needs authorized range reads over a content-addressed tree. They are small, cacheable reads, not whole-object transfers.

Managed storage counts against your plan on two axes:

Metered Basis
Storage physical bytes — post-dedup, post-compression
Egress bytes served on downloads, per calendar month

Because storage is billed on physical bytes, deduplication is a direct discount: ten similar 1 GB checkpoints that share most of their chunks cost far less than 10 GB.

Plan Included storage Included egress/month Max object size
Free 10 GiB 20 GiB 5 GiB
Developer 100 GiB 250 GiB 50 GiB
Team 1 TiB 2 TiB 200 GiB
Business 10 TiB 10 TiB 1 TiB

Beyond the included amount, overage is metered per GB — see Plans & quotas.

Storage is checked before a batch of uploads is authorized, using logical sizes as an upper bound (dedup lands the real figure lower). So a batch that would clearly overflow is refused up front rather than half-written:

{
"error": {
"code": "quota_exceeded",
"message": "storage quota exceeded for plan developer",
"request_id": "8c1f…",
"details": { "reason": "storage", "limit": 107374182400, "used": 106300000000 }
}
}

Warnings fire before the wall: storage.quota.warning at the threshold, then storage.quota.exceeded. Both raise a notification, send an email and fan out to your webhooks.

Terminal window
export API=https://cavsnode.com/api/v1
export H="Authorization: Bearer $CAVS_TOKEN"
curl -sS "$API/organizations/acme-ai/usage" -H "$H"
curl -sS "$API/organizations/acme-ai/usage/series?days=90" -H "$H"
curl -sS "$API/repositories/$REPO/usage" -H "$H"
From the CLI
cav storage

Figures come from an asynchronous reconciliation that sums the real stored bytes under each namespace, so they lag a push by seconds. See Storage insights.

Managed BYOS
Where the bytes live CAVS’s R2 account your bucket, your account
Who pays for storage and egress CAVS, within your plan you, to your provider
Counts against CAVS quotas yes no
Bucket administration CAVS you
Available on every plan Developer (add-on), Team, Business
Data residency control no yes
Compliance boundary CAVS’s yours

A single organization can mix both: repository A on managed storage, B on AWS S3, C on MinIO. The invoice separates each.

Deleting a repository or an organization drops the metadata immediately and queues the bytes for garbage collection. Managed objects become unrecoverable once collected. Take a snapshot or download what you need first.