Connect from Cloud Run

MySQL  |  PostgreSQL  |  SQL Server

This page contains information and examples for connecting to aCloud SQL instance from a service running in Cloud Run.

For step-by-step instructions on running a Cloud Run sample web application connected to Cloud SQL, see thequickstart for connecting from Cloud Run.

Cloud SQL is a fully-managed database service that helps you set up, maintain, manage, and administer your relational databases in the cloud.

Cloud Run is a managed compute platform that lets you run containers directly on top of Google Cloud infrastructure.

Set up a Cloud SQL instance

  1. Enable the Cloud SQL Admin API in the Google Cloud project that you are connecting from, if you haven't already done so:

    Enable the API

  2. Create a Cloud SQL for PostgreSQL instance. We recommend that you choose a Cloud SQL instance location in the same region as your Cloud Run service for better latency, to avoid some networking costs, and to reduce cross region failure risks.

    By default, Cloud SQL assigns a public IP address to a new instance. You also have the option to assign a private IP address. For more information about the connectivity options for both, see the Connecting Overview page.

  3. When you create the instance, you can choose the server certificate (CA) hierarchy for the instance and then configure the hierarchy as theserverCaMode for the instance. You must select the per-instance CA option (GOOGLE_MANAGED_INTERNAL_CA) as the server CA mode for instances that you want to connect to from web applications.

Configure Cloud Run

The steps to configure Cloud Run depend on the type of IP address thatyou assigned to your Cloud SQL instance. If you route all egress trafficthrough Direct VPC egress or a Serverless VPC Access connector, use aprivate IP address.Compare the two network egress methods.

Public IP (default)

Like any configuration change, setting a new configuration for the Cloud SQL connection leads to the creation of a new Cloud Run revision. Subsequent revisions will also automatically get this Cloud SQL connection unless you make explicit updates to change it.

Console

  1. Go to Cloud Run

  2. Start configuring the service. To add Cloud SQL connections to an existing service, do the following:

    1. From theServices list, click the service name you want.
    2. ClickEdit & deploy new revision.
  3. Enable connecting to a Cloud SQL instance:Note: If your application is written in Java you can skip this step, since you do this in the Java Cloud SQL Connector.
    1. ClickContainer(s) and thenSettings.
    2. Scroll toCloud SQL connections.
    3. ClickAdd connection.
    4. ClickEnable the Cloud SQL Admin button if you haven't enabled the Cloud SQL Admin API yet.

    Add a Cloud SQL connection

    • If you're adding a connection to a Cloud SQL instance in your project, then select the Cloud SQL instance you want from the menu.
    • If you're using a Cloud SQL instance from another project, then selectcustom connection string in the menu and enter the full instance connection name in the formatPROJECT-ID:REGION:INSTANCE-ID.
    • To delete a connection, hold your cursor to the right of the connection to display theDelete icon, and click it.
    Note:For more information about adding Cloud SQL connections to a service that you're creating, seeDeploying a new service.
  4. ClickCreate orDeploy.

Command line

Before using any of the following commands, make the following replacements:

  • IMAGE with the image you're deploying
  • SERVICE_NAME with the name of your Cloud Run service
  • INSTANCE_CONNECTION_NAME with the instance connection name of your Cloud SQL instance, or a comma delimited list of connection names.

    If you're deploying a new container, use the following command:

    gcloudrundeploy\--image=IMAGE\--add-cloudsql-instances=INSTANCE_CONNECTION_NAME
    If you're updating an existing service, use the following command:
    gcloudrunservicesupdateSERVICE_NAME\--add-cloudsql-instances=INSTANCE_CONNECTION_NAME

Terraform

The following code creates a base Cloud Run container, with a connected Cloud SQL instance.

