In last month’s analysis of Turso’s evolution roadmap, we discussed From Database-per-Tenant to Database-per-Agent: Turso’s Product Bet and Competitive Landscape: shrinking physically isolated SQLite databases—originally designed for multi-tenancy—down to the granularity of an individual agent or even a single task. In our earlier AI Agent Filesystem Survey, we also noted that the primary bottleneck in AI tasks is rarely memory retrieval, but rather the isolation and recovery of execution state. On July 20, Turso officially released its whitepaper Building AI Agent Databases: A Complete Guide to Database-per-Agent Architecture, which not only systematically presented the Database-per-Agent philosophy, but also outlined four typical architectural patterns for various deployment environments.
Following the whitepaper’s release, discussions quickly shifted from whether this product bet makes commercial sense to how to actually implement it in real-world multi-agent systems. Many teams read the whitepaper, found the idea of assigning one database per agent extremely elegant, and rushed to move it into production. Before long, however, they ran into roadblocks: some teams found their data fragmented across databases, while others discovered that generating a global analytics report was near impossible. This article serves as an extension focusing on engineering implementation. Skipping the commercial perspective, we will discuss how Turso’s four patterns evolve by scenario, how to build a practical Hub-and-Spoke tiered architecture, and several state-ownership traps and engineering pitfalls that were unmentioned in the whitepaper but will cause significant friction in code.
When running thousands of autonomous agents in your system, the
backend bottleneck is usually not the CPU, but the database. When
building traditional web services, engineers typically rely on a single
central database for everything. Handling multi-tenancy involves adding
a tenant_id column with WHERE clauses for
filtering, or creating tenant-specific schemas within the same database.
This pattern has worked seamlessly for over a decade because
microservice data schemas are fixed and their lifecycles are linear. But
with the arrival of AI agents, this conventional wisdom breaks down
immediately.
Consider a production scenario: thousands of coding agents or
customer service agents running concurrently, with each agent constantly
writing its own conversational context, explored paths, trial-and-error
logs, and temporary preferences. If you stuff all this data into a
single agent_memory table in one database and rely on
WHERE agent_id = ? to enforce isolation, severe pain points
will quickly emerge. First, concurrency collapses: thousands of agents
reading and writing to the same massive table at high frequency create
index lock contention that degrades database performance. Next comes the
fragile security boundary: if a developer misses a single
WHERE clause in code, Agent A can directly read the private
memory of Agent B or even other tenants. Worse yet is post-execution
cleanup: when an agent completes a task or crashes due to an error, you
must locate and wipe its records row by row across dozens of related
tables. No matter how carefully written cascade-delete scripts are,
orphaned data inevitably accumulates over time, cluttering the
database.
As analyzed in Part 1 of this series, Turso’s website outlines its core design philosophy: “Databases are files, not processes.” Since a database is simply a file, stop treating databases like expensive long-running servers. On Turso’s new-generation cloud platform, spinning up an isolated database via API is a millisecond-level network call; when an agent task completes, invoking an API to delete the entire database file leaves zero residual data behind. While using lightweight files for physical isolation sounds like a silver bullet, why have so many teams following this path ended up trapped in a dead end of duplicated, split data?
To understand this thoroughly, we must examine where shared databases clash with AI agents. Microservices rely on clear functional boundaries: a billing service manages billing tables, a user service manages user tables, and data schemas are explicitly defined. AI agents are fundamentally different—they are explorers operating with transient state. In a shared database, all agents are forced into a unified schema format. In reality, memory shapes vary drastically across agent types: customer service agents store large blocks of natural language, coding agents store AST trees, file traversal paths, and unit test logs, while data analysis agents store intermediate structured JSON. Forcing a lowest-common-denominator schema results in either an unmaintainable number of columns or developers resorting to dumping raw JSON strings into BLOB fields. Once BLOBs are used, relational databases lose half of their core value: SQL indexing and structured query capabilities.
Another fatal flaw is lifecycle mismatch. Some agents finish their job in five minutes, while others run continuously for months. A shared database cannot apply distinct physical storage strategies to objects with different lifespans, forcing infrastructure teams to allocate resources according to the worst-case maximum capacity for all agents, resulting in obvious waste.
Before discussing specific implementation plans, let’s review the four deployment patterns outlined in Turso’s whitepaper. Detailed configuration for each pattern can be found in the Turso Agent Databases Guide. Understanding scenario differences reveals that these are not merely parallel choices, but four evolutionary stepping stones as a system scales:
.db file with zero network latency for
reads and writes. It works offline, keeps data physically on-device, and
easily meets compliance requirements.In rigorous production environments, the default architecture almost always settles on a Hub-and-Spoke hybrid tiering approach. However, there is a major pitfall that catches most engineers: never bind the database isolation boundary directly to the agent’s name—bind it to the Task or Session instead. If an agent processes tens of thousands of tasks sequentially and the database is tied to the agent’s name, that isolated database will eventually accumulate historical garbage, forcing you back into complex in-database cleanup routines. The cleanest boundary is one database per Task: when the task finishes, simply delete or archive the database, turning it into a purely ephemeral scratchpad.
A robust Hub-and-Spoke production architecture is typically divided into four tiers:
With clear separation of responsibilities—keeping shared facts centralized and ephemeral state private—the architecture stays clean.
Even after assembling a Hub-and-Spoke topology, many teams still run into data confusion and fragmentation during real-world operation. The root cause is that while Turso’s whitepaper successfully proved that provisioning a database per agent is cost-viable, it skipped the most critical step: jumping directly from “shared databases are problematic” to “assign a database to every agent” without clarifying which states should be isolated and which states must never be isolated.
Whether to adopt Database-per-Agent has little to do with how many agents you have or how long they run; the core question is simply: who holds physical ownership of this data? Before designing your system, you must strictly categorize all data generated by running agents into two types:
The first type is inherently private state. This data belongs entirely to the agent or the task itself; when the agent terminates, the data should perish with it. Examples include temporary code snippets tested by a coding agent fixing a bug, an in-progress scratchpad, intermediate file tree traversal paths, or conversational context accumulated during a customer support session. These artifacts matter only for the current task; other agents neither need to read them nor benefit from the noise. For this type of data, a one-database-per-task model with post-execution teardown is the perfect fit, fully leveraging Turso’s strengths.
The second type is private views of shared facts. This data fundamentally belongs to the user, tenant, or system, and the agent merely holds transient operational authority over it. The canonical example is order and user profile data. A sales agent creates an order, a fulfillment agent tracks logistics, and a support agent processes a refund—all operating on the same single source of truth for that order. If you rigidly force a Database-per-Agent model by copying order data into each agent’s isolated database, you effectively create three independently evolving replicas at the physical layer. You would then have to engineer complex sync logic to prevent conflicts, creating artificial distributed data consistency problems just to use isolated databases. The same applies to permission tables, global approval workflows, and financial ledgers: they belong to the system’s global coordination layer and must remain strictly inside the shared truth DB. Data owned by the agent itself that can be safely discarded belongs in a private isolated DB; data owned by the system or user that the agent merely accesses temporarily must remain in the central DB. Database-per-Agent applies only to the former—never use it for the latter.
Beyond the risk of misallocating physical data ownership, there are two major engineering pitfalls glossed over by the whitepaper that must be addressed when deploying this architecture in production:
The first pitfall is Cross-Agent Analytics. In a shared database,
querying how many tasks failed last week is a simple
SELECT COUNT(*) FROM tasks WHERE status = 'failed' that
returns instantly. But across tens of thousands of isolated database
files, executing direct cross-database SQL aggregation is impossible. To
view a global operational dashboard, you must build a full offline ETL
pipeline to extract data from tens of thousands of files into a data
warehouse. While Per-Agent architecture eliminates the hassle of
real-time garbage collection, it shifts that complexity entirely onto
offline ETL.
The second pitfall is Schema Propagation across massive database fleets. As business requirements evolve, adding a column or modifying an index in a single database is a simple, single DDL command. However, altering schemas across hundreds of thousands of isolated SQLite database files becomes a highly complex distributed migration governance problem. Implementing canary rollouts, schema version checks, and network retry handling requires custom infrastructure.
Decoupling databases from shared infrastructure into disposable, ephemeral resources for agents is indeed an elegant move in AI-native architecture. It mirrors the industry’s shift years ago from sharing a massive physical server across applications to isolating each microservice inside its own Docker container.
However, physical isolation is never an excuse to forgo architectural design. The true power of Database-per-Agent lies in offering clean, zero-residual physical isolation for an agent’s ephemeral scratchpad. The next time you design a storage layer for an agent system, refrain from blindly following trends. Take your data and draw clear lines: keep shared business truth in the central DB, and isolate transient exploration in Per-Task databases. Once you thoroughly understand state ownership, the architectural layout becomes self-evident.
Once you determine which states should be isolated in Per-Task databases, the next natural question arises: can this single-file container handle RAG vector retrieval, a core component of LLM applications? For an in-depth practical test on efficiently performing vector retrieval and memory recall within single-file containers, see Part 3 of this series.