Tech 12 min read

Cloudflare Ships Artifacts, a Git-Compatible Storage Primitive for AI Agents

IkesanContents

On April 16, 2026, Cloudflare announced Artifacts as an additional Agents Week release, now in private beta. It’s a Git-compatible version control storage designed for AI agents, built from the premise that today’s GitHub and similar services were made for humans.

Why Existing Git Doesn’t Fit Agents

GitHub and GitLab are designed around humans reviewing PRs, reading code, and managing branches. Agent workloads are different. Hundreds to thousands of agents concurrently generate, edit, and fork code, handling large volumes of small data: session history, configs, tool outputs.

The main pain points of human-oriented Git are threefold.

  • Scale: GitHub’s API rate limits don’t assume agents hitting the API at machine speed
  • Programmatic access: Web UI and CLI-first design, without APIs that let serverless runtimes like Workers create and operate repositories directly
  • Agent-specific metadata: no built-in way to attach execution logs, prompts, and outputs to commit history

Cloudflare’s answer is to solve this as a platform primitive.

Architecture

A Git Server Built on Durable Objects

Artifacts runs on top of Durable Objects. Each repository is a separate Durable Object instance with a globally unique ID.

File objects live in the Durable Object’s local SQLite database. Because Durable Object SQLite sits locally on the machine hosting the object, storage access doesn’t go over the network. Large objects exceeding the 2MB row size limit are split across rows. R2 handles snapshot management and KV tracks auth tokens.

A Lightweight Git Server in Zig

The Git protocol engine is implemented in Zig and runs as roughly a 100KB WebAssembly binary on top of the Durable Object. It supports SHA-1, zlib, delta encoding, and packfile parsing.

Both Git v1 and v2 protocols are supported, along with shallow clones, incremental fetches, and have/want negotiation. Standard Git clients work out of the box.

flowchart TD
    A[Agent / Worker] --> B{Access Method}
    B --> C[Workers Binding]
    B --> D[REST API]
    B --> E[Git Protocol]
    C --> F[Durable Object<br/>Git Server WASM]
    D --> F
    E --> F
    F --> G[SQLite<br/>File Objects]
    F --> H[R2<br/>Snapshots]
    F --> I[KV<br/>Token Management]

Three Access Methods

Workers Binding

Add a binding entry to wrangler.jsonc and a Worker can operate repositories directly.

// wrangler.jsonc
{
  "artifacts": [
    {
      "binding": "ARTIFACTS",
      "namespace": "default"
    }
  ]
}

Namespace-level operations (create, get, list, import, delete) and repository handle operations (createToken, listTokens, revokeToken, fork) are both available.

// Create a repository and issue a token
const repo = await env.ARTIFACTS.create("agent-session-47")
const token = await repo.createToken({ scope: "write", ttl: 3600 })

return { remote: repo.remote, token: token.secret }

The generated remote URL looks like https://{accountId}.artifacts.cloudflare.net/git/{namespace}/{repo}.git and can be passed straight to a standard Git client.

git clone https://x:${TOKEN}@123def456abc.artifacts.cloudflare.net/git/agent-session-47.git

REST API

You can also bypass Workers Bindings and drive the system directly through the REST API.

POST /accounts/$ACCOUNT_ID/artifacts/namespaces/$NAMESPACE/repos
GET  /accounts/$ACCOUNT_ID/artifacts/namespaces/$NAMESPACE/repos
POST /accounts/$ACCOUNT_ID/artifacts/namespaces/$NAMESPACE/repos/:name/fork
POST /accounts/$ACCOUNT_ID/artifacts/namespaces/$NAMESPACE/repos/:name/import
POST /accounts/$ACCOUNT_ID/artifacts/namespaces/$NAMESPACE/tokens

The import endpoint pulls a public Git repository in over HTTPS. The depth option controls the shallow clone depth.

Straight Git Protocol