resource"google_cloud_run_v2_service""default"{name="cloudrun-service"location="us-central1"deletion_protection=false # set to "true" in productiontemplate{containers{image="us-docker.pkg.dev/cloudrun/container/hello:latest" # Image to deployvolume_mounts{name="cloudsql"mount_path="/cloudsql"}}volumes{name="cloudsql"cloud_sql_instance{instances=[google_sql_database_instance.default.connection_name]}}}client="terraform"depends_on=[google_project_service.secretmanager_api,google_project_service.cloudrun_api,google_project_service.sqladmin_api]}

  1. Apply the changes by enteringterraform apply.
  2. Verify the changes by checking theCloud Run service, clicking theRevisions tab, and then theConnections tab.

Private IP

If the authorizing service account belongs to a different project than theone containing the Cloud SQL instance, do the following:

  • In both projects, enable the Cloud SQL Admin API.
  • For the service account in the project that contains the Cloud SQL instance, add theIAM permissions.
Direct VPC egress and connectors use private IP addresses to handlecommunication to your VPC network.To connect directly with private IP addresses using one of these egress methods,do the following:
  1. Make sure that the Cloud SQL instance created previously has a private IP address. To add an internal IP address, seeConfigure private IP.
  2. Configure your egress method to connect to the same VPC network as your Cloud SQL instance. Note the following conditions:
    • Direct VPC egress and Serverless VPC Access both support communication to VPC networks connected usingCloud VPN andVPC Network Peering.
    • Direct VPC egress and Serverless VPC Access don't supportlegacy networks.
    • Unless you're using Shared VPC, a connector must share the same project and region as the resource that uses it, although the connector can send traffic to resources in different regions.
  3. Connect using your instance's private IP address and port5432.

Connect to Cloud SQL

After you configure Cloud Run, you can connect to yourCloud SQL instance.

Public IP (default)

Warning: If you're using a first generation execution environment for your Cloud Run service, then you can connect only to a Cloud SQL instance that's configured with theper-instance certificate authority (CA) option (GOOGLE_MANAGED_INTERNAL_CA) as its server CA mode. The first generation execution environment of Cloud Run embeds the Cloud SQL Auth Proxy v1. For more information about connection requirements to Cloud SQL for the Cloud SQL Auth Proxy, seeRequirements for using the Cloud SQL Auth Proxy.

For public IP paths, Cloud Run provides encryption and connects using theCloud SQL Auth Proxy in two ways:

Connect with Unix sockets

Once correctly configured, you can connect your service to your Cloud SQL instance's Unix domain socket accessed on the environment's filesystem at the following path:/cloudsql/INSTANCE_CONNECTION_NAME.

TheINSTANCE_CONNECTION_NAME uses the formatproject:region:instance-id. You can find it on theOverview page for your instance in theGoogle Cloud console or by running the following command:

gcloud sql instances describe [INSTANCE_NAME]

These connections are automatically encrypted without any additional configuration.

The code samples shown below are extracts from more complete examples on the GitHub site. ClickView on GitHub to see more.

Note: The PostgreSQL standard requires a.s.PGSQL.5432 suffix in the socket path. Some libraries apply this suffix automatically, but others require you to specify the socket path as follows:
/cloudsql/INSTANCE_CONNECTION_NAME/.s.PGSQL.5432
Warning: Linux-based operating systems have a maximum socket path length of 108 characters. If the total length of the path exceeds this length, you cannot connect with a socket from Cloud Run.

Python

To see this snippet in the context of a web application, viewthe README on GitHub.

importosimportsqlalchemydefconnect_unix_socket()->sqlalchemy.engine.base.Engine:"""Initializes a Unix socket connection pool for a Cloud SQL instance of Postgres."""# Note: Saving credentials in environment variables is convenient, but not# secure - consider a more secure solution such as# Cloud Secret Manager (https://cloud.google.com/secret-manager) to help# keep secrets safe.db_user=os.environ["DB_USER"]# e.g. 'my-database-user'db_pass=os.environ["DB_PASS"]# e.g. 'my-database-password'db_name=os.environ["DB_NAME"]# e.g. 'my-database'unix_socket_path=os.environ["INSTANCE_UNIX_SOCKET"]# e.g. '/cloudsql/project:region:instance'pool=sqlalchemy.create_engine(# Equivalent URL:# postgresql+pg8000://<db_user>:<db_pass>@/<db_name>#                         ?unix_sock=<INSTANCE_UNIX_SOCKET>/.s.PGSQL.5432# Note: Some drivers require the `unix_sock` query parameter to use a different key.# For example, 'psycopg2' uses the path set to `host` in order to connect successfully.sqlalchemy.engine.url.URL.create(drivername="postgresql+pg8000",username=db_user,password=db_pass,database=db_name,query={"unix_sock":f"{unix_socket_path}/.s.PGSQL.5432"},),# ...)returnpool

Java

To see this snippet in the context of a web application, viewthe README on GitHub.

importcom.zaxxer.hikari.HikariConfig;importcom.zaxxer.hikari.HikariDataSource;importjavax.sql.DataSource;publicclassConnectorConnectionPoolFactoryextendsConnectionPoolFactory{// Note: Saving credentials in environment variables is convenient, but not// secure - consider a more secure solution such as// Cloud Secret Manager (https://cloud.google.com/secret-manager) to help// keep secrets safe.privatestaticfinalStringINSTANCE_CONNECTION_NAME=System.getenv("INSTANCE_CONNECTION_NAME");privatestaticfinalStringINSTANCE_UNIX_SOCKET=System.getenv("INSTANCE_UNIX_SOCKET");privatestaticfinalStringDB_USER=System.getenv("DB_USER");privatestaticfinalStringDB_PASS=System.getenv("DB_PASS");privatestaticfinalStringDB_NAME=System.getenv("DB_NAME");publicstaticDataSourcecreateConnectionPool(){// The configuration object specifies behaviors for the connection pool.HikariConfigconfig=newHikariConfig();// The following URL is equivalent to setting the config options below:// jdbc:postgresql:///<DB_NAME>?cloudSqlInstance=<INSTANCE_CONNECTION_NAME>&// socketFactory=com.google.cloud.sql.postgres.SocketFactory&user=<DB_USER>&password=<DB_PASS>// See the link below for more info on building a JDBC URL for the Cloud SQL JDBC Socket Factory// https://github.com/GoogleCloudPlatform/cloud-sql-jdbc-socket-factory#creating-the-jdbc-url// Configure which instance and what database user to connect with.config.setJdbcUrl(String.format("jdbc:postgresql:///%s",DB_NAME));config.setUsername(DB_USER);// e.g. "root", _postgres"config.setPassword(DB_PASS);// e.g. "my-password"config.addDataSourceProperty("socketFactory","com.google.cloud.sql.postgres.SocketFactory");config.addDataSourceProperty("cloudSqlInstance",INSTANCE_CONNECTION_NAME);// Unix sockets are not natively supported in Java, so it is necessary to use the Cloud SQL// Java Connector to connect. When setting INSTANCE_UNIX_SOCKET, the connector will// call an external package that will enable Unix socket connections.// Note: For Java users, the Cloud SQL Java Connector can provide authenticated connections// which is usually preferable to using the Cloud SQL Proxy with Unix sockets.// See https://github.com/GoogleCloudPlatform/cloud-sql-jdbc-socket-factory for details.if(INSTANCE_UNIX_SOCKET!=null){config.addDataSourceProperty("unixSocketPath",INSTANCE_UNIX_SOCKET);}// cloudSqlRefreshStrategy set to "lazy" is used to perform a// refresh when needed, rather than on a scheduled interval.// This is recommended for serverless environments to// avoid background refreshes from throttling CPU.config.addDataSourceProperty("cloudSqlRefreshStrategy","lazy");// ... Specify additional connection properties here.// ...// Initialize the connection pool using the configuration object.returnnewHikariDataSource(config);}}

Node.js

To see this snippet in the context of a web application, viewthe README on GitHub.

constKnex=require('knex');// createUnixSocketPool initializes a Unix socket connection pool for// a Cloud SQL instance of Postgres.constcreateUnixSocketPool=asyncconfig=>{// Note: Saving credentials in environment variables is convenient, but not// secure - consider a more secure solution such as// Cloud Secret Manager (https://cloud.google.com/secret-manager) to help// keep secrets safe.returnKnex({client:'pg',connection:{user:process.env.DB_USER,// e.g. 'my-user'password:process.env.DB_PASS,// e.g. 'my-user-password'database:process.env.DB_NAME,// e.g. 'my-database'host:process.env.INSTANCE_UNIX_SOCKET,// e.g. '/cloudsql/project:region:instance'},// ... Specify additional properties here....config,});};

C#

To see this snippet in the context of a web application, viewthe README on GitHub.

usingNpgsql;usingSystem;namespaceCloudSql{publicclassPostgreSqlUnix{publicstaticNpgsqlConnectionStringBuilderNewPostgreSqlUnixSocketConnectionString(){// Equivalent connection string:// "Server=<INSTANCE_UNIX_SOCKET>;Uid=<DB_USER>;Pwd=<DB_PASS>;Database=<DB_NAME>"varconnectionString=newNpgsqlConnectionStringBuilder(){// The Cloud SQL proxy provides encryption between the proxy and instance.SslMode=SslMode.Disable,// Note: Saving credentials in environment variables is convenient, but not// secure - consider a more secure solution such as// Cloud Secret Manager (https://cloud.google.com/secret-manager) to help// keep secrets safe.Host=Environment.GetEnvironmentVariable("INSTANCE_UNIX_SOCKET"),// e.g. '/cloudsql/project:region:instance'Username=Environment.GetEnvironmentVariable("DB_USER"),// e.g. 'my-db-userPassword=Environment.GetEnvironmentVariable("DB_PASS"),// e.g. 'my-db-password'Database=Environment.GetEnvironmentVariable("DB_NAME"),// e.g. 'my-database'};connectionString.Pooling=true;// Specify additional properties here.returnconnectionString;}}}

Go

To see this snippet in the context of a web application, viewthe README on GitHub.

packagecloudsqlimport("database/sql""fmt""log""os"// Note: If connecting using the App Engine Flex Go runtime, use// "github.com/jackc/pgx/stdlib" instead, since v5 requires// Go modules which are not supported by App Engine Flex._"github.com/jackc/pgx/v5/stdlib")// connectUnixSocket initializes a Unix socket connection pool for// a Cloud SQL instance of Postgres.funcconnectUnixSocket()(*sql.DB,error){mustGetenv:=func(kstring)string{v:=os.Getenv(k)ifv==""{log.Fatalf("Fatal Error in connect_unix.go: %s environment variable not set.\n",k)}returnv}// Note: Saving credentials in environment variables is convenient, but not// secure - consider a more secure solution such as// Cloud Secret Manager (https://cloud.google.com/secret-manager) to help// keep secrets safe.var(dbUser=mustGetenv("DB_USER")// e.g. 'my-db-user'dbPwd=mustGetenv("DB_PASS")// e.g. 'my-db-password'unixSocketPath=mustGetenv("INSTANCE_UNIX_SOCKET")// e.g. '/cloudsql/project:region:instance'dbName=mustGetenv("DB_NAME")// e.g. 'my-database')dbURI:=fmt.Sprintf("user=%s password=%s database=%s host=%s",dbUser,dbPwd,dbName,unixSocketPath)// dbPool is the pool of database connections.dbPool,err:=sql.Open("pgx",dbURI)iferr!=nil{returnnil,fmt.Errorf("sql.Open: %w",err)}// ...returndbPool,nil}

Ruby

To see this snippet in the context of a web application, viewthe README on GitHub.

unix:&unixadapter:postgresql# Configure additional properties here.# Note: Saving credentials in environment variables is convenient, but not# secure - consider a more secure solution such as# Cloud Secret Manager (https://cloud.google.com/secret-manager) to help# keep secrets safe.username:<%= ENV["DB_USER"] %>  # e.g. "my-database-user"  password: <%=ENV["DB_PASS"]%># e.g. "my-database-password"database:<%= ENV.fetch("DB_NAME") { "vote_development" } %>  # Specify the Unix socket path as host  host: "<%=ENV["INSTANCE_UNIX_SOCKET"]%>"

PHP

To see this snippet in the context of a web application, viewthe README on GitHub.

namespace Google\Cloud\Samples\CloudSQL\Postgres;use PDO;use PDOException;use RuntimeException;use TypeError;class DatabaseUnix{    public static function initUnixDatabaseConnection(): PDO    {        try {            // Note: Saving credentials in environment variables is convenient, but not            // secure - consider a more secure solution such as            // Cloud Secret Manager (https://cloud.google.com/secret-manager) to help            // keep secrets safe.            $username = getenv('DB_USER'); // e.g. 'your_db_user'            $password = getenv('DB_PASS'); // e.g. 'your_db_password'            $dbName = getenv('DB_NAME'); // e.g. 'your_db_name'            $instanceUnixSocket = getenv('INSTANCE_UNIX_SOCKET'); // e.g. '/cloudsql/project:region:instance'            // Connect using UNIX sockets            $dsn = sprintf(                'pgsql:dbname=%s;host=%s',                $dbName,                $instanceUnixSocket            );            // Connect to the database.            $conn = new PDO(                $dsn,                $username,                $password,                # ...            );        } catch (TypeError $e) {            throw new RuntimeException(                sprintf(                    'Invalid or missing configuration! Make sure you have set ' .                        '$username, $password, $dbName, ' .                        'and $instanceUnixSocket (for UNIX socket mode). ' .                        'The PHP error was %s',                    $e->getMessage()                ),                (int) $e->getCode(),                $e            );        } catch (PDOException $e) {            throw new RuntimeException(                sprintf(                    'Could not connect to the Cloud SQL Database. Check that ' .                        'your username and password are correct, that the Cloud SQL ' .                        'proxy is running, and that the database exists and is ready ' .                        'for use. For more assistance, refer to %s. The PDO error was %s',                    'https://cloud.google.com/sql/docs/postgres/connect-external-app',                    $e->getMessage()                ),                (int) $e->getCode(),                $e            );        }        return $conn;    }}

Connect with Cloud SQL connectors

TheCloud SQL connectors are language specific libraries that provide encryption and IAM-based authorization when connecting to a Cloud SQL instance.

Python

To see this snippet in the context of a web application, viewthe README on GitHub.

importosfromgoogle.cloud.sql.connectorimportConnector,IPTypesimportpg8000importsqlalchemydefconnect_with_connector()->sqlalchemy.engine.base.Engine:"""    Initializes a connection pool for a Cloud SQL instance of Postgres.    Uses the Cloud SQL Python Connector package.    """# Note: Saving credentials in environment variables is convenient, but not# secure - consider a more secure solution such as# Cloud Secret Manager (https://cloud.google.com/secret-manager) to help# keep secrets safe.instance_connection_name=os.environ["INSTANCE_CONNECTION_NAME"]# e.g. 'project:region:instance'db_user=os.environ["DB_USER"]# e.g. 'my-db-user'db_pass=os.environ["DB_PASS"]# e.g. 'my-db-password'db_name=os.environ["DB_NAME"]# e.g. 'my-database'ip_type=IPTypes.PRIVATEifos.environ.get("PRIVATE_IP")elseIPTypes.PUBLIC# initialize Cloud SQL Python Connector objectconnector=Connector(refresh_strategy="LAZY")defgetconn()->pg8000.dbapi.Connection:conn:pg8000.dbapi.Connection=connector.connect(instance_connection_name,"pg8000",user=db_user,password=db_pass,db=db_name,ip_type=ip_type,)returnconn# The Cloud SQL Python Connector can be used with SQLAlchemy# using the 'creator' argument to 'create_engine'pool=sqlalchemy.create_engine("postgresql+pg8000://",creator=getconn,# ...)returnpool

Java

To see this snippet in the context of a web application, viewthe README on GitHub.

Note:

  • CLOUD_SQL_CONNECTION_NAME should be represented as <MY-PROJECT>:<INSTANCE-REGION>:<INSTANCE-NAME>
  • See the JDBC socket factory version requirements for the pom.xml file here.

importcom.zaxxer.hikari.HikariConfig;importcom.zaxxer.hikari.HikariDataSource;importjavax.sql.DataSource;publicclassConnectorConnectionPoolFactoryextendsConnectionPoolFactory{// Note: Saving credentials in environment variables is convenient, but not// secure - consider a more secure solution such as// Cloud Secret Manager (https://cloud.google.com/secret-manager) to help// keep secrets safe.privatestaticfinalStringINSTANCE_CONNECTION_NAME=System.getenv("INSTANCE_CONNECTION_NAME");privatestaticfinalStringINSTANCE_UNIX_SOCKET=System.getenv("INSTANCE_UNIX_SOCKET");privatestaticfinalStringDB_USER=System.getenv("DB_USER");privatestaticfinalStringDB_PASS=System.getenv("DB_PASS");privatestaticfinalStringDB_NAME=System.getenv("DB_NAME");publicstaticDataSourcecreateConnectionPool(){// The configuration object specifies behaviors for the connection pool.HikariConfigconfig=newHikariConfig();// The following URL is equivalent to setting the config options below:// jdbc:postgresql:///<DB_NAME>?cloudSqlInstance=<INSTANCE_CONNECTION_NAME>&// socketFactory=com.google.cloud.sql.postgres.SocketFactory&user=<DB_USER>&password=<DB_PASS>// See the link below for more info on building a JDBC URL for the Cloud SQL JDBC Socket Factory// https://github.com/GoogleCloudPlatform/cloud-sql-jdbc-socket-factory#creating-the-jdbc-url// Configure which instance and what database user to connect with.config.setJdbcUrl(String.format("jdbc:postgresql:///%s",DB_NAME));config.setUsername(DB_USER);// e.g. "root", _postgres"config.setPassword(DB_PASS);// e.g. "my-password"config.addDataSourceProperty("socketFactory","com.google.cloud.sql.postgres.SocketFactory");config.addDataSourceProperty("cloudSqlInstance",INSTANCE_CONNECTION_NAME);// The ipTypes argument can be used to specify a comma delimited list of preferred IP types// for connecting to a Cloud SQL instance. The argument ipTypes=PRIVATE will force the// SocketFactory to connect with an instance's associated private IP.config.addDataSourceProperty("ipTypes","PUBLIC,PRIVATE");// cloudSqlRefreshStrategy set to "lazy" is used to perform a// refresh when needed, rather than on a scheduled interval.// This is recommended for serverless environments to// avoid background refreshes from throttling CPU.config.addDataSourceProperty("cloudSqlRefreshStrategy","lazy");// ... Specify additional connection properties here.// ...// Initialize the connection pool using the configuration object.returnnewHikariDataSource(config);}}

Go

To see this snippet in the context of a web application, viewthe README on GitHub.

packagecloudsqlimport("context""database/sql""fmt""log""net""os""cloud.google.com/go/cloudsqlconn""github.com/jackc/pgx/v5""github.com/jackc/pgx/v5/stdlib")funcconnectWithConnector()(*sql.DB,error){mustGetenv:=func(kstring)string{v:=os.Getenv(k)ifv==""{log.Fatalf("Fatal Error in connect_connector.go: %s environment variable not set.\n",k)}returnv}// Note: Saving credentials in environment variables is convenient, but not// secure - consider a more secure solution such as// Cloud Secret Manager (https://cloud.google.com/secret-manager) to help// keep passwords and other secrets safe.var(dbUser=mustGetenv("DB_USER")// e.g. 'my-db-user'dbPwd=mustGetenv("DB_PASS")// e.g. 'my-db-password'dbName=mustGetenv("DB_NAME")// e.g. 'my-database'instanceConnectionName=mustGetenv("INSTANCE_CONNECTION_NAME")// e.g. 'project:region:instance'usePrivate=os.Getenv("PRIVATE_IP"))dsn:=fmt.Sprintf("user=%s password=%s database=%s",dbUser,dbPwd,dbName)config,err:=pgx.ParseConfig(dsn)iferr!=nil{returnnil,err}varopts[]cloudsqlconn.OptionifusePrivate!=""{opts=append(opts,cloudsqlconn.WithDefaultDialOptions(cloudsqlconn.WithPrivateIP()))}// WithLazyRefresh() Option is used to perform refresh// when needed, rather than on a scheduled interval.// This is recommended for serverless environments to// avoid background refreshes from throttling CPU.opts=append(opts,cloudsqlconn.WithLazyRefresh())d,err:=cloudsqlconn.NewDialer(context.Background(),opts...)iferr!=nil{returnnil,err}// Use the Cloud SQL connector to handle connecting to the instance.// This approach does *NOT* require the Cloud SQL proxy.config.DialFunc=func(ctxcontext.Context,network,instancestring)(net.Conn,error){returnd.Dial(ctx,instanceConnectionName)}dbURI:=stdlib.RegisterConnConfig(config)dbPool,err:=sql.Open("pgx",dbURI)iferr!=nil{returnnil,fmt.Errorf("sql.Open: %w",err)}returndbPool,nil}

Node.js

To see this snippet in the context of a web application, viewthe README on GitHub.

constKnex=require('knex');const{Connector}=require('@google-cloud/cloud-sql-connector');// In case the PRIVATE_IP environment variable is defined then we set// the ipType=PRIVATE for the new connector instance, otherwise defaults// to public ip type.constgetIpType=()=>process.env.PRIVATE_IP==='1'||process.env.PRIVATE_IP==='true'?'PRIVATE':'PUBLIC';// connectWithConnector initializes connection pool for a Cloud SQL instance// of Postgres using the Cloud SQL Node.js Connector.constconnectWithConnector=asyncconfig=>{// Note: Saving credentials in environment variables is convenient, but not// secure - consider a more secure solution such as// Cloud Secret Manager (https://cloud.google.com/secret-manager) to help// keep secrets safe.constconnector=newConnector();constclientOpts=awaitconnector.getOptions({instanceConnectionName:process.env.INSTANCE_CONNECTION_NAME,ipType:getIpType(),});constdbConfig={client:'pg',connection:{...clientOpts,user:process.env.DB_USER,// e.g. 'my-user'password:process.env.DB_PASS,// e.g. 'my-user-password'database:process.env.DB_NAME,// e.g. 'my-database'},// ... Specify additional properties here....config,};// Establish a connection to the database.returnKnex(dbConfig);};

Use Secret Manager

Google recommends that you useSecret Manager to store sensitive information such as SQL credentials. You canpass secrets as environment variables or mount as a volume with Cloud Run.

Aftercreating a secret in Secret Manager, update an existing service, with the following command:

Command line

gcloudrunservicesupdateSERVICE_NAME\--add-cloudsql-instances=INSTANCE_CONNECTION_NAME--update-env-vars=INSTANCE_CONNECTION_NAME=INSTANCE_CONNECTION_NAME_SECRET\--update-secrets=DB_USER=DB_USER_SECRET:latest\--update-secrets=DB_PASS=DB_PASS_SECRET:latest\--update-secrets=DB_NAME=DB_NAME_SECRET:latest

Terraform

The following creates secret resources to securely hold the database user, password, and name values usinggoogle_secret_manager_secret andgoogle_secret_manager_secret_version. Note that you must update the project compute service account to have access to each secret.

# Create dbuser secretresource"google_secret_manager_secret""dbuser"{secret_id="dbusersecret"replication{auto{}}depends_on=[google_project_service.secretmanager_api]}# Attaches secret data for dbuser secretresource"google_secret_manager_secret_version""dbuser_data"{secret=google_secret_manager_secret.dbuser.idsecret_data="secret-data" # Stores secret as a plain txt in state}# Update service account for dbuser secretresource"google_secret_manager_secret_iam_member""secretaccess_compute_dbuser"{secret_id=google_secret_manager_secret.dbuser.idrole="roles/secretmanager.secretAccessor"member="serviceAccount:${data.google_project.project.number}-compute@developer.gserviceaccount.com" # Project's compute service account}

# Create dbpass secretresource"google_secret_manager_secret""dbpass"{secret_id="dbpasssecret"replication{auto{}}depends_on=[google_project_service.secretmanager_api]}# Attaches secret data for dbpass secretresource"google_secret_manager_secret_version""dbpass_data"{secret=google_secret_manager_secret.dbpass.idsecret_data="secret-data" # Stores secret as a plain txt in state}# Update service account for dbpass secretresource"google_secret_manager_secret_iam_member""secretaccess_compute_dbpass"{secret_id=google_secret_manager_secret.dbpass.idrole="roles/secretmanager.secretAccessor"member="serviceAccount:${data.google_project.project.number}-compute@developer.gserviceaccount.com" # Project's compute service account}

# Create dbname secretresource"google_secret_manager_secret""dbname"{secret_id="dbnamesecret"replication{auto{}}depends_on=[google_project_service.secretmanager_api]}# Attaches secret data for dbname secretresource"google_secret_manager_secret_version""dbname_data"{secret=google_secret_manager_secret.dbname.idsecret_data="secret-data" # Stores secret as a plain txt in state}# Update service account for dbname secretresource"google_secret_manager_secret_iam_member""secretaccess_compute_dbname"{secret_id=google_secret_manager_secret.dbname.idrole="roles/secretmanager.secretAccessor"member="serviceAccount:${data.google_project.project.number}-compute@developer.gserviceaccount.com" # Project's compute service account}

Update the main Cloud Run resource to include the new secrets.

resource"google_cloud_run_v2_service""default"{name="cloudrun-service"location="us-central1"deletion_protection=false # set to "true" in productiontemplate{containers{image="us-docker.pkg.dev/cloudrun/container/hello:latest" # Image to deploy      # Sets a environment variable for instance connection nameenv{name="INSTANCE_CONNECTION_NAME"value=google_sql_database_instance.default.connection_name}      # Sets a secret environment variable for database user secretenv{name="DB_USER"value_source{secret_key_ref{secret=google_secret_manager_secret.dbuser.secret_id # secret nameversion="latest"                                      # secret version number or 'latest'}}}      # Sets a secret environment variable for database password secretenv{name="DB_PASS"value_source{secret_key_ref{secret=google_secret_manager_secret.dbpass.secret_id # secret nameversion="latest"                                      # secret version number or 'latest'}}}      # Sets a secret environment variable for database name secretenv{name="DB_NAME"value_source{secret_key_ref{secret=google_secret_manager_secret.dbname.secret_id # secret nameversion="latest"                                      # secret version number or 'latest'}}}volume_mounts{name="cloudsql"mount_path="/cloudsql"}}volumes{name="cloudsql"cloud_sql_instance{instances=[google_sql_database_instance.default.connection_name]}}}client="terraform"depends_on=[google_project_service.secretmanager_api,google_project_service.cloudrun_api,google_project_service.sqladmin_api]}

Apply the changes by enteringterraform apply.

The example command uses the secret version,latest; however, Google recommendspinning the secret to a specific version,SECRET_NAME:v1.

Private IP

For private IP paths, your application connects directly to yourinstance through a VPC network.This method uses TCP to connect directly to the Cloud SQLinstance without using the Cloud SQL Auth Proxy.

Connect with TCP

Connect using the private IP address of your Cloud SQL instance as the host and port5432.

Python

To see this snippet in the context of a web application, viewthe README on GitHub.

importosimportsslimportsqlalchemydefconnect_tcp_socket()->sqlalchemy.engine.base.Engine:"""Initializes a TCP connection pool for a Cloud SQL instance of Postgres."""# Note: Saving credentials in environment variables is convenient, but not# secure - consider a more secure solution such as# Cloud Secret Manager (https://cloud.google.com/secret-manager) to help# keep secrets safe.db_host=os.environ["INSTANCE_HOST"]# e.g. '127.0.0.1' ('172.17.0.1' if deployed to GAE Flex)db_user=os.environ["DB_USER"]# e.g. 'my-db-user'db_pass=os.environ["DB_PASS"]# e.g. 'my-db-password'db_name=os.environ["DB_NAME"]# e.g. 'my-database'db_port=os.environ["DB_PORT"]# e.g. 5432pool=sqlalchemy.create_engine(# Equivalent URL:# postgresql+pg8000://<db_user>:<db_pass>@<db_host>:<db_port>/<db_name>sqlalchemy.engine.url.URL.create(drivername="postgresql+pg8000",username=db_user,password=db_pass,host=db_host,port=db_port,database=db_name,),# ...)returnpool

Java

To see this snippet in the context of a web application, viewthe README on GitHub.

Note:

importcom.zaxxer.hikari.HikariConfig;importcom.zaxxer.hikari.HikariDataSource;importjavax.sql.DataSource;publicclassTcpConnectionPoolFactoryextendsConnectionPoolFactory{// Note: Saving credentials in environment variables is convenient, but not// secure - consider a more secure solution such as// Cloud Secret Manager (https://cloud.google.com/secret-manager) to help// keep secrets safe.privatestaticfinalStringDB_USER=System.getenv("DB_USER");privatestaticfinalStringDB_PASS=System.getenv("DB_PASS");privatestaticfinalStringDB_NAME=System.getenv("DB_NAME");privatestaticfinalStringINSTANCE_HOST=System.getenv("INSTANCE_HOST");privatestaticfinalStringDB_PORT=System.getenv("DB_PORT");publicstaticDataSourcecreateConnectionPool(){// The configuration object specifies behaviors for the connection pool.HikariConfigconfig=newHikariConfig();// The following URL is equivalent to setting the config options below:// jdbc:postgresql://<INSTANCE_HOST>:<DB_PORT>/<DB_NAME>?user=<DB_USER>&password=<DB_PASS>// See the link below for more info on building a JDBC URL for the Cloud SQL JDBC Socket Factory// https://github.com/GoogleCloudPlatform/cloud-sql-jdbc-socket-factory#creating-the-jdbc-url// Configure which instance and what database user to connect with.config.setJdbcUrl(String.format("jdbc:postgresql://%s:%s/%s",INSTANCE_HOST,DB_PORT,DB_NAME));config.setUsername(DB_USER);// e.g. "root", "postgres"config.setPassword(DB_PASS);// e.g. "my-password"// ... Specify additional connection properties here.// ...// Initialize the connection pool using the configuration object.returnnewHikariDataSource(config);}}

Node.js

To see this snippet in the context of a web application, viewthe README on GitHub.

constKnex=require('knex');constfs=require('fs');// createTcpPool initializes a TCP connection pool for a Cloud SQL// instance of Postgres.constcreateTcpPool=asyncconfig=>{// Note: Saving credentials in environment variables is convenient, but not// secure - consider a more secure solution such as// Cloud Secret Manager (https://cloud.google.com/secret-manager) to help// keep secrets safe.constdbConfig={client:'pg',connection:{host:process.env.INSTANCE_HOST,// e.g. '127.0.0.1'port:process.env.DB_PORT,// e.g. '5432'user:process.env.DB_USER,// e.g. 'my-user'password:process.env.DB_PASS,// e.g. 'my-user-password'database:process.env.DB_NAME,// e.g. 'my-database'},// ... Specify additional properties here....config,};// Establish a connection to the database.returnKnex(dbConfig);};

Go

To see this snippet in the context of a web application, viewthe README on GitHub.

packagecloudsqlimport("database/sql""fmt""log""os"// Note: If connecting using the App Engine Flex Go runtime, use// "github.com/jackc/pgx/stdlib" instead, since v5 requires// Go modules which are not supported by App Engine Flex._"github.com/jackc/pgx/v5/stdlib")// connectTCPSocket initializes a TCP connection pool for a Cloud SQL// instance of Postgres.funcconnectTCPSocket()(*sql.DB,error){mustGetenv:=func(kstring)string{v:=os.Getenv(k)ifv==""{log.Fatalf("Fatal Error in connect_tcp.go: %s environment variable not set.",k)}returnv}// Note: Saving credentials in environment variables is convenient, but not// secure - consider a more secure solution such as// Cloud Secret Manager (https://cloud.google.com/secret-manager) to help// keep secrets safe.var(dbUser=mustGetenv("DB_USER")// e.g. 'my-db-user'dbPwd=mustGetenv("DB_PASS")// e.g. 'my-db-password'dbTCPHost=mustGetenv("INSTANCE_HOST")// e.g. '127.0.0.1' ('172.17.0.1' if deployed to GAE Flex)dbPort=mustGetenv("DB_PORT")// e.g. '5432'dbName=mustGetenv("DB_NAME")// e.g. 'my-database')dbURI:=fmt.Sprintf("host=%s user=%s password=%s port=%s database=%s",dbTCPHost,dbUser,dbPwd,dbPort,dbName)// dbPool is the pool of database connections.dbPool,err:=sql.Open("pgx",dbURI)iferr!=nil{returnnil,fmt.Errorf("sql.Open: %w",err)}// ...returndbPool,nil}

C#

To see this snippet in the context of a web application, viewthe README on GitHub.

usingNpgsql;usingSystem;namespaceCloudSql{publicclassPostgreSqlTcp{publicstaticNpgsqlConnectionStringBuilderNewPostgreSqlTCPConnectionString(){// Equivalent connection string:// "Uid=<DB_USER>;Pwd=<DB_PASS>;Host=<INSTANCE_HOST>;Database=<DB_NAME>;"varconnectionString=newNpgsqlConnectionStringBuilder(){// Note: Saving credentials in environment variables is convenient, but not// secure - consider a more secure solution such as// Cloud Secret Manager (https://cloud.google.com/secret-manager) to help// keep secrets safe.Host=Environment.GetEnvironmentVariable("INSTANCE_HOST"),// e.g. '127.0.0.1'// Set Host to 'cloudsql' when deploying to App Engine Flexible environmentUsername=Environment.GetEnvironmentVariable("DB_USER"),// e.g. 'my-db-user'Password=Environment.GetEnvironmentVariable("DB_PASS"),// e.g. 'my-db-password'Database=Environment.GetEnvironmentVariable("DB_NAME"),// e.g. 'my-database'// The Cloud SQL proxy provides encryption between the proxy and instance.SslMode=SslMode.Disable,};connectionString.Pooling=true;// Specify additional properties here.returnconnectionString;}}}

Ruby

To see this snippet in the context of a web application, viewthe README on GitHub.

tcp:&tcpadapter:postgresql# Configure additional properties here.# Note: Saving credentials in environment variables is convenient, but not# secure - consider a more secure solution such as# Cloud Secret Manager (https://cloud.google.com/secret-manager) to help# keep secrets safe.username:<%= ENV["DB_USER"] %>  # e.g. "my-database-user"  password: <%=ENV["DB_PASS"]%># e.g. "my-database-password"database:<%= ENV.fetch("DB_NAME") { "vote_development" } %>  host: <%=ENV.fetch("INSTANCE_HOST"){"127.0.0.1"}%># '172.17.0.1' if deployed to GAE Flexport:<%=ENV.fetch("DB_PORT"){5432}%>

PHP

To see this snippet in the context of a web application, viewthe README on GitHub.

namespace Google\Cloud\Samples\CloudSQL\Postgres;use PDO;use PDOException;use RuntimeException;use TypeError;class DatabaseTcp{    public static function initTcpDatabaseConnection(): PDO    {        try {            // Note: Saving credentials in environment variables is convenient, but not            // secure - consider a more secure solution such as            // Cloud Secret Manager (https://cloud.google.com/secret-manager) to help            // keep secrets safe.            $username = getenv('DB_USER'); // e.g. 'your_db_user'            $password = getenv('DB_PASS'); // e.g. 'your_db_password'            $dbName = getenv('DB_NAME'); // e.g. 'your_db_name'            $instanceHost = getenv('INSTANCE_HOST'); // e.g. '127.0.0.1' ('172.17.0.1' for GAE Flex)            // Connect using TCP            $dsn = sprintf('pgsql:dbname=%s;host=%s', $dbName, $instanceHost);            // Connect to the database            $conn = new PDO(                $dsn,                $username,                $password,                # ...            );        } catch (TypeError $e) {            throw new RuntimeException(                sprintf(                    'Invalid or missing configuration! Make sure you have set ' .                        '$username, $password, $dbName, and $instanceHost (for TCP mode). ' .                        'The PHP error was %s',                    $e->getMessage()                ),                $e->getCode(),                $e            );        } catch (PDOException $e) {            throw new RuntimeException(                sprintf(                    'Could not connect to the Cloud SQL Database. Check that ' .                        'your username and password are correct, that the Cloud SQL ' .                        'proxy is running, and that the database exists and is ready ' .                        'for use. For more assistance, refer to %s. The PDO error was %s',                    'https://cloud.google.com/sql/docs/postgres/connect-external-app',                    $e->getMessage()                ),                $e->getCode(),                $e            );        }        return $conn;    }}

Best practices and other information

You can use theCloud SQL Auth Proxy when testingyour application locally. See thequickstart for using the Cloud SQL Auth Proxyfor detailed instructions.

You can also test using theCloud SQL Proxy via a docker container.

Connection Pools

Connections to underlying databases may be dropped, either by the databaseserver itself, or by the platform infrastructure. We recommend using a client library that supports connection pools that automatically reconnect broken client connections.For more detailed examples on how to use connection pools, see theManaging database connections page.

Connection Limits

Both the MySQL and PostgreSQL editions of Cloud SQL impose a maximum limit onconcurrent connections, and these limits may vary depending on the databaseengine chosen (see theCloud SQL Quotas and Limits page).

Cloud Run container instances are limited to 100 connections to aCloud SQL database.Each instance of a Cloud Run service or job can have100 connections to the database, and as this service or job scales, the total number ofconnections per deployment can grow.

You can limit the maximum number of connections used per instance by using aconnection pool. For more detailed examples on how to limit the number ofconnections, see the Managing database connections page.

API Quota Limits

Cloud Run provides a mechanism that connects using the Cloud SQL Auth Proxy, which uses theCloud SQL Admin API.API quota limits apply to the Cloud SQL Auth Proxy. The Cloud SQL Admin API quotaused is approximately two times the number of Cloud SQL instancesconfigured by the number of Cloud Run instances of a particularservice deployed at any one time.You cancap or increase the numberof Cloud Run instances to modify the expected API quotaconsumed.

What's next

Except as otherwise noted, the content of this page is licensed under theCreative Commons Attribution 4.0 License, and code samples are licensed under theApache 2.0 License. For details, see theGoogle Developers Site Policies. Java is a registered trademark of Oracle and/or its affiliates.

Last updated 2025-07-16 UTC.