Monitoring On-Prem Postgres Without a VPN
If your database holds regulated data, the standard monitoring pitch sounds good until security reviews it: "install our agent, and it will phone home to our cloud." For Postgres workloads under PCI, HIPAA, or strict internal compliance rules, that sentence ends the conversation. The data cannot leave, the agent cannot reach out, and nobody wants to maintain a VPN just to let a vendor watch queries.
There is a third path, and it starts by being precise about which data you are protecting. Praxion's agent is a process you run inside your own network — a container or a native binary. It reads pg_stat_statements from your read-only replica, anonymizes the queries, and sends metadata only. Row values never leave, on any plan. What varies by plan is the transport: Starter and Growth reach the platform API over HTTPS/TLS, and Enterprise connects over AWS PrivateLink.
The classic tradeoff
Historically you had two choices, and both were bad:
- Cloud agent. Great visibility, but the agent maintains an outbound connection to the vendor's cloud. Security teams reject it because the database effectively has a phone line to a third party.
- Air-gapped tooling. Perfectly private, but you lose the intelligence: no automated analysis, no alerting, no second pair of eyes on your query performance. Everything stays manual.
The middle ground people reach for is a VPN or a bastion host. It works, but it widens your attack surface, needs certificate management, and still funnels sensitive traffic through a gateway you now have to maintain.
Private connectivity, two ways
Praxion matches the transport to the plan, so every customer gets a private-by-design connection:
- Enterprise — AWS PrivateLink. The connection is a private interface that exists inside AWS's network. It never touches the public internet and never needs an IP allowlist. It is not self-serve: we provision a VPC endpoint service against your AWS account first, and only then does a private DNS name exist for the agent to use as its
CONTROL_PLANE_URL. Azure Private Link works the same way. - Starter and Growth — HTTPS/TLS. The agent authenticates and connects outwards to the platform API over TLS. No VPN, and your database never exposes a port to anyone.
In both cases the payload is the same deliberately minimal data contract. The transport is what changes, not what travels.
Enterprise: PrivateLink is a private interface, not a tunnel
With AWS PrivateLink the endpoint service is provisioned against your account, and the private DNS name it issues becomes the agent's control-plane address. For a regulated workload that converts "the vendor's agent is in our VPC" from a security finding into a non-event.
agent (container or binary)
reads replica
private DNS name
CONTROL_PLANE_URL
From a networking perspective it is a private interface between the two accounts — no peering, no gateway, no SSH, no public DNS name for your side.
Minimal telemetry: what crosses, what never does
The transport solves how data travels. A second principle decides what travels at all: send the minimum that still allows useful analysis.
What a well-designed agent emits:
- Query fingerprints — stable hashes of normalized statements, not the statements themselves
- Latency percentiles — p50/p95/p99 per fingerprint
- Catalog metadata — the tables and columns the schema map and glossary are built from
- Heartbeats — a liveness signal, so silence is detectable
What never crosses: row values, credentials, and the host and database names. Those two are fingerprinted the moment they arrive and the originals are discarded, which is why the panel can list your databases without being able to tell anyone what they are called.
What the agent needs, and what it never needs
Be honest about the baseline: if your environment permits no outbound connection at all, no hosted analyser of any kind will work, and the honest answer is to fix it locally. Praxion is not an air-gapped product, and claiming otherwise would be a worse answer than the truth.
What it does need is short: a reachable read-only replica with pg_stat_statements enabled, Docker or a native binary, outbound HTTPS, and four settings — AGENT_ID, LICENSE_KEY, CONTROL_PLANE_URL and PG_REPLICA_DSN. What it never needs: an inbound port, a VPN, a bastion host, a public DNS record for your database, or write credentials of any kind.
What this means for compliance
- Row values never leave the network — on any plan, not only on Enterprise
- Row-level identifiers are discarded — hosts and database names are fingerprinted on arrival, so the panel never holds the original
- Prove what happened afterwards — the audit log is append-only and hash-chained, and
make audit-verifychecks its integrity. Only state changes are recorded: applying an optimization, editing the glossary, changing a role, connecting a database - Detectable silence — an agent counts as running only if it reported in the last 90 seconds, so a stopped process or a blocked connection reads as exactly that instead of as a quiet, healthy agent
The result is monitoring that behaves like infrastructure you own, not a vendor you trust. The transport keeps the connection private — PrivateLink on Enterprise, HTTPS/TLS on Starter and Growth — and a deliberately narrow data contract keeps the data yours.
Private by architecture, not by policy.
See how the two transports differ, and what never crosses either of them.
See the architecture →