Existing Git workflows work unchanged. Authentication supports either Bearer tokens (via http.extraHeader) or embedding the token in the URL password field.

# Bearer token style
git -c http.extraHeader="Authorization: Bearer $TOKEN" clone $REMOTE

# URL-embedded token style
git clone https://x:$TOKEN@123def456abc.artifacts.cloudflare.net/git/default/repo.git

ArtifactFS

Alongside Artifacts, Cloudflare ships ArtifactFS, a FUSE driver for mounting large repositories quickly.

A standard git clone downloads every file before work can start. A 2.4GB repository takes around two minutes. ArtifactFS performs a blobless clone (fetching only commits, trees, and refs), FUSE-mounts the repository, and pulls blob contents on demand when files are actually read. The same repository mounts in 10 to 15 seconds.

It’s a FUSE daemon implemented in Go, with background parallel downloads running in the meantime. High-priority files like package.json and config files are fetched first.

ArtifactFS works not only with Cloudflare Artifacts but also with GitHub, GitLab, and self-hosted Git remotes.

flowchart LR
    A[ArtifactFS<br/>FUSE Daemon] --> B[Blobless Clone<br/>Commits/Trees/Refs]
    A --> C[FUSE Mount<br/>File Tree Immediately Visible]
    C --> D[File Read Request]
    D --> E{Cached?}
    E -- No --> F[On-demand Fetch<br/>Download Blob Body]
    E -- Yes --> G[Return from Cache]
    F --> G

Metadata Management via git-notes

Artifacts natively supports Git’s git-notes feature. git-notes attaches arbitrary metadata to a commit without modifying the commit object itself, so the commit hash stays stable while you write annotations.

Writing agent execution logs, prompts, and tool outputs under refs/notes/ lets you manage commit history and metadata as a single unit. The “why did the agent make this change” context stays inside Git rather than being peeled off elsewhere.

# Attach metadata to a commit
git notes --ref=refs/notes/agent add -m '{"prompt":"...", "model":"claude-opus-4-7"}' HEAD

# Read it back
git notes --ref=refs/notes/agent show HEAD

Use Cases

One Repository Per Agent

The recommended pattern is to use a session ID or other stable identifier as the repository name and give each agent its own repository.

export default {
  async fetch(request: Request, env: Env) {
    const sessionId = request.headers.get("x-session-id") ?? crypto.randomUUID()

    // Get or create a repository tied to the session
    const repo = await env.ARTIFACTS.create(`session-${sessionId}`)
    const token = await repo.createToken({ scope: "write", ttl: 1800 })

    return Response.json({ remote: repo.remote, token: token.secret })
  }
}

Write-capable tokens are meant to be short-lived (TTL bound), and read-only tokens should be issued only when needed. Least-privilege design.

Pairing with Sandboxes

Sandboxes GA and Artifacts are designed to be combined. Sandboxes provides the isolated execution environment for agents, and Artifacts commits and version-controls the results.

Cross-session “time travel” (rewinding to any commit) and session forking (multiple agents proceeding independently from the same state) fall out naturally as Git operations.

Tenant Isolation via Namespaces

Namespaces are recommended for separating teams, environments, and projects.

// Separating dev/prod via namespaces
{
  "artifacts": [
    { "binding": "DEV_ARTIFACTS",  "namespace": "dev" },
    { "binding": "PROD_ARTIFACTS", "namespace": "prod" }
  ]
}

Pricing

ItemFree tierOverage
Operations10,000 ops/month$0.15 per 1,000 ops
Storage1GB/month$0.50 per GB-month

The design is “large, active repos cost more; small, barely-used repos cost very little.” The agent use case of creating lots of small repositories keeps costs down.

Roadmap

Public beta is scheduled for early May 2026, with the following features announced in advance.

  • Event Subscriptions: fire events on push/pull/clone/fork
  • TypeScript / Go / Python SDKs
  • Repository-level search
  • Stronger metrics for operations and storage usage

