Start deploying
·7 min read·a2a cloud

Neon vs an auto-provisioned agent database: which Postgres should your AI agent use?

Neon is excellent Postgres. But for a LangGraph, CrewAI, or OpenAI Agents SDK agent, the real choice is between a database you provision and wire yourself and one that ships with the agent: scoped credential, lifecycle-coupled, with MCP, an API, and signed receipts alongside it. An honest comparison, including when Neon wins.

postgresneoncomparisonlanggraphcrewaiopenai-agents-sdkmcpsigned-receiptsagent-infrastructure

Neon is a very good Postgres. Serverless compute, branching that works like git, a generous free tier, and a Postgres that is actually Postgres. If you're building a web app, it's one of the first things we'd reach for.

This post is about a narrower question that AI engineers keep asking us: "I have a LangGraph / CrewAI / OpenAI Agents SDK agent. Should I put its state in Neon, or let the agent host provision the database?" The honest answer is "it depends on what the database is *for*", so here's the comparison for that specific decision, including the cases where Neon is the right pick.

The short version

| | Neon + your own agent host | a2a cloud (auto-provisioned per agent) | |---|---|---| | What you provision | A Neon project, a role, a connection string, then a host for the agent, then wiring between them | One a2a deploy — the agent and its Postgres come up together | | Who owns the database | Your Neon account, shared across whatever you point at it | The agent. Scoped role, injected as DATABASE_URL, torn down with the agent | | Credential path | Connection string in a secret store you operate, copied into the host | Platform-injected into the agent's runtime; never pasted anywhere | | Branching | First-class: branch per PR, per environment, per experiment | Per-agent isolation rather than branches; preview deploys get their own database | | Compute model | Autoscaling, suspends when idle | Managed Postgres sized for agent workloads | | What else comes with it | Nothing. You still need hosting, an API layer, MCP, auth, and audit | MCP server, HTTP/OpenAPI surface, frontend, Ed25519-signed receipt per run | | Best at | A database that outlives any single service; multi-app data platforms; ephemeral branches in CI | Getting one agent to production with its own data, tools, and evidence, fast |

What you're actually comparing

It's tempting to read this as "Neon vs some other Postgres". It isn't. Both are plain Postgres. pgvector works in both. LangGraph's PostgresSaver works in both. psql works in both.

The real comparison is a database you provision separately and connect to an agent versus a database that is part of the agent's deployment contract. Those produce different operational shapes.

Shape 1: Neon + separate host

Text
Neon project  ──(connection string)──▶  secret store  ──▶  Fly / Railway / K8s / Lambda
                                                                   │
                                                              your agent
                                                                   │
                                                 (you build) API, MCP server, auth, logs

You end up operating three things that have to agree with each other: the database, the host, and the glue that carries the credential between them. Each is fine. The seams are where weekend projects stall: a connection string that's valid in staging but not prod, a Neon branch that someone forgot to delete, a pooled connection that times out on compute wake, an agent that's holding idle in transaction and keeping compute awake all month.

Shape 2: database declared by the agent

YAML
# a2a.yaml
resources:
  databases:
    - name: app
      engine: postgres
      access_mode: read_write
      env:
        url: DATABASE_URL
Python
import os
import asyncpg
from a2a_pack.agent import A2AAgent, skill
from a2a_pack.context import RunContext, NoAuth

class Support(A2AAgent[dict, NoAuth]):
    name = "support"
    description = "Support agent with its own Postgres"

    @skill(description="Record a ticket outcome")
    async def record(self, ctx: RunContext[NoAuth], ticket_id: str, outcome: str) -> dict:
        conn = await asyncpg.connect(os.environ["DATABASE_URL"])
        await conn.execute(
            "insert into outcomes (ticket_id, outcome) values ($1, $2)",
            ticket_id, outcome,
        )
        await conn.close()
        return {"ticket_id": ticket_id}

