Connect from Cloud Run functions

MySQL  |  PostgreSQL  |  SQL Server

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

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

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 functions is a lightweight compute solution for developers to create single-purpose, standalone functions that respond to Cloud events without the need to manage a server or runtime environment.

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 SQL Server 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 functions

The steps to configure Cloud Run functions depend on the type ofIP address that you assigned to your Cloud SQL instance.

Public IP (default)

Cloud Run functions supports connecting to Cloud SQL forSQL Server over public IP using theGo, Java and Python connectors.

To configure Cloud Run functions to enable connections to a Cloud SQLinstance:
  • Confirm that the instance created above has a public IP address. You can confirm this on theOverview page for the instance in theGoogle Cloud console. If you need to add a public IP address, seeConfigure public IP.
  • Get the instance'sINSTANCE_CONNECTION_NAME. This value is available:
    • On theOverview page for the instance, in theGoogle Cloud console, or
    • By running the following command:gcloud sql instances describe [INSTANCE_NAME]
  • Configure the service account for your function. If the authorizing service account belongs to a different project from the Cloud SQL instance, then you must enable the Cloud SQL Admin API, and add theCloud SQL ClientIAM role to both projects.
  • Confirm that the service account has this role so that the account can connect to Cloud SQL.
  • If you're using Cloud Run functions and not Cloud Run functions (1st gen), the following are required (also see Configure Cloud Run):
    1. Initially deploy your function.
      When you first begin creating a Cloud Run function in the Google Cloud console, the underlying Cloud Run service hasn't been created yet. You can't configure a Cloud SQL connection until that service is created (by deploying the Cloud Run function).
    2. In the Google Cloud console, in the upper right of theFunction details page, underPowered by Cloud Run, click the link to access the underlying Cloud Run service.
    3. On the Cloud RunService details page, select theEdit and deploy new revision tab.
    4. Follow thestandard steps (as in the case of any configuration change) for setting a new configuration for a Cloud SQL connection.
      This creates a new Cloud Run revision, and subsequent revisions automatically receive this Cloud SQL connection, unless you explicitly change it.

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.
A Serverless VPC Access connector uses private IP addresses tohandle communication to your VPC network.To connect directly with private IP addresses, you must do the following:
  1. Make sure that the Cloud SQL instance created previously has a private IP address. If you need to add one, seeConfigure private IP for instructions.
  2. Create a Serverless VPC Access connector in the same VPC network as your Cloud SQL instance. Note the following conditions:
    • Unless you're using Shared VPC, your connector must be in the same project and region as the resource that uses it, but it can send traffic to resources in different regions.
    • Serverless VPC Access supports communication to VPC networks connected usingCloud VPN andVPC Network Peering.
    • Serverless VPC Access doesn't supportlegacy networks.
  3. Configure Cloud Run functions to use the connector.
  4. Connect using your instance's private IP address and port1433.

Connect to Cloud SQL

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

Public IP (default)

