Optimize networking
The simplicity of Cloud Run functions lets you quickly develop code and run it in a serverless environment. At moderate scale, the cost of running functions is low, and optimizing your code might not seem like a high priority. As your deployment scales up, however, optimizing your code becomes increasingly important.
This document describes how to optimize networking for your functions. Some of the benefits of optimizing networking are as follows:
- Reduce CPU time spent in establishing new outbound connections at each function call.
- Reduce the likelihood of running out of connection or DNS quotas.
Maintaining Persistent Connections
This section gives examples of how to maintain persistent connections in a function. Failure to do so can result in quickly exhausting connection quotas.
The following scenarios are covered in this section:
- HTTP/S
- Google APIs
HTTP/S Requests
The optimized code snippet below shows how to maintain persistent connections instead of creating a new connection upon every function invocation:
Node.js
Python
Go
PHP
We recommend using the Guzzle PHP HTTP Framework to send HTTP requests, as it handles persistent connections automatically.
Accessing Google APIs
The example below uses Cloud Pub/Sub, but this approach also works for other client libraries—for example, Cloud Natural Language or Cloud Spanner. Note that performance improvements may depend on the current implementation of particular client libraries.
Creating a Pub/Sub client object results in one connection and two DNS queries per invocation. To avoid unnecessary connections and DNS queries, create the Pub/Sub client object in global scope as shown in the sample below:
Node.js
Python
Go
Outbound connection resets
Connection streams from your function to both VPC and internet can be occasionally terminated and replaced when underlying infrastructure is restarted or updated. If your application reuses long-lived connections, we recommend that you configure your application to re-establish connections to avoid the reuse of a dead connection.
Load-testing Your Function
To measure how many connections your function performs on average, simply deploy it as a HTTP function and use a performance-testing framework to invoke it at certain QPS. One possible choice is Artillery, which you can invoke with a single line:
$ artillery quick -d 300 -r 30 URL
This command fetches the given URL at 30 QPS for 300 seconds.
After performing the test, check the usage of your connection quota on the Cloud Run functions API quota page in Cloud Console. If the usage is consistently around 30 (or its multiple), you are establishing one (or several) connections in every invocation. After you optimize your code, you should see a few (10-30) connections occur only at the beginning of the test.
You can also compare the CPU cost before and after the optimization on the CPU quota plot on the same page.