You’re about to build an AI feature — a chatbot over your docs, an agent that takes actions, a semantic search box — and the reflex is to assemble a stack. Postgres for your data, Redis for a job queue, Pinecone or Weaviate for the vectors, a separate cron service for scheduled work. Four systems before you’ve written a line of product code. But you can build a complete Postgres AI backend where one database does all four jobs, and for most apps that’s not a compromise — it’s the better call.
The idea is simple: a handful of extensions turn a single Postgres database into a relational store, a document store, a vector index, a durable queue, and a scheduler at once. This is the hands-on version of that argument — what to reach for, how the pieces fit, which managed platform to start on, and the honest trade-offs so you know when the one-engine approach stops being right.

🧱 The Stack You Think You Need (and the One You Actually Do)
The default AI-app architecture has four moving parts. A relational database for users, sessions, and app state. A queue — Redis or SQS — to hand slow work (embedding a document, calling a model) to a background worker. A dedicated vector database for semantic search. And something to run recurring jobs: a cron container, a scheduler service, a managed workflow tool.
Each of those is a system to deploy, monitor, secure, back up, and keep in sync with the others. That’s the tax of polyglot persistence, and you pay it every day the app runs.
Here’s the consolidation. pgvector gives Postgres real vector search, so the vector database folds in. pgmq gives you a durable, SQS-style queue that’s literally just Postgres tables. pg_cron schedules jobs from inside the database using ordinary cron syntax. Between them — plus the LISTEN/NOTIFY and SELECT … FOR UPDATE SKIP LOCKED primitives Postgres has always had — the four-system stack becomes one system with one backup, one connection pool, and one set of credentials. Better still, a vector write and a relational write happen in the same transaction: they commit together or not at all, so your search index can’t silently drift from your source data.
One honest caveat up front, because it’s the crux of the whole approach: routing your queue and cron traffic through the same instance that serves your primary reads couples their performance. For a small or mid-size app that’s a great trade. At high scale it becomes a real capacity decision, and you split the busiest piece back out. The win isn’t “one Postgres forever” — it’s “one Postgres until your numbers tell you otherwise,” with a clean exit when they do.
🚀 Two On-Ramps: Supabase and Neon
You don’t install any of this on a bare server. Two managed platforms define the modern Postgres-for-AI landscape, from opposite directions.
Supabase is the bundled option — “backend-as-a-service” built on Postgres. Alongside the database you get authentication, auto-generated REST and GraphQL APIs, realtime updates over websockets, file storage, serverless edge functions, and pgvector, all wired together. Its documented auto-embeddings pattern is a good taste of the style: a database trigger drops a job on a queue, an edge function picks it up and calls an embedding model, and your pgvector column stays in sync with the source table automatically — no separate pipeline to babysit. If you want most of a backend to exist the moment you create a project, Supabase is the on-ramp.
Neon goes the other way: unbundled, serverless Postgres that scales its compute to zero when idle and back up on demand. Its headline feature is copy-on-write branching — the reason it shows up so often in AI tooling, which we’ll get to next. Neon is API-first: the whole control plane (create a database, branch it, tear it down) is programmable, which is why it’s become popular as the database layer for platforms and agents that provision databases on the fly. Databricks acquired Neon in 2025 with exactly that AI-agent framing.
Rule of thumb: reach for Supabase when you want batteries included and a fast path to a working product; reach for Neon when you want plain Postgres you can branch and automate, and you’ll bring your own auth/API layer.
🌿 Branch-Per-Agent: Git for Your Database
Neon’s branching deserves its own section because it changes a workflow, not just a feature list. A branch is copy-on-write: it shares the parent’s data and only stores the rows that actually diverge, so creating one is near-instant, costs almost nothing, and doesn’t add load to the parent. If you’ve ever wished you could git checkout -b your database, that’s basically what this is.
The payoff for AI work is the “branch-per-agent” pattern Neon documents directly. Before an autonomous coding agent touches your schema or data, you branch. The agent runs, makes its changes, and you check the result. If it’s good, you keep the branch; if the agent broke something, you throw the branch away and you’re back to the exact state it started from — and because restores preserve the connection endpoint, your app doesn’t even need to reconnect somewhere new. It’s a checkpoint-and-rollback loop for data, cheap enough to run on every agent attempt rather than saving for special occasions.

