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
localhostand 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 ROLEandGRANT. - The
pg_stat_statementsextension, 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 Replace
public that agents should read.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 Success state: signed in as
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: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 Then reload the config with
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: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
Agent capabilities
Verify the connection
permission denied error names the object the user can’t read.
Example prompts
Troubleshooting
Connection refused or timed out
Connection refused or timed out
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.Password authentication failed or no pg_hba.conf entry
Password authentication failed or no pg_hba.conf entry
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.pg_stat_statements not found, or no slow-query data
pg_stat_statements not found, or no slow-query data
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.Permission denied for a table or schema
Permission denied for a table or schema
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.HypoPG not installed
HypoPG not installed
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=requirein DATABASE_URI so credentials and results never cross the network in plain text.verify-fullalso needs your server’s CA certificate on CloudThinker’s side, and the connection has no field to supply one, so userequire. - 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.
Related
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.