---
title: "Why I Built PgBeam"
description: "PgBeam decides what an AI agent is allowed to do with your Postgres. It did not start there: it started as a proxy for cross-region latency, and the same proxy turned out to be the only honest place to put the rules."
canonical: "https://pgbeam.com/blog/why-i-built-pgbeam"
last-updated: "2026-09-03T00:00:00.000Z"
---

# Why I Built PgBeam

> PgBeam decides what an AI agent is allowed to do with your Postgres. It did not start there: it started as a proxy for cross-region latency, and the same proxy turned out to be the only honest place to put the rules.

URL: https://pgbeam.com/blog/why-i-built-pgbeam
Published: 2026-02-19
Author: Alexis Rico
Tags: founding, architecture, ai

PgBeam decides what an AI agent is allowed to do with your Postgres. You hand the agent a scoped connection string or a hosted MCP endpoint instead of your superuser one, and PgBeam enforces the policy attached to that credential inside the PostgreSQL wire protocol: read-only or not, which tables and columns are reachable, which rows come back, what gets masked, how many queries it may run. Every statement is recorded with the decision and the reason for it. It works with any Postgres and needs no code changes.

I did not set out to build that. I set out to fix a latency problem, and the thing I built to fix it turned out to be the one place in the path that can refuse a query. The product today is a direct consequence of the problem I started with, so this is the story in order.

## The problem I started with

If you run PostgreSQL across regions, you know the latency problem.

A database in Virginia serves a request from Tokyo in 100-200ms per round trip. But a new PostgreSQL connection is not one round trip. It is four: TCP handshake, TLS negotiation, PG startup, and authentication. That is 400-800ms before the first query executes.

In serverless and edge architectures, where connections are short-lived, teams pay this cost on nearly every request. The result is either degraded user experience or expensive over-provisioning of read replicas, along with their operational complexity.

## The gap I found

I looked at the solutions available and found that every one of them forces a trade-off:

**PgBouncer** handles connection pooling but offers no query caching. Every read still round-trips to the origin. You also have to host and operate it yourself.

**Cloudflare Hyperdrive** provides pooling and caching, but only works from Cloudflare Workers. If you're on Vercel, AWS Lambda, Fly.io, or Railway, you can't use it.

**Prisma Accelerate** offers similar capabilities, but requires the Prisma ORM. If your team uses Drizzle, Knex, raw `pg`, SQLAlchemy, or any non-JavaScript stack, it's not an option.

**RDS Proxy** is VPC-bound, single-region, AWS-only, and adds no caching.

I couldn't find a platform-agnostic, managed solution that combines connection pooling and query caching across multiple regions, so I built one.

PgBeam

Hyperdrive

Prisma Accelerate

PgBouncer

Pooling

Yes

Yes

Yes

Yes

Query cache

Yes

Yes

Yes

No

Multi-region

Yes

Yes

Yes

No

Platform lock-in

None

CF Workers

Prisma ORM

None

Managed

Yes

Yes

Yes

Self-hosted

Read replicas

Yes

No

No

No

Custom domains

Yes

No

No

N/A

That table is the map I was working from in early 2026, and every row in it is still true. It is no longer the comparison anyone arrives with. What people weigh PgBeam against now is a hand-rolled read-only Postgres role or a DIY MCP server holding a full-privilege connection string. The rest of this post is how the distance between those two tables got closed.

## The approach

PgBeam is a managed PostgreSQL proxy. It speaks the PG wire protocol natively, so standard drivers and ORMs work without code changes. Adoption requires changing one environment variable:

No SDK. No code changes. No migration. This matters because PgBeam should slot into existing stacks without engineering effort or vendor risk.

Three capabilities compound to reduce database load and improve response times:

**Global routing**: each connection is routed to the nearest proxy region.

**Connection pooling**: warm upstream connections eliminate the 4-RTT handshake overhead, reducing connection establishment cost by 3-7x.

**Edge query caching**: read query results are cached in the region that served them with stale-while-revalidate semantics, controlled per query via SQL annotations or dashboard rules.

## How the proxy works

PgBeam is a wire-protocol proxy. It speaks the PostgreSQL frontend/backend protocol directly, so from your application's perspective it looks like a normal PostgreSQL server. The proxy handles TLS termination, authentication, and the startup handshake, then maps your session onto a pre-authenticated upstream connection.

This is different from an HTTP-level proxy or an SDK wrapper. Because PgBeam operates at the wire protocol level, it can inspect individual statements, cache read results, and manage connection lifecycle without your application knowing anything about it. Any client that speaks PostgreSQL works: `psql`, `pg` for Node, `asyncpg` for Python, JDBC, ODBC, Go's `database/sql`.

