PostgreSQL on Cloud SQL: Managed PostgreSQL in GCP

PostgreSQL on Cloud SQL is Google’s managed PostgreSQL service. You get a real PostgreSQL database (same engine, same SQL, same drivers) without managing servers, storage, or backups. Google handles patching, failover, and maintenance; you focus on your schema and your application.

This page covers what PostgreSQL on Cloud SQL is, how to set it up, and the specific behaviours that differ from self-managed PostgreSQL: the permission model, extension support, database flags, and a few version-specific details that catch people out in production. For connection security (Auth Proxy, private IP, IAM auth), see Connecting to Cloud SQL Securely.

What is PostgreSQL on Cloud SQL?

Cloud SQL is GCP’s managed relational database service. It runs MySQL, PostgreSQL, and SQL Server on Google-managed infrastructure. When you create a PostgreSQL instance, you get a real PostgreSQL database running on a Google-managed virtual machine in the region you choose.

The key difference from a self-hosted setup is what you no longer have to do. You do not install the database software, manage OS patches, configure storage, set up backups, or wire together high availability. Google handles all of that. What you still manage is your schema, your data, your users, and how your application connects.

Analogy

Think of it like the difference between leasing a car and buying one. With a lease, someone else handles servicing, depreciation, and compliance checks. You just drive. With Cloud SQL, Google handles the server, the OS, the backups, and the patching. You just write SQL. You give up some customisation, but you gain back a lot of time.

For a broader overview of Cloud SQL across all three engines, see Cloud SQL Overview. If you are deciding which GCP database fits your workload, see Choosing the Right Storage Service.

How PostgreSQL on Cloud SQL works

A Cloud SQL instance is a virtual machine running PostgreSQL, managed by Google. You choose the machine type (which controls CPU and memory), the storage type and size, and the region. Google manages the hypervisor, operating system, and PostgreSQL installation. You interact with the database using the same tools you would use with any PostgreSQL server: psql, application ORMs, database GUIs.

Storage grows automatically if you enable the option. Automated backups run on the schedule you configure. Point-in-time recovery (PITR) is built on PostgreSQL’s write-ahead log (WAL): when backups are enabled, PITR is available automatically with no extra flags. This is simpler than MySQL, which requires separate binary log configuration. For more on backup and recovery options, see Backups and High Availability.

Connections from your application reach Cloud SQL through one of three patterns: the Cloud SQL Auth Proxy (recommended for most cases), private IP within a VPC, or public IP with an authorised networks allowlist. The Auth Proxy handles TLS and IAM authentication, so you do not need to manage SSL certificates or open broad firewall rules. For full connection guidance, see Connecting to Cloud SQL Securely.

High availability is an optional add-on. When enabled, Cloud SQL maintains a standby instance in a different zone within the same region. Failover is automatic if the primary fails. You can also add read replicas for read-heavy workloads.

Two things work differently from self-managed PostgreSQL: you cannot edit postgresql.conf directly (server configuration goes through Cloud SQL database flags), and the postgres user has restricted privileges rather than full superuser access. Both are covered below.

Creating a PostgreSQL instance

Use gcloud sql instances create to create a new instance. The flags below represent a sensible baseline for a production workload: SSD storage, automatic storage growth, and automated backups.

# Create a PostgreSQL 15 instance with backups enabled
gcloud sql instances create my-postgres-instance \
  --database-version=POSTGRES_15 \
  --tier=db-n1-standard-2 \
  --region=europe-west2 \
  --storage-type=SSD \
  --storage-size=20GB \
  --storage-auto-increase \
  --backup-start-time=02:00

PITR is enabled automatically when backups are on. PostgreSQL uses WAL archiving rather than binary logging, so no separate flag is needed.

Note

Cloud SQL does not offer db-f1-micro for PostgreSQL 15 and later. The smallest available tier for development is db-g1-small. For production, choose a tier based on your expected connection count and query workload, not just storage size.

After creating the instance, create a database for your application:

# Create an application database
gcloud sql databases create my-app-db \
  --instance=my-postgres-instance

Users, roles, and permissions

Cloud SQL creates a default user called postgres. On a self-managed instance this user is a full superuser. On Cloud SQL, postgres is a member of the cloudsqlsuperuser role, which has broad privileges but not unrestricted ones. Operations that require genuine superuser access, such as loading server-side extensions not on the approved list, are blocked.

Analogy

Think of postgres on Cloud SQL like a senior employee who has access to most rooms in the building. They can do almost everything. But a few doors (the server room, the electrical panel) require the facilities manager (Google) to open. You hand over control of those rooms in exchange for not having to maintain them.

