a2a cloud
one declaration, both sides

Local Postgres for AI agents, same as prod.

Declare a database once in a2a.yaml. Run `a2a chat` and get a real local Postgres — postgres:16-alpine over Docker Compose, pgvector available, DATABASE_URL injected. Deploy, and the same declaration provisions a managed Neon Postgres per agent with the same connection contract. One declaration, a real database in development and production, no SQLite-in-dev mismatch to debug later.

declare once · real Postgres in dev · same engine in prod

0
a2a.yaml declaration
0
config for dev vs prod
0%
same Postgres engine
the problem

Dev used SQLite. Prod used Postgres. The bug lived in the gap.

The path of least resistance is a fake database in development — SQLite or a mock — because standing up a real Postgres locally feels like too much setup. Then production runs Postgres, and now you're testing against one engine and shipping to another. Migrations that pass locally fail live, types and transaction semantics differ, and pgvector — the extension your agent memory depends on — simply isn't there in the stand-in. The gap between dev and prod becomes a category of bug you only find after deploy.

SQLite-in-dev, Postgres-in-prod: you never actually test the engine you ship.
Two database configs — one for local, one for production — that drift apart.
pgvector and other extensions missing locally, so vector code breaks only in prod.
Migrations and transaction semantics that pass on the stand-in and fail live.
the a2a way

Declare the database once; get a real Postgres on both sides.

A single `resources.databases` block in a2a.yaml is the whole contract. Locally, `a2a chat` provisions a real postgres:16-alpine over Docker Compose with a persistent volume and pgvector; in production the same declaration provisions a managed Neon Postgres per agent. Same engine, same DATABASE_URL, same connection contract — dev↔prod parity by construction.

Declare the database onceA real local PostgresThe same engine in prodpgvector on both sidesOne isolated DB per agentPersistent local state

Declare the database once

Add `resources.databases` to a2a.yaml — a name, provider neon, engine postgres, and an env like `url: DATABASE_URL`. That single declaration is the contract for both local development and production. There is no second config file for dev.

A real local Postgres

Run `a2a chat` and the database is provisioned locally via Docker Compose as postgres:16-alpine with a persistent volume. Your agent connects at postgresql://a2a:a2a@postgres:5432/<db>, with DATABASE_URL injected. You develop against Postgres, not a stand-in.

The same engine in prod

In production the exact same declaration provisions a managed Neon Postgres per agent. Same engine, same connection contract, same DATABASE_URL — so what you test locally is the database you ship to. Dev and prod stop drifting apart.

pgvector on both sides

The local Postgres has pgvector available, and so does the managed production database. Embeddings and semantic memory behave the same in `a2a chat` as they do live — you don't discover a missing extension after deploy.

One isolated DB per agent

Each agent gets its own database, locally and in production — an isolation and audit boundary, not a shared cluster with a tenant column. Your local dev store mirrors the per-agent boundary you run in prod.

Persistent local state

The local Postgres volume persists across `a2a chat` sessions, so migrations, seed data, and rows you wrote last run are still there. It behaves like a database you'd keep, not a scratch buffer wiped on restart.

side-by-side

Mismatched dev/prod databases vs. one declaration, real Postgres both sides.

dimension
dev≠prod
a2a parity
declaration
One config for a local DB, another for the production DB — two sources of truth.
One `resources.databases` block in a2a.yaml drives local and production alike.
dev engine
SQLite (or a mock) locally because a real Postgres is a hassle to stand up.
A real postgres:16-alpine via Docker Compose on `a2a chat`, DATABASE_URL injected.
prod engine
Postgres in prod — a different engine from the one you actually tested against.
Managed Neon Postgres per agent — the same engine and connection contract as dev.
parity
Bugs that only appear in prod because dev used a different database.
Dev↔prod parity: same engine, same URL, same pgvector — what you test is what ships.
vectors
pgvector 'works locally' only if your stand-in happens to support it.
pgvector available in the local Postgres and the managed production database.
questions

Frequently asked.

How do I get a local Postgres for my AI agent?

Declare a database in a2a.yaml under `resources.databases` — a name, provider neon, engine postgres, and an env such as `url: DATABASE_URL`. Then run `a2a chat`, and the CLI provisions a local Postgres via Docker Compose (postgres:16-alpine with a persistent volume) at postgresql://a2a:a2a@postgres:5432/<db>, injecting DATABASE_URL into your agent. You develop against a real Postgres with no separate local setup.

Is the local development database the same as production?

It's the same engine and the same connection contract. Locally, `a2a chat` gives you postgres:16-alpine over Docker Compose; in production the identical a2a.yaml declaration provisions a managed Neon Postgres per agent. Same Postgres engine, same DATABASE_URL, same pgvector — so you get dev↔prod parity instead of a database that behaves one way in testing and another when live. The production side is covered in detail on the managed Postgres for AI agents page.

Why not just use SQLite in dev and Postgres in prod?

That's the mismatch this design exists to avoid. SQLite-in-dev, Postgres-in-prod means you test against one engine and ship to another, so migrations, types, transaction semantics, and extensions like pgvector can all behave differently in production than they did on your machine. Declaring the database once and running a real Postgres locally means the database you test is the database you deploy.

Does the local Postgres support pgvector for agent memory?

Yes. pgvector is available in the local Postgres that `a2a chat` provisions, and it's also present in the managed production database. That means embeddings, semantic memory, and vector retrieval behave the same in local development as they do in production — you won't build against a missing extension and find out after deploy.

Does my local data persist between `a2a chat` sessions?

Yes. The local Postgres runs on a persistent Docker volume, so migrations, seed data, and rows written in a previous session are still there when you start the next one. Each agent also gets its own isolated database locally, mirroring the per-agent isolation boundary you run in production, so your dev environment reflects the real shape of prod.

keep reading

Related guides.

All guides live in the guides index.

what you test is what ships

One declaration. A real Postgres in dev and in prod.

a2a cloud deploys any agent — LangGraph, OpenAI Agents SDK, CrewAI, or custom — from a single a2a.yaml. Declare a database and you get a real local Postgres for `a2a chat` and the same managed Neon Postgres per agent in production, with pgvector on both sides. The managed production database, an MCP server, an API, a frontend, and an Ed25519-signed receipt per run come with it. No dev/prod database mismatch to debug after you ship.