Part 8
Where state lives
This page shows where each project stores configuration, runtime state, and snapshots, and what that choice means for the tools you operate with.
After this page you can:
- State why ax keeps all of its state out of etcd.
- State which kagent data lives in Kubernetes and which lives in PostgreSQL.
- List the stores Substrate adds underneath both projects.
The same conclusion, a different line
Both projects keep high-churn agent state out of etcd. They draw the line in different places. ax keeps everything out of etcd, while kagent keeps the declarative definitions in Kubernetes and everything that changes per conversation in PostgreSQL.29
ax: Redis, no CRDs
ax DESIGN.md gives the reason directly: "Storing millions of short-lived tasks as Kubernetes CRDs pushes etcd past its comfort zone (single-digit GB storage limits, write-rate bottlenecks, control plane degradation)." ax stores its state in Redis and reconciles directly with Agent Substrate under fine-grained distributed locks.2
Because ax resources are not Kubernetes objects, kubectl cannot list them. You use the ax CLI, which is shaped like kubectl with apply, get, describe, watch, and delete.1 GitOps tools that reconcile Kubernetes objects, such as Argo CD or Flux, have no ax objects to watch, so applying ax manifests from Git needs a step that calls ax apply.
kagent: CRDs for configuration, PostgreSQL for runtime
kagent's architecture doc states the split: "Kubernetes stores desired agent and sandbox configuration. PostgreSQL stores runtime identity, A2A history, and lifecycle state."9 A Session is PostgreSQL-backed control-plane state exposed through gRPC, and it is not a Kubernetes resource.10
Agent definitions are ordinary Kubernetes objects, so kubectl apply and GitOps workflows work on them.8 High-churn data, such as turns and events, stays out of etcd, and you operate a PostgreSQL database for it.
Placement by data type
| Data | ax | kagent |
|---|---|---|
| Agent and runtime definitions | ax: Redis (Task, Workspace, Model).2 | kagent: Kubernetes (Agent, Harness, AgentTemplate, SandboxTemplate).9 |
| Compiled runtime input | ax: No equivalent. The Task runs the image as declared.3 | kagent: the prepared revision, in PostgreSQL and ate-api as a Substrate ActorTemplate.9 |
| Data | ax | kagent |
|---|---|---|
| Execution record and status | ax: Redis, with locks and PubSub for watches.2 | kagent: PostgreSQL Session rows, exposed by gRPC.9 |
| Conversation history | ax: No equivalent. History is whatever your agent writes.3 | kagent: A2A context, tasks, and events in PostgreSQL.9 |
| Data | ax | kagent |
|---|---|---|
| Sandbox filesystem | ax: workspaces mounted at their own paths in the Task.3 | kagent: a Substrate DurableDir at /data, private to the runtime.10 |
| Restart point | ax: the actor checkpoint taken by SuspendTask.2 | kagent: a named checkpoint in PostgreSQL plus a Substrate snapshot tag.9 |
The stores Substrate adds
The Substrate install includes its own PostgreSQL and the rustfs object store.12 Saying "ax uses Redis" is therefore incomplete: an ax install runs Redis plus Substrate's PostgreSQL, and a kagent install runs its own PostgreSQL plus Substrate's. Plan backups and capacity for every one of these stores.