This restriction is by design. It lets Google run the managed service reliably without allowing tenants to break the underlying infrastructure. In practice you will rarely hit the limit unless you are migrating a workload that depended on OS-level PostgreSQL features.

For your application, create a dedicated user with only the privileges it needs. Do not connect as postgres. PostgreSQL’s permission model is more granular than MySQL’s: you grant database-level, schema-level, and object-level permissions separately.

# Set the postgres user password
gcloud sql users set-password postgres \
  --instance=my-postgres-instance \
  --password=your-secure-password

# Create a dedicated application user
gcloud sql users create app-user \
  --instance=my-postgres-instance \
  --password=app-user-password

Once connected via psql or the Auth Proxy, grant the application user access at each level:

-- Grant connection rights to the database
GRANT CONNECT ON DATABASE my-app-db TO "app-user";

-- Grant usage rights on the schema
GRANT USAGE ON SCHEMA public TO "app-user";

-- Grant access to all existing tables
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO "app-user";

The last grant covers existing tables but not tables created later, for example by application migrations. Set default privileges to handle future tables automatically:

-- Grant permissions on tables created in the future
ALTER DEFAULT PRIVILEGES IN SCHEMA public
  GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO "app-user";
Tip

Store your database password in Secret Manager rather than hardcoding it in environment variables or deployment configuration. This keeps credentials out of your codebase and makes rotation straightforward.

Schemas and the PostgreSQL 15 public schema change

PostgreSQL 15 changed the default permissions on the public schema. Before PostgreSQL 15, every user had the CREATE privilege on the public schema by default. In PostgreSQL 15 and later, that default was revoked. If your application user needs to create tables (which includes running migrations), you must grant this explicitly.

-- PostgreSQL 15+: grant schema creation to the application user
GRANT CREATE ON SCHEMA public TO "app-user";

-- Alternatively, create a dedicated application schema
CREATE SCHEMA myapp AUTHORIZATION "app-user";
Watch out

An application that worked on PostgreSQL 14 or earlier will fail with a permission denied error when running migrations against a new PostgreSQL 15 instance. This is one of the most common surprise failures when upgrading. Check this early, before your first deployment.

PostgreSQL extensions in Cloud SQL

PostgreSQL extensions add functionality to the database: UUID generation, text search, geographic data types, cryptography, and more. You install them per-database with CREATE EXTENSION.

Cloud SQL supports a curated list of extensions. Common ones including pgcrypto, uuid-ossp, PostGIS, pg_trgm, and hstore are available. Extensions that require OS-level access or genuine superuser operations are not. Before building a schema that depends on a specific extension, verify it is on the Cloud SQL supported extensions list. Discovering a missing extension during a migration is an expensive problem.

-- Enable UUID generation
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";

-- Enable trigram indexing for fast text search
CREATE EXTENSION IF NOT EXISTS pg_trgm;

-- Enable PostGIS for geographic data
CREATE EXTENSION IF NOT EXISTS postgis;

-- List currently installed extensions
SELECT extname, extversion FROM pg_extension;
Note

Some extensions (including PostGIS) must be enabled by a cloudsqlsuperuser member before an unprivileged user can use them. If CREATE EXTENSION fails with a permission error, connect as postgres and run it there first.

Configuring PostgreSQL with database flags

On a self-managed PostgreSQL server you edit postgresql.conf to tune memory, connections, and logging. On Cloud SQL, that file is managed by Google and not directly editable. Instead, you set configuration through Cloud SQL database flags, which map directly to PostgreSQL server parameters and are applied via gcloud sql instances patch.

Analogy

Database flags are like the settings app on a smartphone. You can adjust everything the manufacturer exposes to you: display brightness, notification behaviour, power settings. But you cannot open the phone and resolder a component. A self-managed PostgreSQL server is like having the full schematic. Cloud SQL gives you the settings app. For most use cases, the settings app is enough.

# Increase the maximum number of connections
gcloud sql instances patch my-postgres-instance \
  --database-flags=max_connections=200

# Log queries taking longer than 500ms (helps identify slow queries)
gcloud sql instances patch my-postgres-instance \
  --database-flags=log_min_duration_statement=500

# Enable logical decoding for CDC tools like Debezium
gcloud sql instances patch my-postgres-instance \
  --database-flags=cloudsql.logical_decoding=on

# View currently configured flags
gcloud sql instances describe my-postgres-instance \
  --format="value(settings.databaseFlags)"