The same trick powers branch-per-pull-request preview environments: every PR gets a real database with real (copied) data, spun up and discarded automatically. Data stops being the thing that makes ephemeral environments hard.
🧰 A Queue and a Scheduler Without New Services
Back to consolidation, concretely. Two extensions replace two whole services.
pgmq is a message queue implemented as Postgres tables. You send a JSON message, a worker reads it with a visibility timeout (so two workers don’t grab the same job), and it archives or deletes on completion — the same mental model as SQS, but inside the database you already run. It isn’t a toy: its documented production users include managed-Postgres platforms themselves.
pg_cron runs SQL on a schedule with familiar cron syntax — cron.schedule('nightly', '0 3 *', 'CALL reindex_embeddings()'). One gotcha worth knowing: because it needs a long-running background worker, managed platforms often gate it to paid tiers (on Supabase it’s a Pro-plan feature, not available on free). Pair the two and you get a full job system: pg_cron ticks on a schedule and inserts a message, pgmq durably queues it, a worker processes it — no Redis, no cron container, no external scheduler.

This is where the earlier caveat gets concrete: these jobs run on your database’s I/O budget. That’s fine — even ideal — until it isn’t, at which point you move the hottest queue to something dedicated. Knowing that in advance is the difference between a deliberate architecture and a surprise.
🧠 Give Your Agent a Memory
If you’re building agents, Postgres solves the memory problem two ways at once. LangGraph — a popular agent framework — ships an official PostgresSaver (and an async version) that persists an agent’s thread state directly in Postgres tables: conversation continuity, human-in-the-loop pauses, and replay/”time-travel” debugging, all surviving process restarts. That’s short-term memory — the state of an ongoing task. (One practical note: you call a one-time .setup() to create its tables.)
For long-term memory — facts and summaries an agent should recall across sessions — you use the same pgvector you already enabled: embed the memories, then retrieve the relevant ones by similarity. Both halves of an agent’s memory live in one database, under one backup, with no separate “memory service” to run.

A word of caution on the marketing here: vendors selling “agent memory” love to quote specific accuracy improvements from their layered-memory architectures. Treat those as vendor claims unless someone independent has reproduced them. The architecture is sound; the numbers are sales copy.
🔐 Multi-Tenancy: Decide Before You Ship
If your app has tenants — separate customers whose data must never leak into each other — pick an isolation model early, because changing it later is painful. Postgres gives you three.
Shared tables with Row-Level Security (RLS) keeps every tenant’s rows in the same tables and uses database policies to filter each request down to its own tenant. Lowest operational overhead, best resource sharing — but the largest blast radius: one policy bug exposes everyone. Treat RLS as defense-in-depth on top of correct application-level filtering, not the only thing standing between tenants.
Schema-per-tenant gives each tenant its own set of tables. Stronger isolation, but it stops scaling cleanly past a few hundred tenants, as per-schema migrations and catalog bloat drag on the planner.
Database-per-tenant is the strongest isolation and the one that fights Postgres hardest at scale: connection pooling multiplies per database, and you hit connection limits long before you run out of CPU or storage. It’s a niche choice for a handful of high-value tenants, not a default.
There’s no free winner — just a trade-off to make on purpose. (We go deeper on the security side of this in the Secure pillar.)
🤖 Wiring an Agent In — Over MCP, Carefully
The newest layer is letting an LLM talk to your database directly through the Model Context Protocol (MCP). Both major platforms ship official servers: Supabase’s is a hosted, OAuth2-authenticated endpoint that lets an AI client manage your project; Neon’s wraps its management API for natural-language branching and queries.
But here’s the cautionary tale that should shape how you do this. The original reference Postgres MCP server was archived in July 2025 after security researchers at Datadog disclosed a SQL-injection vulnerability in it. The lesson isn’t “MCP is unsafe” — it’s that handing an LLM an unscoped database connection is the risk, and scoping it is the fix. The actively maintained successor, crystaldba/postgres-mcp, adds exactly that: configurable read/write limits, plus database health checks and index-tuning analysis. Give an agent a least-privilege, read-limited role with a statement timeout — never a superuser connection string. (The Secure pillar has the full checklist.)

