Pushing & pulling large files
Through Git
Section titled “Through Git”Once connected, nothing about your Git workflow changes:
git add model.safetensorsgit commit -m "Retrain with the augmented set"git pushThree things happen in parallel, described in How it works: Git pushes the commit, the CAVS agent chunks and uploads the object, and the pre-push hook uploads the Git index.
Pulling:
git pull # commits + LFS objects for the checked-out treegit lfs pull # just the LFS objectsgit lfs fetch --all # every object on every ref (careful — this can be large)The CLI offers thin wrappers that make sure the CAVS wiring is in place first:
cav push # → git pushcav pull # → git pullcav sync # → git pull, then git pushThey forward extra arguments straight to Git: cav push --force-with-lease origin main.
Selective checkout
Section titled “Selective checkout”For a repository with far more data than any one machine needs:
# Clone without fetching any LFS contentGIT_LFS_SKIP_SMUDGE=1 git clone <url> && cd <repo>
# Then fetch only what you needgit lfs pull --include="checkpoints/v3/**"git lfs pull --include="*.safetensors" --exclude="archive/**"Or make it the default for the repository:
git config lfs.fetchinclude "checkpoints/current/**"git config lfs.fetchexclude "archive/**,experiments/**"Without Git
Section titled “Without Git”With the CLI
Section titled “With the CLI”Works in any repository connected with cav repo connect — it reads
cavs.repo-id from the Git config.
cav upload ./checkpoints/epoch-42.safetensors ./metrics.jsoncav download 9f2c8b0e…4f6b --output model.safetensorscav verify ./checkpoints/epoch-42.safetensors # is this exact content already stored?cav upload hashes every file first, so a bad path fails before a session is
opened. cav download refuses to overwrite an existing file without --force.
cav verify hashes locally and asks the Hub whether those oids exist — a cheap
way to check a release is complete before shipping it.
Add --json to any of them for machine-readable output:
cav upload ./model.bin --json | jq -r '.[].oid'With an SDK
Section titled “With an SDK”from cavs import CAVS, sha256_file
client = CAVS.from_env()
result = client.artifacts.upload( path="./checkpoints/epoch-42.safetensors", project="vision-models", # slug, name or UUID name="resnet50", kind="model", version="1.4.0", metadata={"epochs": 42, "val_acc": 0.942},)print(result.reference)
# Download by oid (or an immutable @sha256: reference).oid = sha256_file("./checkpoints/epoch-42.safetensors")client.artifacts.download(oid, dest="./restored/model.safetensors", project="vision-models")import { CAVS, sha256File } from '@cavsnode/cavs-sdk';
const client = CAVS.fromEnv();
const result = await client.artifacts.upload({ path: './dist/bundle.tar', project: process.env.CAVS_REPO_ID!, // the repository UUID name: 'client', kind: 'archive', version: process.env.GITHUB_SHA!,});
const oid = await sha256File('./dist/bundle.tar');console.log(result.reference, oid);With plain HTTP
Section titled “With plain HTTP”Four calls to upload, one to download. See Plain HTTP for the full walkthrough, or the Quickstart’s curl tab.
What determines how much you actually transfer
Section titled “What determines how much you actually transfer”-
Whether the CAVS agent is in the path. Standard
git-lfsmoves whole files. The agent moves chunks. This is the difference between 22 MiB and 3 MiB on a small edit. -
What the local chunk cache already holds. On pull, the agent computes the set of chunks it’s missing and fetches only those, with parallel range requests. A machine that has the previous version pays almost nothing for the next one.
-
How your format behaves under editing. Formats that append or patch in place dedup beautifully. Formats that reshuffle every offset on any change (some archive and package formats) defeat chunking. See Deduplication explained.
-
Whether the bytes are already stored. An object whose oid already exists in the repository is a metadata operation — nothing travels.
Verifying a transfer
Section titled “Verifying a transfer”Every path verifies content by construction: the oid is the SHA-256, so a download that doesn’t hash back to its oid is rejected rather than written.
To check by hand:
shasum -a 256 model.safetensors # sha256sum on LinuxTo confirm the platform’s view:
cav verify ./model.safetensorscurl -sS "$API/repositories/$REPO/objects?sort=recent&limit=5" -H "$H" | jqReading the numbers after a push
Section titled “Reading the numbers after a push”cav storage # organization totalscurl -sS "$API/repositories/$REPO/usage" -H "$H" # this repositorycurl -sS "$API/repositories/$REPO/transfers?kind=push&limit=10" -H "$H"transfers is the measured record the agent reported: duration, logical bytes,
stored bytes, new vs reused chunks. The dashboard’s Benchmarks tab renders
the same data. See Storage insights.
Concurrency and limits
Section titled “Concurrency and limits”| Limit | Value |
|---|---|
| API rate limit | 30 requests/second sustained, burst 60, keyed per token (or per user, or per IP when anonymous) |
| Concurrent uploads | plan-dependent: 2 (Free) → 64 (Business) |
| Max object size | plan-dependent: 5 GiB (Free) → 1 TiB (Business) |
| Presigned URL lifetime | 15 minutes |
| Upload session lifetime | 6 hours |
| Control-plane request body | 1 MiB |
Exceeding the rate limit returns 429 rate_limited; back off exponentially with
jitter. Exceeding a plan limit returns 402 quota_exceeded with a details
object naming which one. See Plans & quotas.
Interrupted transfers
Section titled “Interrupted transfers”| Path | Behaviour |
|---|---|
| CAVS agent, pull | Resumes with HTTP range requests from where it stopped. Corrupt cache entries are quarantined and repaired. |
| CAVS agent, push | Already-stored chunks are skipped; only the remainder is re-sent. |
| Upload session | Re-run the authorize step: objects already stored are reported as such, so the upload resumes by skipping them. Then finalize. |
Standard git-lfs |
LFS retries the whole object. |
| Expired presigned URL | Re-request it — the authorize call is cheap and idempotent. |
- Browsing your data — find what you pushed.
- Releases & snapshots — mark and capture states.
- Storage insights — measure the savings.