Some flag changes require a restart. The gcloud response includes a requiresRestart field when a restart is needed. Schedule these during a maintenance window for production instances.

Warning

Each PostgreSQL connection holds several MB of RAM. Setting max_connections too high on a small instance can exhaust memory under load. For applications with many concurrent connections, use a connection pooler like PgBouncer in front of Cloud SQL and keep max_connections at a level the instance tier can actually support.

Importing and exporting data

# Export a database to Cloud Storage as a SQL dump
gcloud sql export sql my-postgres-instance \
  gs://my-backup-bucket/my-app-db-export.sql \
  --database=my-app-db

# Import a SQL dump from Cloud Storage
gcloud sql import sql my-postgres-instance \
  gs://my-backup-bucket/my-app-db-export.sql \
  --database=my-app-db

# Export a single table as CSV
gcloud sql export csv my-postgres-instance \
  gs://my-backup-bucket/my-table.csv \
  --database=my-app-db \
  --query="SELECT * FROM my_table"

The Cloud SQL service account needs roles/storage.objectAdmin on the target bucket, or at minimum storage.objectCreate for exports and storage.objectGet for imports.

Note

Large imports run as long-running operations and do not block the instance. For very large databases or minimal-downtime migrations from an external PostgreSQL system, Database Migration Service (DMS) uses continuous replication to cut over with only seconds of downtime.

When to use PostgreSQL on Cloud SQL

PostgreSQL on Cloud SQL is a strong fit for:

  • Transactional web and mobile applications that need ACID guarantees, relational data, and SQL joins
  • Teams migrating an existing PostgreSQL workload to GCP without rewriting application code or queries
  • Applications that use PostgreSQL-specific features such as PostGIS for geographic data, pg_trgm for text search, or JSONB for semi-structured data
  • Internal tools and admin systems where predictable, consistent query behaviour matters more than horizontal scale
  • Teams that want managed operations (automated backups, HA failover, version patching) without running a database server

PostgreSQL on Cloud SQL may not be the right choice when:

  • You need globally distributed writes across multiple regions. Cloud Spanner is designed for that workload.
  • Your data is document-structured and schema-free. Firestore may fit better; see Cloud SQL vs Firestore.
  • Your workload is primarily analytical. Large scans and aggregations across billions of rows are better handled by BigQuery.
  • You need full superuser access, custom OS-level extensions, or configuration options not exposed through database flags.

PostgreSQL vs MySQL on Cloud SQL

Both engines run on the same Cloud SQL infrastructure with the same management model: same backup system, same connection options, same flag-based configuration. The differences are in the database engines themselves.

PostgreSQLMySQL
Data typesRicher: arrays, JSONB, ranges, custom typesSimpler: JSON supported, fewer native types
Extension ecosystemExtensive: PostGIS, pg_trgm, pgcrypto, hstore, and moreLimited extension support
SQL complianceStrict and standards-compliantHistorically more permissive with non-standard SQL
PITR mechanismWAL archiving, automatic when backups are enabledRequires —enable-bin-log flag at creation
Public schema (v15+)CREATE on public schema must be granted explicitlyNot applicable
Common use casesComplex schemas, GIS, text search, migrations from PostgreSQLLAMP stack apps, existing MySQL workloads, simple schemas

If you are starting from scratch, both engines are reasonable choices for most web applications. PostgreSQL is generally preferred when you need complex data types, richer extensions, or strict SQL behaviour. MySQL is often simpler to set up for straightforward web workloads. For MySQL-specific setup, see Running MySQL on Cloud SQL.

Cloud SQL for PostgreSQL vs self-managed PostgreSQL

Running PostgreSQL on a Compute Engine VM gives you more control at the cost of more responsibility. Here is how the two compare:

  • Operational overhead: Self-managed requires you to handle OS patching, database upgrades, backup configuration, and HA setup. Cloud SQL handles all of that automatically.

  • Superuser access: Self-managed gives you full postgres superuser access. Cloud SQL restricts it to cloudsqlsuperuser. Most applications are unaffected; workloads that need OS-level access or unsupported extensions are not.

  • Configuration: Self-managed lets you edit postgresql.conf and pg_hba.conf directly. Cloud SQL uses database flags, which cover most tuning needs but not every edge case.

  • Extension availability: Self-managed lets you install any extension. Cloud SQL only supports its curated list.

  • Cost: Cloud SQL instances carry managed service overhead. Self-managed VMs are cheaper per CPU-hour but require engineering time to run reliably, which typically costs more in practice.

