Skip to main content

Best practices for functions

Exam guide§2.1

These are the practices Google recommends for writing, running, and operating Cloud Run functions: write functions that survive being retried, report their own failures, start fast, reuse network state, retry only transient errors, and run with least privilege. This page covers implementing functions, reporting errors, performance and networking, retrying on failure, and IAM.

Writing functions

IdempotencyFunctions should be idempotent sothey produce the same result whencalled multiple times.HTTP responseAn HTTP function must alwaysreturn an HTTP response.Background activitiesDo not have background activitiesrunning after your functioninvocation returns or completes.Temporary filesAlways delete temporary files ifcreated by your function.
Four rules for writing functions: make them idempotent, always return an HTTP response, leave no background work running after the invocation returns, and delete any temporary files you create.
GotchaMake functions idempotent

Write functions to be idempotent - the same result whether they run once or many times. Only an idempotent function is safe to retry after a partial failure, which is what makes automatic retries (below) usable at all.

GotchaAn HTTP function must always return a response

If an HTTP function never returns a response, it keeps executing until it hits the timeout - and you are billed for the entire time until then. Always send a response.

GotchaNo background work after the function returns

Once an invocation terminates, the CPU is not accessible and your code stops executing. Any work you left running in the background does not finish - and worse, a later invocation reusing the same environment can resume that stale work and corrupt the current one. Ensure every asynchronous operation finishes before you return.

GotchaDelete temporary files you create

The temporary directory is an in-memory file system. Files you write there consume your function's memory and can persist between invocations, so they accumulate and eventually cause an out-of-memory error and a cold start. Explicitly delete any files your code creates.

Implementing functions

Local developmentand testingReduce the timethat it takes toiterativelydevelop and testyour function codewith localdevelopment.Data localityRun your functionson other platformscompatible withCloud Runfunctionsopen-sourceabstractionlayers.Error ReportingTo avoid coldstarts in futurefunctioninvocations, donot throw uncaughtexceptions in yourfunction code.Function exitTo exit fromfunctions, uselanguage-specificsyntax to return,or send an HTTPresponse.
Four things to get right when implementing functions: develop and test locally, respect data-locality restrictions, report errors, and exit cleanly instead of throwing uncaught exceptions.
FactsDevelop and test locally
  • To test a deployed function you must wait for the deploy to finish and for log entries to appear - slow.
  • Developing and testing the function locally in your own environment makes iteration significantly faster.
  • For data-locality rules that keep traffic inside a geographic or network boundary your functions cannot reach, run them on another platform that honors those restrictions and is compatible with the open-source abstraction layers Cloud Run functions uses.
GotchaDo not throw uncaught exceptions or exit manually

Uncaught exceptions force a cold start on the next invocation, so always handle runtime errors. Do not call process.exit() (Node.js) or sys.exit() (Python) either - manual exits cause unexpected behavior. Instead return implicitly or explicitly from event-driven functions, and return an HTTP response from HTTP functions.

Reporting errors

Function runtimeCloud LoggingError Reporting
A function reports failures to two places: log debug messages to Cloud Logging (stdout/stderr appear automatically), and send runtime exceptions to Error Reporting to aggregate, alert on, and troubleshoot them.

Handle runtime errors and exceptions in your code, then report them: log debug messages to Cloud Logging and send runtime exceptions to Error Reporting.

FactsWhere a function reports failures
  • Cloud Logging - runtime logging is on by default; anything written to stdout or stderr appears automatically in the Google Cloud console.
  • Error Reporting - runtime exceptions emitted from your function are sent here, where you can aggregate and view them, be notified when they occur, and troubleshoot.
  • HTTP functions should report the error and respond with an appropriate HTTP status code.
  • Event-driven functions should report and return an error message when an exception occurs.

Improving performance

A cold start creates and initializes a function's execution environment, loading every dependency the function imports and adding to invocation latency. Most performance practices are about paying that cost less often, or paying less each time.

FactsReduce cold-start cost
  • Remove unused dependencies - don't load what the function never uses; this cuts both invocation latency and deploy time.
  • Reuse global-scope state - the previous invocation's environment is often recycled, so a variable declared in global scope keeps its value for later invocations without recomputing. Cache expensive objects (API clients, network connections) there.
  • Initialize global variables lazily - global init always adds cold-start latency. If a global is not used on every code path, create it on demand instead of eagerly.
  • Set a minimum number of instances - keeping instances warm and ready to serve reduces cold starts and improves overall latency.

Optimizing networking

CODE (function)URLHTTPSPub/SubVPC
Cache expensive network state in global scope. Reuse persistent HTTP connections and Google service client objects, and route traffic to internal resources through a Serverless VPC Access connector.
FactsCache network state, keep internal traffic private
  • Create persistent HTTP connections to URLs your function calls, and cache them in global scope - this avoids the CPU cost of a new connection per invocation and reduces the chance of exhausting your connection quota.
  • Create Google service client objects in global scope too, to avoid unnecessary connections and DNS queries when calling Google APIs.
  • Use Serverless VPC Access connectors to reach internal resources over internal DNS and internal IP addresses, so traffic to your VPC is never exposed to the internet.

For configuring a connector, restricting it with firewall rules, and Shared VPC, see Serverless VPC Access.

Retrying functions on failure

FactsHow retries work
  • Event-driven functions only - automatic retry is not available for HTTP functions.
  • Disabled by default. Enable it with the --retry flag on gcloud functions deploy, or the Retry on failure option in the console. To disable, redeploy without --retry (or clear the option).
  • With retry on, the event is retried repeatedly for up to seven days by default, until the function succeeds or the retry period elapses.
  • On failure without retry, the function stops executing and the event is discarded.

Common reasons a function fails: an unhandled runtime exception (a bug); an unreachable service endpoint that times out; code that intentionally throws under some condition; or a Node.js function that returns a rejected promise or passes a non-null value to a callback.

GotchaRetries are for transient failures - fix bugs before enabling

Retries suit intermittent or transient failures (a connection that times out, an endpoint briefly unreachable) that are likely to succeed on a later try. Because a failing function is retried continuously for up to seven days, a bug retried this way just fails over and over - find and fix bugs through testing before enabling retries, and handle any exception that should not trigger a retry.

GotchaAdd an end condition to avoid infinite retry loops

When a failure is persistent, prevent an infinite retry loop by putting an end condition in your code before the processing runs. A common approach: compare the event's timestamp and discard events older than a chosen age.

IAM considerations

FactsLeast privilege for functions
  • Limit access to your functions to the minimum number of users and service accounts, with the minimum set of permissions needed to develop and use them.
  • Restrict function-to-function calls - when functions connect to each other, ensure each can call only the specific subset it needs (a login function may reach a user-profiles function but not a search function).
  • Give each function a dedicated identity - unless you specify one, a function runs as the default service account. For production, assign a user-managed service account so you can grant a minimal, function-specific set of permissions via IAM.