Taken together with the other Agents Week releases (Sandboxes, Durable Object Facets, Project Think, Agent Memory and so on), Artifacts fills the version control layer in the “execute → persist state → version control → memory retrieval” stack.

The Rest of Agents Week 2026

This article focused on Artifacts, but the related announcements rolled out all week.

Sandboxes / Facets for execution, Mesh / MCP for networking, Project Think / Workflows for orchestration, Email / Memory for channels and memory, and Artifacts for version control.

Artifacts isn’t a standalone new product. It sits on the line of isolated execution, enterprise governance, parallel agents, and prompt injection work that has been progressing in parallel over recent weeks and months.

Looking at Artifacts from jj (Jujutsu), a Git-Compatible VCS

Because Artifacts is designed so that standard Git clients work unchanged, any Git-compatible front-end can talk to the same remote. jj (Jujutsu), which has started showing up in agent-related discussions, is one such tool. This blog hasn’t covered jj before, so here’s a brief orientation alongside how it meshes with Artifacts.

Operational Model Differences Between jj and Git

jj can be described as “a VCS that keeps Git compatibility but rebuilds the client-side CLI.” It has a mode where the storage backend is Git, and commits produced there are ordinary Git commits. So the remote can be GitHub, GitLab, or Artifacts equally well. Where things differ is the client-side operation model. The main differences come in six points.

ItemGitjj
Unit of changeCommit (rewriting content changes the hash)Changeset (rewriting content preserves the ID)
Staginggit add to build an indexNo index, the working tree is automatically committed
BranchesExplicit branches by defaultAnonymous branches, managed as graph leaves
ConflictsStop the operation when they occurStored inside the commit, resolved later
History rewindreflog (per-ref)operation log (atomic snapshot of all refs), jj undo handles it in one shot
Working treeSeparate state from commitsThe working tree itself is treated as one commit

The piece that lines up most with agent operations is the operation log. Because every jj command implicitly snapshots the working tree, even if an agent destroys uncommitted files you can recover them through jj obslog. The sorts of accidents that are unrecoverable under pure Git, like “Claude Code compacts context and the work state vanishes” or “another process overwrites an in-progress file,” drop down to merely recoverable accidents.

How an Artifacts Remote Looks from jj

Artifacts speaks Git protocol v1 and v2, so from jj’s Git backend it’s just a regular Git remote. You can pass the clone URL Artifacts hands out straight into jj git clone to initialize.

# Clone an Artifacts remote with jj so both git and jj work in the same directory
jj git clone --colocate \
  https://x:$TOKEN@123def456abc.artifacts.cloudflare.net/git/default/agent-session.git

Passing --colocate sets things up so that both git and jj can drive the same directory. The agent side can keep calling git clone / git commit / git push as before while jj snapshots the working tree alongside it. What ends up pushed to the remote is still ordinary Git commits, so from Artifacts’ point of view jj is just another Git client.

Splitting the roles makes it easier to read.

  • Artifacts: provides the server-side version control storage. A Git server on Durable Objects, short-lived tokens, tenant isolation via namespaces.
  • jj: overlays a client-side operational model that is recoverable when agents break things. Auto-snapshotting of uncommitted changes, jj undo, anonymous branches.

Layering jj’s “operation log that tracks the working tree over time” on top of Artifacts’ “one repo per agent” pattern shrinks the unit of incident recovery down to a single agent step.

Current Caveats

  • Artifacts is designed to attach metadata via git-notes under refs/notes/, but jj itself doesn’t yet have a dedicated git-notes subcommand. In colocate mode you end up running git notes from the Git CLI side.
  • jj’s changeset IDs are a jj-side local concept. By the time they reach Artifacts they are back to ordinary Git commits. For other agents receiving them through Artifacts, ID stability only matters on the jj-using side.
  • What Cloudflare is pushing in Agents Week is a Git-compatible workflow. jj fits as a way to make the local side driving the agent more pleasant to operate, rather than as something Artifacts itself is designed around.