For most teams building applications on GCP, Cloud SQL is the right default. Self-managed PostgreSQL on Compute Engine makes sense when you have very specific configuration requirements, need extensions Cloud SQL does not support, or are running a cost-sensitive workload where the operational investment is justified.

Common mistakes

  1. Assuming the postgres user has full superuser access. The postgres user on Cloud SQL is more restricted than on a self-managed instance. Operations like loading unsupported extensions or modifying replication settings directly are unavailable. Plan your permission model around cloudsqlsuperuser from the start.

  2. Forgetting default privileges for future tables. Granting access to existing tables but not to future ones means your application fails when a migration creates a new table. Use ALTER DEFAULT PRIVILEGES so tables added later are automatically accessible to the application user.

  3. Not handling the PostgreSQL 15 public schema change. Applications that worked on PostgreSQL 14 or earlier will get a permission denied error when running migrations on a new PostgreSQL 15 instance. Explicitly grant CREATE on the public schema or create a dedicated application schema.

  4. Setting max_connections too high without a connection pooler. Each PostgreSQL connection holds several MB of RAM. Setting max_connections=500 on a small instance can exhaust memory under load. Use PgBouncer for high-connection workloads and size connections to match the instance tier.

  5. Depending on an extension without verifying it is supported. Not every PostgreSQL extension is available in Cloud SQL. Verify an extension is on the supported list before designing a schema that depends on it. Discovering a missing extension during a migration is far more expensive than finding out during planning. If you hit connection problems after setup, see Cloud SQL Connection Refused for troubleshooting steps.

Frequently asked questions

What is PostgreSQL on Cloud SQL?

PostgreSQL on Cloud SQL is Google’s managed PostgreSQL database service. It runs a real PostgreSQL engine, but Google manages the underlying infrastructure: the virtual machine, OS patches, backups, storage, and high availability. You interact with it using standard PostgreSQL tools and application drivers.

Is Cloud SQL PostgreSQL the same as regular PostgreSQL?

For application code, yes. The same SQL, the same drivers, the same query behaviour. The differences are operational: you cannot edit postgresql.conf directly, the postgres user has restricted superuser access, and only supported extensions can be installed. The vast majority of applications run without any changes.

Does Cloud SQL give full superuser access?

No. The postgres user is a member of the cloudsqlsuperuser role, which has broad but restricted privileges. Genuine superuser operations (loading server-side extensions not on the approved list, modifying replication internals) are blocked. This is a deliberate constraint of the managed service.

Which PostgreSQL extensions are supported in Cloud SQL?

Cloud SQL supports a curated list that includes many common extensions: pgcrypto, uuid-ossp, PostGIS, pg_trgm, hstore, and others. Extensions that require OS-level access or unrestricted superuser operations are not supported. Check the Cloud SQL extensions documentation before your project depends on a specific one.

When should I choose PostgreSQL instead of MySQL in Cloud SQL?

Choose PostgreSQL when your application uses complex data types (arrays, JSONB, custom types), geographic data via PostGIS, or depends on strict SQL compliance. Choose PostgreSQL if you are migrating from an existing PostgreSQL system. If you are starting fresh with a straightforward web app schema, either engine works well and the choice often comes down to team familiarity.

Frequently asked questions

What PostgreSQL versions does Cloud SQL support?

Cloud SQL supports PostgreSQL 12, 13, 14, 15, and 16. Use version 15 or 16 for new instances. Older versions such as 9.6 and 10 are deprecated and no longer available for new instances. Check the Cloud SQL documentation for the current supported list, as minor versions are updated regularly.

Is Cloud SQL PostgreSQL the same as regular PostgreSQL?

It runs the same PostgreSQL engine, so your SQL, application drivers, and most tools work without changes. The differences are operational: the postgres user has restricted privileges, you configure server settings through database flags instead of postgresql.conf, and only supported extensions can be installed. For most applications, these constraints are invisible.

Can I use pg_dump to export data from Cloud SQL PostgreSQL?

Yes. Connect via the Cloud SQL Auth Proxy and run pg_dump from your local machine or a Compute Engine VM. Cloud SQL also supports exporting directly to Cloud Storage using gcloud sql export sql, which creates a pg_dump-compatible file without impacting the running instance. For very large databases, Database Migration Service is a better option.

Does Cloud SQL for PostgreSQL support logical replication?

Yes. Enable logical replication by setting the cloudsql.logical_decoding flag to on. This allows external tools like Debezium to read the write-ahead log (WAL) for change data capture. External read replicas using logical replication are also supported for migration scenarios.

Last verified: 23 March 2026 Cloud services change frequently. Verify details against official documentation before making infrastructure decisions.