I needed to connect to a Cloud SQL instance to debug a data issue. Here’s the quick way to get a psql session without fiddling with IP allowlists or VPN connections.

Using a service account:

gcloud beta sql connect my-instance \
    --project my-project \
    --user=my-user \
    -d=my-database

Using IAM authentication (your Google account):

gcloud sql generate-login-token | pbcopy && \
gcloud beta sql connect my-instance \
    --project my-project \
    --user=me@example.com \
    -d=my-database

The pbcopy puts the token in your clipboard so you can paste it as the password.

If you haven’t got the proxy installed:

gcloud components install cloud-sql-proxy

You can also use the proxy directly for longer sessions:

cloud-sql-proxy my-project:europe-north1:my-instance

Then connect with your normal psql client to localhost:5432.

Proxy vs direct connection: when to use which Link to heading

Use the Cloud SQL proxy when:

  • You’re connecting from your local machine for debugging
  • You’re running a long-lived application (the proxy handles reconnections)
  • You want IAM authentication (no need to manage database passwords)
  • You’re connecting from Kubernetes (using the sidecar pattern)
  • Security is a concern (all traffic goes through an encrypted tunnel)

Use a direct connection (private IP) when:

  • You’re in the same VPC as the database
  • You need the lowest possible latency (no extra hop through the proxy)
  • You’re using connection pooling tools like PgBouncer (they can’t work through the proxy)

Use a public IP connection when:

  • You’re doing a one-off migration from an external service
  • Your application is outside GCP and you can’t use the proxy

For production applications, I always use private IP with connection pooling. For debugging and one-off scripts, the proxy is much more convenient.

Security considerations Link to heading

The good news:

  • The Cloud SQL proxy encrypts all traffic, even if you’re connecting to a public IP
  • IAM authentication means no database passwords to rotate or leak
  • You can grant temporary access via IAM without touching the database

The gotchas:

  • If you’re using IAM auth, the database user must be created with GRANT cloudsqliamuser
  • The IAM user/service account needs roles/cloudsql.client permission
  • IAM tokens expire after an hour, so long-running connections need to handle re-authentication

What I got wrong once: I set up IAM auth but forgot that the Cloud SQL instance needs the cloudsql.iam_authentication flag enabled. Spent 20 minutes debugging before I found that setting buried in the instance configuration.

Also, if you’re connecting from GKE, use Workload Identity for the service account, not a key file. I’ve seen teams accidentally commit service account keys trying to set up Cloud SQL access.

Further reading Link to heading