Database-Per-Agent: The Turso Pattern for Coordinating 10,000+ AI Agents
The shared-database problem nobody saw coming
For twenty years, "share a database between your services" was the default answer for backend architecture. Then in 2026, teams running fleets of AI agents at production scale ran into a pattern that broke that assumption.
The setup is familiar. You have an agent framework — LangGraph, CrewAI, or Deep Agents (see our framework comparison). Each agent instance needs to persist state — conversation history, plan artifacts, tool-call logs, retrieval indexes, user memory. So you point them all at your central Postgres. It works for the first 100 agents. It stumbles at 1,000. It falls over at 10,000.
Turso, an ex-Chesire spinoff that turned into a serious infrastructure vendor, quietly popularized the alternative: give each agent its own SQLite database. The pattern is now called database-per-agent, and it's how several agent-native startups scale to millions of concurrent agents on modest hardware.
Here's what the pattern actually looks like, why it works, and when you should — and shouldn't — copy it.
What "database-per-agent" means
Instead of one shared Postgres holding all agent state, you provision a small SQLite database per agent instance. That agent's memory, conversation log, tool history, and embeddings live in its own file. When the agent terminates, the database is either archived or discarded.
The architecture looks like this:
- A control plane (Postgres or DynamoDB) tracks which agents exist and where their databases live.
- Each agent, on spawn, gets a database file — created fresh or restored from a snapshot.
- The agent reads and writes only to its own database.
- Coordination between agents happens through queues, pub-sub, or explicit RPC — not through a shared data store.
- The control plane periodically consolidates useful information from agent databases into a shared analytics warehouse.
The pattern is not new — it's basically actor-model persistence — but Turso made it practical because their platform handles the two operationally hard parts: fast per-tenant provisioning and fleet-wide operations at millions of databases. You don't run 10,000 SQLite files yourself. You run 10,000 logical databases inside a single control plane that gives you one endpoint.
Why this beats sharing Postgres at scale
Three reasons, in decreasing order of how obvious they are.
1. Concurrent write contention disappears
Postgres handles concurrent writes well up to a few hundred connections. Above that, you're tuning connection pools, dealing with lock contention, and eventually hitting the max_connections wall. Agents write a lot — every step of every plan is a write. At 10,000 concurrent agents, that's tens of thousands of writes per second against a shared store, and the shared store is going to fail before your agents do.
With database-per-agent, each agent's writes go to its own file. Zero contention. The bottleneck moves to the compute, not the database.
2. Isolation is free
Agent state is naturally isolated by design — one user's agent should never see another user's data. In a shared Postgres, you enforce this with row-level security, careful queries, and constant vigilance. Every SQL bug is a potential data leak.
With database-per-agent, isolation is architectural. Agent A physically cannot read Agent B's database. This is a huge win for regulated industries and for the multi-tenant SaaS pattern where a single security bug can leak thousands of tenants' data.
3. Per-agent snapshots become trivial
"Pause this agent, snapshot its state, spin up a debug clone to reproduce a bug" is a nightmare against a shared database. Against a per-agent SQLite file, it's a copy command.
The same applies to A/B testing agent versions, rolling back an agent's decisions, and archiving completed agents. Every one of these operations becomes a file operation, not a distributed-systems problem.
Where it starts to hurt
The pattern is not free. Three costs you need to plan for.
1. Cross-agent queries are hard
"Show me every agent that decided to escalate to human in the last hour" is a natural analytics question. Against a shared Postgres, it's one query. Against 10,000 SQLite files, it requires either fanning out queries or streaming writes to a central warehouse.
The mitigation: use a write-ahead-log tailing pattern. Turso, along with tools like Litestream and Change Data Capture, lets you tail changes from every agent database and replicate them into a central OLAP store (usually BigQuery, Snowflake, or ClickHouse). Reads for analytics go against that warehouse. Reads for agent state go against the per-agent database.
2. Schema migrations are a fleet operation
Changing the schema of your agent state used to be one ALTER TABLE. With 10,000 agent databases, it's an orchestration problem. You need to:
- Version your schema explicitly.
- Migrate lazily on agent wake, or eagerly via a background worker.
- Handle mid-migration state cleanly.
- Have a plan for agents that haven't been woken in months.
Turso's platform gives you fleet-migration primitives, but you still have to think about them. Underinvest here and you'll create a mess.
3. Cost per database matters at extreme scale
Each database has some overhead. On a Postgres cluster, one more row is close to free. In a database-per-agent architecture, one more agent is one more database, and there's a floor cost.
Turso's pricing model — generous free tier, then per-database pricing — makes the math work for most workloads, but if you're spawning a million ephemeral agents per day, you need to model this carefully. A common pattern: use per-agent databases for long-lived agents, and use in-memory state (with periodic checkpoints to a shared store) for short-lived ones.
When to use this pattern
Use database-per-agent when:
- You have long-lived agents with meaningful state (assistants, research agents, monitoring agents).
- Isolation between agents is a security or compliance requirement.
- Your write load per agent is high enough to strain a shared store.
- You want the ability to snapshot, replay, or debug individual agent state.
- You're deploying on a platform (Turso, Cloudflare Durable Objects, Fly's LiteFS) that makes per-tenant databases operationally cheap.
Do not use it when:
- Your agents are short-lived (seconds to minutes). In-memory + periodic checkpoint is simpler.
- Your agents are stateless — that is, the state lives entirely in the LLM context and doesn't need to persist. Skip the whole layer.
- You have strong analytical queries that need to run across all agent state in real time. A shared store may still be right.
- Your team doesn't yet have the operational maturity to run fleet migrations. Get there first.
A concrete architecture
Here's the shape we build for enterprise clients running long-lived agent fleets.
Control plane (Postgres): owns the registry of agents, users, permissions, and metadata. Sees no agent operational state.
Agent state (Turso per-agent SQLite): owns conversation history, plans, tool logs, memory, retrieved documents. One database per agent, provisioned on first spawn.
Vector store (pgvector in Postgres, or Turso vector extension): owns embeddings. For most workloads, per-agent embeddings live in the agent's own database. For global knowledge (company docs, product catalog), a shared vector store shared read-only across agents.
Event bus (Redis Streams or Cloudflare Queues): owns inter-agent coordination. Agents publish events; other agents subscribe. No shared writes.
Analytics warehouse (BigQuery / ClickHouse): owns the read model for cross-agent analytics. Fed by change-data-capture from the per-agent databases.
Observability (LangSmith or a self-hosted equivalent): owns tracing and evals. Reads from the event bus; correlated with per-agent database snapshots as needed.
This looks like more moving parts than a single Postgres, and it is. In exchange you get isolation, per-tenant scalability, and the ability to reason about individual agents without a distributed-systems detour.
The Turso-specific wins
We use several platforms for this pattern; here's why Turso specifically has become our default for new agent workloads.
- Instant per-database provisioning. Sub-100ms to create a new database. Matters when agents spawn in response to user actions.
- Embedded replication. Each agent's local process can hold a synced replica of its database, giving you sub-millisecond reads.
- Multi-region replication built in. For agents that need to run close to users across the Middle East, India, and the US, this is a real win.
- Litestream-compatible export. You're not locked in — export to plain SQLite files any time.
- Reasonable pricing at scale. Free tier is generous; scaling costs grow linearly, not exponentially.
The alternatives worth knowing: Cloudflare Durable Objects for a compute-plus-storage primitive, Fly.io's LiteFS for FUSE-mounted SQLite, and Neon per-branch for a Postgres-native version of the same idea. Each has its niche.
Frequently asked questions
How is this different from just using SQLite per user? Not much, philosophically. The insight is that "per agent" is a natural unit of isolation for AI workloads, in the same way "per user" was for traditional apps. If your agents map one-to-one with users, they're the same thing.
What about backups? Snapshot each agent's database on a schedule (or on state change). Store snapshots in object storage. Turso and the alternatives all handle this natively. Test your restore path before you need it.
Can I mix this with a shared Postgres? Yes, and you probably should. Per-agent state goes to per-agent databases. Global metadata, user records, and cross-agent analytics stay in the shared Postgres. Use each for what it's good at.
Does this work on-prem? Yes. Turso can be self-hosted. LiteFS runs anywhere. This is a viable pattern for air-gapped and data-residency-restricted deployments — a common requirement for our KSA and UAE enterprise clients.
What's the failure mode when this goes wrong? The nastiest failure we've seen is a mismatched schema between agent versions after a deploy. Agent v2 tries to read Agent v1's database with an incompatible expectation. The fix: version your schema explicitly, and always support N-1 for at least a rollback window.
The strategic read
Database-per-agent is not a fashion. It's the natural conclusion of taking agents seriously as first-class workloads with lifecycle, isolation, and coordination requirements distinct from CRUD apps. The teams that adopt this pattern get to scale their agent fleets predictably; the teams that don't hit a wall around a few thousand concurrent agents and have to re-architect under pressure.
If you're standing up an agent product in 2026 and expect to scale beyond a few thousand concurrent users, this pattern belongs on your architecture whiteboard. If you're already scaling and feeling the pain of a shared datastore, this is often the fastest path out.
At Xenolve we design and ship agent architectures for enterprise clients. If you're weighing this pattern for a specific product — or you're stuck at the "our Postgres can't take any more" stage — reach out. It's a solvable problem, and the migration is much less scary than it looks from the outside.
Small databases, one per agent. Boring on paper. Transformative in production.
Enjoyed this article?
Subscribe to our newsletter or follow us for more insights on building premium software and AI solutions.