The gateway runs across 12 metros worldwide. The region closest to your user accepts the connection, and the upstream connection to your database can be established from the region closest to the database instead. That keeps the client hop short without lengthening the database hop.

## The line that changed the product

Read that paragraph again: the proxy inspects individual statements before the database sees them.

I built that to decide what was cacheable. A read with no volatile functions can be served from a cache; anything else has to go upstream. Making that call means parsing the statement and understanding which relations it touches and what it intends to do to them.

By the middle of 2026, the people showing up were not asking about latency. They were wiring Claude Code, Cursor, and in-house agent loops into real databases, and the thing keeping them up was not how long a query took. It was which queries the agent could run at all. The two answers available were a hand-rolled read-only Postgres role, which blocks writes and nothing else, and an MCP server pointed at a full-privilege connection string, where the guardrails are whatever you remembered to write and keep writing.

The parse that decides what is cacheable is the same parse that decides what is allowed. A component that already terminates the connection, authenticates the client, and reads every statement before the database does is the only one in the path that can refuse a statement without the application's cooperation. I had built an enforcement point by accident, while trying to build a cache.

The full argument for why the wire is the right layer, and why the agent, the application, and the database itself are each worse places to put the rules, is in The Proxy Is the Right Place to Make Agent Database Access Safe.

## What PgBeam is for now

Same proxy, different job. A PgBeam credential carries a policy, and the policy is enforced before the statement reaches your database:

**Read-only by default**: allowed statement types are set per credential, and writes and DDL are rejected at the wire.

**Table and column allowlists**: anything off the list is refused, whatever the query looks like.

**Row-level policies**: a predicate is appended to the query that the agent cannot remove.

**PII masking**: redact, null, or hash a column so the agent never receives the raw value.

**Query budgets and row caps**: a ceiling per credential, so a looping agent stops.

**Kill-switch**: revoke one credential, or every credential on a project, without rotating your database role.

**Audit trail**: every statement with its decision, reason, rows, bytes, and latency.

There are two front doors onto that one policy engine: a guarded Postgres connection string, and a hosted MCP endpoint. The full control surface is on the features page, and Launching PgBeam walks through scoping an agent from an empty account to a guarded credential.

Pooling and caching did not go away, and they are not the pitch either. They are the reason the guardrails are affordable: an agent that opens a connection per tool call is exactly the client a pooler was built for, and an agent that asks the same question four times is exactly the client a cache was built for.

## Benchmark

We publish a live latency benchmark that runs serverless functions from 20 global regions. Each function opens a real TLS PostgreSQL connection to a database in `us-east-1`, once directly and once through PgBeam. It measures full connect time plus p50 query latency across 5 samples (first discarded as warmup). No synthetic data, no cherry-picked regions.

Those numbers are measured on request rather than quoted from a run I liked, which is the point of publishing them that way. The shape is consistent: the further the client is from `us-east-1`, the more of the request was handshake, and a cache hit collapses it to the client-to-proxy hop. Even on a cache miss, pooling alone cuts connection establishment by 3-7x, because the 4-RTT handshake has already happened. The query still round-trips to the origin, but the connection is already warm.

## Limitations

**Read caching only.** We do not replicate data, writes pass through to the upstream.

**Eventual consistency.** Cached reads can be up to 60s stale by default. Caching can be enabled and configured per query from Cache Rules.

**No cross-region cache sync.** Each region's cache is independent and expires via TTL.

**PostgreSQL only.** There's no support for MySQL or other databases right now.

**Allowlists do not see through views.** A view has to be allowlisted explicitly, or it is refused.

**`SET search_path` is blocked for agent credentials**, because allowing it would let an agent walk around an allowlist.

**Query budgets are enforced per region.** On a globally distributed workload, treat a budget as a close approximation rather than a globally coordinated counter.

## Why self-fund

PgBeam is self-funded. Running global regions costs real money every month. The pricing exists to make the project sustainable long-term, not to maximize revenue.

The goal is straightforward: cover infrastructure costs from day one so the project doesn't depend on runway or external funding to keep running. If PgBeam solves a real problem, it should be able to sustain itself on the value it delivers.

## What's next

The early roadmap here was about regions and multi-cloud. That is not where the work went. It went into the policy engine: row-level policies, human-in-the-loop approval queues, anomaly detection, a tamper-evident audit log you can stream to your SIEM, and instant branches so an agent can rehearse a migration on a throwaway copy. The changelog has the record.

What I want now is workloads I did not predict. If you are pointing an agent at a database and the policy you need does not exist yet, that is the interesting failure, and I would like to hear about it.

If you are about to give an agent a connection string to a database you care about, try PgBeam instead. Check the live benchmarks to see what the proxy in the path costs you.
