Security & Compliance

Data Handling — What MonPG Stores

Exactly which data flows to MonPG and how it's stored.

This page exists for the security review your buyer is going to ask you to send us. Most of it is about what we do collect, what we don't, and how it's stored. If you're reading this for compliance reasons, the short version: schema and metric data, not row data; encrypted at rest, isolated per tenant; retention varies by plan.

What we collect

System metrics — TPS, connections, cache hit ratio, disk usage. Just numbers, no row content. Query fingerprints, which is normalized SQL with the constants stripped out: SELECT * FROM users WHERE id = ? with the actual ID replaced by a placeholder. We never see the literal value. Query plans, but only if you've enabled auto_explain; plans contain table and index names but PostgreSQL's EXPLAIN doesn't leak row data, that's a property of the plan format itself. Schema metadata: table names, column names, index names, sizes, estimated row counts. And log entries, but only if you've configured log collection — and what's in those logs depends entirely on your log_statement / log_min_duration config; if you log query bind values, we store what you logged.

What we don't

Row data from your tables. We never run SELECT *; the role we provision can read system catalogs and stats views, not your application tables. Backup contents — we don't read those at all. Application connection passwords — we use a dedicated monpg_monitor role we created, your app's credentials are never in our path.

Where it's stored

Operational data (your servers, users, alert rules) goes to PostgreSQL on Azure with encryption at rest via Azure Storage Service Encryption. Time-series data (metrics, snapshots, query stats) goes to ClickHouse on Azure, also encrypted at rest, with column-store compression and partition-level retention. Log entries also live in ClickHouse with compression. Customer DB credentials in hosted mode are wrapped with Azure Key Vault and only the ciphertext sits in our PostgreSQL — only the hosted-fleet collector role can unwrap them.

Tenant isolation

Every row in every table carries an organization_id. PostgreSQL Row-Level Security policies enforce isolation at the database layer; ClickHouse Row Policies enforce the same on the analytical store. Two safety nets — even a bug in application code can't cross-tenant leak, because the database itself refuses to return rows the active session isn't scoped to. We test this with a deny-all default and explicit per-tenant grants, not the other way around.

Retention

Free 7 days, Pro 30 days, Business 90 days, Enterprise custom. After retention, time-series rows drop off via ClickHouse TTL. Operational data (server configs, alert rules) is kept indefinitely until you delete the org. If you want operational data deleted while keeping the org alive, the API supports per-server delete + a cool-off window before purge.