Skip to main content
Connect a PostgreSQL database to let CloudThinker agents read schemas, rank slow queries, recommend indexes, and check vacuum, lock, and replication health. You give CloudThinker one connection URL for a dedicated read-only user, and the connection runs in restricted mode: every query is read-only, so agents can’t write even with your approval.

Prerequisites

  • A PostgreSQL endpoint CloudThinker can reach from the internet, such as self-hosted PostgreSQL, Amazon RDS or Aurora, Cloud SQL, or Azure Database for PostgreSQL. Agents connect from CloudThinker Cloud, so localhost and private addresses resolve there, not on your network.
  • No private-link or VPN option exists for this connection yet. If the database is private, expose an endpoint restricted to CloudThinker’s egress IPs. Exposing a read replica keeps the primary private, but its query statistics cover only the replica’s own workload. See Reaching private services.
  • An admin account that can run CREATE ROLE and GRANT.
  • The pg_stat_statements extension, if you want slow-query ranking and workload index advice. Everything else works without it.

Setup

1

Create a read-only user

Connect as an admin and create a login role for CloudThinker:
2

Grant read access

Run these in the database you want analyzed. Repeat the schema lines for every schema besides public that agents should read.
Replace app_owner with the role that creates your application’s tables, often the one your migrations run as. Default privileges only cover tables created by the role you name, so repeat the line for each role that creates tables.pg_monitor lets agents see every session, lock, and query statistic, not only their own.
3

Turn on pg_stat_statements

Check first, since many managed services already preload it:
If pg_stat_statements is missing, add it to shared_preload_libraries and restart PostgreSQL. On RDS, Aurora, or Cloud SQL, set it in the parameter group or database flags and reboot. Skip the restart if it’s already listed. Then, as an admin in the target database:
Success state: signed in as cloudthinker_readonly, SELECT count(*) FROM pg_stat_statements; returns a number instead of an error. That also proves the pg_monitor grant works.
4

Open network access

Allow inbound connections on the PostgreSQL port (default 5432) from CloudThinker’s egress IPs in your firewall, security group, or authorized networks list. These docs don’t publish CloudThinker’s egress IP list: ask your CloudThinker contact, or contact us.On self-hosted PostgreSQL, also let cloudthinker_readonly sign in from those addresses in pg_hba.conf, one line per IP:
Then reload the config with SELECT pg_reload_conf();. Managed services handle this for you.
5

Add the connection in CloudThinker

Open More → Workspace settings → Connections, select PostgreSQL, and click Connect on its detail panel. In the dialog, optionally change the Alias and Description (agents read the description to pick the right database when you connect several). Paste the URL into DATABASE_URI and click Connect:
Success state: the connection shows Connecting and Verifying, then Connected. CloudThinker then runs Discovery once: a read-only look at the database whose results show in the Discovery section of the connection’s detail panel.

Connection details

The form labels the URL field DATABASE_URI. Each connection covers the one database named in the URL. To analyze another database, add another PostgreSQL connection with a different Alias. If the password contains @, :, /, or #, URL-encode it (for example, @ becomes %40), or the URL won’t parse.

Required permissions

Keep the user read-only. Restricted mode already blocks writes from agents (unlike MySQL, where writes go through Approvals), but a SELECT-only role means a mistake in either layer still can’t change data.

Agent capabilities

Verify the connection

Expect table names grouped by schema with their sizes. A permission denied error names the object the user can’t read.

Example prompts

Troubleshooting

CloudThinker can’t reach the host. Check that the host and port in DATABASE_URI are public or otherwise reachable, that your firewall or security group allows CloudThinker, and that listen_addresses in postgresql.conf isn’t localhost. On RDS, the instance must be publicly accessible or reachable through your network setup.
The user or password is wrong, or pg_hba.conf doesn’t allow this user from CloudThinker’s address. Check that the password is URL-encoded in DATABASE_URI, add a pg_hba.conf line for the user, and reload PostgreSQL.
The extension isn’t loaded or created. Confirm SHOW shared_preload_libraries; includes pg_stat_statements, restart if you just added it, and run CREATE EXTENSION pg_stat_statements; in the target database. Statistics start from the last reset, so a fresh server has little history.
The user lacks USAGE on the schema or SELECT on the table. Tables created after your grants need the ALTER DEFAULT PRIVILEGES FOR ROLE line, naming the role that creates them.
Hypothetical index tests need the hypopg extension. Install it, or ask for index recommendations without testing them.

Security

  • Least privilege — grant only the permissions the agents need for your use case; start read-only and widen later.
  • Read-only by default — use read-only credentials unless you want agents to make changes through this connection.
  • Rotate credentials — rotate keys and tokens on your normal schedule; CloudThinker picks up the new value when you update the connection.
  • Revoke on offboarding — remove the credential at the provider when you delete a connection or a teammate leaves.
  • Encrypt in transit: put sslmode=require in DATABASE_URI so credentials and results never cross the network in plain text. verify-full also needs your server’s CA certificate on CloudThinker’s side, and the connection has no field to supply one, so use require.
  • Restricted mode on every query: CloudThinker launches the PostgreSQL connection read-only, so agents can’t write even if the role’s grants would allow it.

CockroachDB

Connect a PostgreSQL-compatible CockroachDB cluster with separate read and write users.

MySQL

Connect MySQL with a read-only user too. Unlike PostgreSQL, MySQL writes go through Approvals instead of being blocked.