🧭 How to Actually Start
Concretely: create one managed Postgres — Supabase if you want auth and APIs handed to you, Neon if you want branchable plain Postgres. Enable pgvector and put your embeddings there. Add pgmq and pg_cron when you genuinely need background work and scheduling, not before. If an agent needs database access, give it a scoped MCP connection, not the keys to everything. And keep your source data and its embeddings in the same transactions so they never drift.
You’ll have a real Postgres AI backend — data, search, queue, scheduler, and agent memory — running as one system you can actually reason about. Add the second database the day your metrics prove you need it, and not a day sooner. One caveat that never expires: every free-tier limit and plan gate mentioned here changes constantly, so check the current pricing page before you commit.
📚 Further Reading
- Why Postgres Became the Default Database for AI Apps — the “why” behind everything in this guide.
- Postgres as a Vector Database: What the Benchmarks Actually Say — how far pgvector’s search really goes before you need a dedicated engine (coming soon).
- Don’t Give Your AI Agent
psqlAccess — the full MCP security checklist (coming soon). - What Is MCP? — the protocol behind connecting agents to your database and tools.
- Serena MCP: Give AI Coding Agents a Real Memory — a concrete MCP-based memory setup for coding agents, complementing the Postgres-backed memory described here.
- Primary sources: Supabase docs, Neon branching, pgmq, and LangGraph persistence.
❓ Frequently Asked Questions
Do I really not need a separate vector database or Redis?
For most apps, no. pgvector covers semantic search into the millions of embeddings, and pgmq covers a durable job queue — both inside the Postgres you already run. You add a dedicated vector DB or queue when your scale or latency targets specifically demand it, not by default.
What’s the catch with running everything on one Postgres?
Coupling. Your queue, scheduler, and vector search share the primary database’s I/O and failure modes. That’s a good trade for small-to-mid apps and a worse one at large scale — plan to split the busiest piece out when your numbers justify it.
Supabase or Neon — which should I pick?
Supabase if you want a batteries-included backend (auth, APIs, realtime, storage) the moment you start. Neon if you want plain, serverless Postgres with instant branching and an API-first control plane, and you’ll supply your own auth/API layer.
What is “branch-per-agent”?
Using Neon’s copy-on-write branching to give each AI agent run its own disposable database branch. The agent works on the branch; you keep it if the change is good or discard it if not, instantly returning to the starting state — like a git branch for your data.
Is it safe to connect an AI agent to my database over MCP?
Only if you scope it. The original reference Postgres MCP server was archived after a SQL-injection disclosure; the fix is to give the agent a least-privilege, read-limited role with a statement timeout (for example via the maintained crystaldba/postgres-mcp server), never a superuser connection.
📚 Recommended Resources
Disclosure: some links below are Amazon affiliate links. If you buy through them, I earn a small commission — at no extra cost to you — which helps keep this site running.
Designing Machine Learning Systems
Chip Huyen · Book · ~$50 on Amazon
The best map of the infrastructure around a model — data layers, feature stores, and pipelines. It’s the natural companion to this article: once your AI backend lives in one Postgres, this shows how it fits the larger system.
Fundamentals of Data Engineering
Joe Reis & Matt Housley · Book · ~$55 on Amazon
A clear framework for storage, ingestion, and orchestration decisions — exactly the vocabulary you need to reason about when “one Postgres for everything” is the right call and when to split a piece out.
PostgreSQL: Up and Running
Regina Obe & Leo Hsu · Book · ~$40 on Amazon
A fast, practical field guide to Postgres’s real features — JSON, indexing, and the extension system that makes pgvector, pgmq, and pg_cron possible in the first place.