Give your AI agent a Postgres database
Every agent deployed to a2a cloud is provisioned with its own managed Postgres — injected as DATABASE_URL, isolated per agent, and covered by signed receipts.
Most agent frameworks stop at the edge of memory. LangGraph gives you a checkpointer interface, CrewAI gives you memory backends, the OpenAI Agents SDK gives you sessions — and every one of them expects *you* to bring a database. That's the gap where a weekend project stalls: you now need a Postgres instance, a connection string, migrations, a secret store, and a way to keep the agent from carrying production credentials around in its environment.
On a2a cloud, an agent gets a database the same way it gets a URL: by being deployed.
What you get on deploy
Every agent deployed to a2a cloud is provisioned with its own managed Postgres database, injected as DATABASE_URL. No dashboard step, no separate provider, no copy-pasting a connection string into a secret manager. The database belongs to that agent — not to a shared pool that every other service can reach.
import os
import asyncpg
from a2a import tool
@tool
async def remember(key: str, value: str) -> dict:
conn = await asyncpg.connect(os.environ["DATABASE_URL"])
await conn.execute(
"insert into memories (key, value) values ($1, $2) "
"on conflict (key) do update set value = excluded.value",
key,
value,
)
await conn.close()
return {"stored": key}Deploy that and the table lives in a real Postgres database with a real backup story — not in a process-local dict that evaporates the next time the agent scales down.
Why per-agent, and not one shared database
Giving an agent a database is easy. Giving an agent a database *without handing it production* is the actual problem. Three properties matter:
- Isolation by default. The agent's credential reaches its own database and nothing else. A prompt injection that convinces the agent to run
drop tablecan only reach the blast radius you deployed it with. - Lifecycle coupling. The database is created with the agent and torn down with it. No orphaned database projects accumulating from experiments you abandoned in March.
- Provable access. Every run the agent performs emits a signed Ed25519 receipt, so "which agent touched this data, when, under whose authority" is answerable after the fact — not reconstructed from log grep.
That third point is the one teams underrate until a security lead asks for it. Trace logs tell you what your own system chose to write down. A signed receipt is a cryptographic statement about what actually ran — see signed receipts vs trace logs for the distinction, and giving agents database access without handing over production for the security model underneath.
Memory, RAG, and state — same database
Because it's plain Postgres, you're not locked into a bespoke memory API:
- Conversation state / checkpoints — point your LangGraph
PostgresSaveratDATABASE_URLand threads survive restarts. - Vector search —
pgvectorfor retrieval, in the same database as your relational data, so a RAG query and a business query are one join instead of two systems. - Application tables — the boring ones. Leads, jobs, receipts, whatever your agent actually manages.
This blog's own distribution agent runs exactly that way: its signals, posts, actions, and lead records all live in one managed Postgres database attached to the agent, not in a sidecar service someone has to operate.
The rest of the stack comes with it
The database is one of five things provisioned per agent. The same deploy also gives the agent an MCP server (so other agents and IDE clients can call its tools — see wiring an MCP server to your agent), an HTTP API, a frontend, and receipt signing.
The framework you started in doesn't change:
- Deploy a LangGraph agent in 60 seconds
- Deploy a CrewAI agent in 60 seconds
- Deploy an OpenAI Agents SDK agent in 60 seconds
Try it
pip install a2a-pack
a2a deployRead os.environ["DATABASE_URL"] from inside your agent. It's already there.