a2a deploy creates the agent, creates its database, binds the role to the agent's runtime, and exposes the skill as an MCP tool and an HTTP endpoint. The agent cannot reach any other database because it was never given a credential for one. When you undeploy the agent, its database goes with it. Walkthrough: Give your AI agent a Postgres database.

Where the difference actually bites

1. Blast radius

A Neon connection string is a bearer credential to whatever that role can see. Most teams start with one role on one database, because that's the path of least resistance, and the agent inherits full read/write to everything in it. A prompt injection that gets the agent to run a destructive query gets whatever that role gets.

Per-agent provisioning flips the default: the credential only reaches that agent's database, and access_mode can be read_only for agents that shouldn't write. You can build the same thing on Neon with separate projects and roles per agent. It's just work you have to remember to do, and the platform does it for you here. The security model is in giving agents database access without handing over production.

2. Lifecycle

Agents are the most disposable workload most teams run. You spin one up to try an idea, keep it for a week, replace it. Databases provisioned by hand tend to outlive the thing they were for. Databases provisioned *with* the agent don't. That matters less for your flagship agent and a lot for the fourteen experiments before it.

3. Branching

This one goes to Neon. Branch-per-PR with copy-on-write data is a genuinely great workflow, especially when the database is shared by a whole application and you want a realistic dataset in CI. a2a cloud gives you isolation per agent and per preview deploy, which covers the common agent case ("don't let my experiment touch prod data") but is not the same thing as "give me a 2 TB branch in 200 ms".

4. What happens *around* the database

On Neon, the database is the product. Everything else, the host, the MCP server other agents call, the OpenAPI surface, the auth in front of it, the evidence trail, is yours to assemble. That's reasonable if you already run a platform.

On a2a cloud the database is one of five things provisioned per deploy. The same @skill becomes an MCP tool (wire an MCP server to your agent, zero config) and an HTTP endpoint (expose your agent as an API), and every run emits an Ed25519-signed receipt binding inputs, outputs, and the agent identity. When a customer or security lead asks "prove the agent wrote exactly that row", a Neon query log is text you produced; a signed receipt is something they can verify. More on that distinction in signed receipts vs trace logs.

5. Memory and RAG

Same in both. pgvector, a memories table, LangGraph checkpoints: it's Postgres. The difference is only that on a2a cloud the vector store, the checkpoint table, and the agent's business tables are already in the one database that was created for it, so there's nothing to wire. Pattern: add memory and RAG to an AI agent with Postgres + pgvector.

When to choose Neon

  • The database outlives any single agent. It's your application's system of record and the agent is one of several clients.
  • You want branch-per-PR with realistic data in CI, or branches for experiments on a large dataset.
  • You need read replicas, point-in-time restore across a long window, or a specific Postgres major on your own schedule.
  • You already run a platform team that is happy to own hosting, secrets, MCP, and audit for the agent separately.

In that situation, use Neon. You can still deploy the agent to a2a cloud and point it at Neon via a secret; the receipts and MCP surface don't care where the data lives.

When auto-provisioning fits better

  • You have one agent (or a few) that needs its own data: a support agent's tickets, a growth agent's pipeline, a research agent's corpus.
  • You want the credential scoped to the agent by default, not managed by convention.
  • You want the database created and destroyed with the agent, so experiments don't leave orphans.
  • You need MCP, an API, and signed receipts anyway and would rather not build them.

That's the case this blog's own distribution agent is in: its signals, leads, and actions live in the Postgres that was provisioned with it. Nobody set up a project for it.

Try it

Shell
pip install a2a-pack
a2a deploy

Read os.environ["DATABASE_URL"] inside the agent. It's already there, scoped to that agent, and every run that touches it leaves a receipt. Framework walkthroughs: LangGraph, CrewAI, OpenAI Agents SDK. If you compared Cloudflare's Agents SDK too, the same honest treatment is in Cloudflare Agents alternative.

discussion

0 comments

Likes0Dislikes0
No comments yet.