For public IP paths, Cloud Run functions provides encryption and connects using the Cloud SQL connectors.

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,IPTypesimportpytdsimportsqlalchemydefconnect_with_connector()->sqlalchemy.engine.base.Engine:"""    Initializes a connection pool for a Cloud SQL instance of SQL Server.    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.get("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(ip_type=ip_type,refresh_strategy="LAZY")connect_args={}# If your SQL Server instance requires SSL, you need to download the CA# certificate for your instance and include cafile={path to downloaded# certificate} and validate_host=False. This is a workaround for a known issue.ifos.environ.get("DB_ROOT_CERT"):# e.g. '/path/to/my/server-ca.pem'connect_args={"cafile":os.environ["DB_ROOT_CERT"],"validate_host":False,}defgetconn()->pytds.Connection:conn=connector.connect(instance_connection_name,"pytds",user=db_user,password=db_pass,db=db_name,**connect_args)returnconnpool=sqlalchemy.create_engine("mssql+pytds://",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");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 is equivalent to setting the config options below:// jdbc:sqlserver://;user=<DB_USER>;password=<DB_PASS>;databaseName=<DB_NAME>;// socketFactoryClass=com.google.cloud.sql.sqlserver.SocketFactory;// socketFactoryConstructorArg=<INSTANCE_CONNECTION_NAME>// 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.setDataSourceClassName("com.microsoft.sqlserver.jdbc.SQLServerDataSource");config.setUsername(DB_USER);// e.g. "root", "sqlserver"config.setPassword(DB_PASS);// e.g. "my-password"config.addDataSourceProperty("databaseName",DB_NAME);config.addDataSourceProperty("socketFactoryClass","com.google.cloud.sql.sqlserver.SocketFactory");config.addDataSourceProperty("socketFactoryConstructorArg",INSTANCE_CONNECTION_NAME);// The Java Connector provides SSL encryption, so it should be disabled// at the driver level.config.addDataSourceProperty("encrypt","false");// 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"mssql"github.com/denisenkom/go-mssqldb")typecsqlDialerstruct{dialer*cloudsqlconn.DialerconnNamestringusePrivatebool}// DialContext adheres to the mssql.Dialer interface.func(c*csqlDialer)DialContext(ctxcontext.Context,network,addrstring)(net.Conn,error){varopts[]cloudsqlconn.DialOptionifc.usePrivate{opts=append(opts,cloudsqlconn.WithPrivateIP())}returnc.dialer.Dial(ctx,c.connName,opts...)}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 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"))dbURI:=fmt.Sprintf("user id=%s;password=%s;database=%s;",dbUser,dbPwd,dbName)c,err:=mssql.NewConnector(dbURI)iferr!=nil{returnnil,fmt.Errorf("mssql.NewConnector: %w",err)}// 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.dialer,err:=cloudsqlconn.NewDialer(context.Background(),cloudsqlconn.WithLazyRefresh())iferr!=nil{returnnil,fmt.Errorf("cloudsqlconn.NewDailer: %w",err)}c.Dialer=&csqlDialer{dialer:dialer,connName:instanceConnectionName,usePrivate:usePrivate!="",}dbPool:=sql.OpenDB(c)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.

const{Connection}=require('tedious');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 a TCP connection// to a Cloud SQL instance of SQL Server.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.getTediousOptions({instanceConnectionName:process.env.INSTANCE_CONNECTION_NAME,ipType:getIpType(),});constdbConfig={// Please note that the `server` property here is not used and is only// defined due to a bug in the tedious driver// (ref: https://github.com/tediousjs/tedious/issues/1541)// With that in mind, do not try to change this value since it will have no// impact in how the connector works, this sample will be updated to remove// this property declaration as soon as the tedious driver bug is fixedserver:'0.0.0.0',// e.g. '127.0.0.1'authentication:{type:'default',options:{userName:process.env.DB_USER,// e.g. 'my-db-user'password:process.env.DB_PASS,// e.g. 'my-db-password'},},options:{...clientOpts,// Please note that the `port` property here is not used and is only// defined due to a bug in the tedious driver// (ref: https://github.com/tediousjs/tedious/issues/1541)// With that in mind, do not try to change this value since it will have// no impact in how the connector works, this sample will be updated to// remove this property declaration as soon as the tedious driver bug is// fixedport:9999,database:process.env.DB_NAME,// e.g. 'my-database'useColumnNames:true,},// ... Specify additional properties here....config,};// Establish a connection to the database.returnnewConnection(dbConfig);};

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 port1433.

Python

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

importosimportsqlalchemydefconnect_tcp_socket()->sqlalchemy.engine.base.Engine:"""Initializes a TCP connection pool for a Cloud SQL instance of SQL Server."""# 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. 1433pool=sqlalchemy.create_engine(# Equivalent URL:# mssql+pytds://<db_user>:<db_pass>@<db_host>:<db_port>/<db_name>sqlalchemy.engine.url.URL.create(drivername="mssql+pytds",username=db_user,password=db_pass,database=db_name,host=db_host,port=db_port,),# ...)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();// Configure which instance and what database user to connect with.config.setJdbcUrl(String.format("jdbc:sqlserver://%s:%s;databaseName=%s",INSTANCE_HOST,DB_PORT,DB_NAME));config.setUsername(DB_USER);// e.g. "root", "sqlserver"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.

constmssql=require('mssql');// createTcpPool initializes a TCP connection pool for a Cloud SQL// instance of SQL Server.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={server:process.env.INSTANCE_HOST,// e.g. '127.0.0.1'port:parseInt(process.env.DB_PORT),// e.g. 1433user:process.env.DB_USER,// e.g. 'my-db-user'password:process.env.DB_PASS,// e.g. 'my-db-password'database:process.env.DB_NAME,// e.g. 'my-database'options:{trustServerCertificate:true,},// ... Specify additional properties here....config,};// Establish a connection to the database.returnmssql.connect(dbConfig);};

Go

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

packagecloudsqlimport("database/sql""fmt""log""os""strings"_"github.com/denisenkom/go-mssqldb")// connectTCPSocket initializes a TCP connection pool for a Cloud SQL// instance of SQL Server.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.\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'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. '1433'dbName=mustGetenv("DB_NAME")// e.g. 'my-database')dbURI:=fmt.Sprintf("server=%s;user id=%s;password=%s;port=%s;database=%s;",dbTCPHost,dbUser,dbPwd,dbPort,dbName)// dbPool is the pool of database connections.dbPool,err:=sql.Open("sqlserver",dbURI)iferr!=nil{returnnil,fmt.Errorf("sql.Open: %w",err)}// ...returndbPool,nil}

PHP

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

namespace Google\Cloud\Samples\CloudSQL\SQLServer;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(                'sqlsrv:server=%s;Database=%s',                $instanceHost,                $dbName            );            // 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/sqlserver/connect-external-app',                    $e->getMessage()                ),                (int) $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.

Connection Pools

Connections to underlying databases may be dropped, either by the database server itself, or by the infrastructure underlying Cloud Run functions. We recommend using a client library that supports connection pools that automatically reconnect broken client connections.Additionally, we recommend using a globally scoped connection pool toincrease the likelihood that your function reuses the same connection forsubsequent invocations of the function, and closes the connection naturally whenthe instance is evicted (auto-scaled down).For more detailed examples on how to use connection pools, seeManaging database connections.

Connection Limits

Cloud SQL imposes a maximum limit on concurrent connections, and these limitsmay vary depending on the database engine chosen (seeCloud SQL Quotas and Limits).It's recommended to use a connection with Cloud Run functions, but it is importantto set the maximum number of connections to 1.

Note: Cloud Run functions limits concurrent executions to one per instance. You never have a situation where a single function instance is processing two requests at the same time. In most situations, only a single database connection is needed.

Where possible, you should take care to only initialize a connection pool for functions that need access to your database. Some connection pools will create connections preemptively, which can consume excess resources and count towards your connection limits. For this reason, it's recommended to use Lazy Initialization to delay the creation of a connection pool until needed, and only include the connection pool in functions where it's used.

For more detailed examples on how to limit the number of connections, seeManaging database connections.

API Quota Limits

Cloud Run functions provides a mechanism that connects using the Cloud SQL Auth Proxy,which uses the Cloud 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 times the total number of functions deployed. You canset thenumber of max concurrent invocations to modify the expected API quotaconsumed. Cloud Run functions also imposesrate limits on the numberof API calls allowed per 100 seconds.

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.