Prev Next

Cloud / Google Cloud Run Functions Interview questions

Last updated

1. What is Cloud Run functions? 2. What are the types of triggers supported by Cloud Run functions? 3. What programming languages does Cloud Run functions support? 4. What is the Functions Framework? 5. What is an HTTP function in Cloud Run functions? 6. What is an event-driven function in Cloud Run functions? 7. What is Eventarc in Cloud Run functions? 8. What is a cold start in Cloud Run functions? 9. What are minimum instances in Cloud Run functions? 10. What are maximum instances in Cloud Run functions? 11. What is the default timeout of a Cloud Run function? 12. What is concurrency in Cloud Run functions? 13. How do you deploy a Cloud Run function using gcloud? 14. How do you create an HTTP function in Python? 15. How do you trigger a Cloud Run function from Pub/Sub? 16. How do you trigger a Cloud Run function from Cloud Storage? 17. What is the difference between Cloud Run functions 1st gen and 2nd gen? 18. What is the difference between Cloud Run functions and Cloud Run? 19. What is the difference between Cloud Run functions and Cloud Run jobs? 20. What is the difference between Cloud Run functions and App Engine? 21. How do you secure an HTTP Cloud Run function? 22. How do you pass secrets to a Cloud Run function? 23. How do you set environment variables in a Cloud Run function? 24. How do you connect a Cloud Run function to a VPC network? 25. How do you view logs for a Cloud Run function? 26. How does Cloud Run functions scale? 27. Why do functions need to be idempotent? 28. How do retries work for event-driven Cloud Run functions? 29. When should you use Cloud Run functions instead of Cloud Run? 30. How does an HTTP function handle CORS? 31. How do you test a Cloud Run function locally? 32. What is a service account in Cloud Run functions? 33. How do you configure memory and CPU for a Cloud Run function? 34. What is the structure of a CloudEvent? 35. What is the purpose of the --entry-point flag? 36. Explain the execution flow of an event-driven Cloud Run function? 37. How can you reduce cold start latency in Cloud Run functions? 38. What happens when a Cloud Run function exceeds its timeout? 39. How do you troubleshoot an out-of-memory error in a function? 40. Why should you initialize clients in global scope? 41. Why should you avoid background work after returning a response? 42. How do you handle long-running work triggered by an event? 43. How do you roll back a bad Cloud Run function deployment? 44. How do you deploy Cloud Run functions with Terraform? 45. How do you handle poison messages in a Pub/Sub-triggered function? 46. How does service-to-service authentication work between Cloud Run functions? 47. How does pricing work for Cloud Run functions? 48. How do you set up CI/CD for Cloud Run functions? 49. How do you monitor and alert on a Cloud Run function? 50. When would you choose Workflows over chaining functions directly?

1. What is Cloud Run functions?

Cloud Run functions is Google Cloud's serverless functions-as-a-service offering. You write a single-purpose function, deploy it, and Google runs it on demand without you managing servers, operating systems, or scaling.

It is the current name for what used to be Cloud Functions (2nd gen). Under the hood each function is deployed as a Cloud Run service, built with Cloud Build and triggered either by an HTTP request or by an event routed through Eventarc.

You pay only while the function is handling requests (plus any minimum instances you configure), and it scales to zero when idle.

Take quiz
Cloud Run functions was previously known as:
App Engine Flexible
Cloud Dataflow templates
Cloud Functions (2nd gen)
Under the hood, a Cloud Run function is deployed as:
a Compute Engine managed instance group
a GKE Autopilot cluster
a Dataproc job
a Cloud Run service

2. What are the types of triggers supported by Cloud Run functions?

Cloud Run functions supports two trigger types: HTTP triggers and event-driven triggers.

An HTTP function responds to HTTP(S) requests and gets a run.app URL automatically. It suits webhooks, REST endpoints, and callbacks from Stripe, GitHub, or Slack.

An event-driven function (also called a CloudEvent function) reacts to something happening inside your Google Cloud project, such as a file landing in Cloud Storage or a message arriving on Pub/Sub. All event-driven functions get their events through Eventarc.

HTTP trigger Event-driven trigger
Invoked by an HTTP request Invoked by an Eventarc event
Function signature takes request and response Function signature takes a CloudEvent
Caller waits for the response Caller does not wait for a result

Take quiz
Which service delivers events to event-driven Cloud Run functions?
Eventarc
Cloud Scheduler
Cloud Armor
Cloud Deploy
A Stripe webhook handler is best built with which trigger type?
Cloud Storage trigger
Firestore trigger
HTTP trigger
Audit log trigger

3. What programming languages does Cloud Run functions support?

Cloud Run functions offers Google-managed runtimes for Node.js, Python, Go, Java, Ruby, PHP, and .NET.

Each runtime bundles an operating system image, language support, and the Functions Framework library that actually invokes your code. Runtimes are identified by a language-and-version ID such as python312 or nodejs22, which you pass at deploy time.

Every runtime follows a support schedule, so deprecated versions eventually stop accepting new deployments. Check the current runtime list before picking a version.

Pick the language your team already knows well. No single runtime is the fastest choice for every workload.

Take quiz
A runtime ID such as python312 is passed to Cloud Run functions at:
invoke time only
billing export time
deploy time
Which library inside each runtime actually invokes your function code?
Eventarc SDK
Functions Framework
Cloud Trace agent
Cloud Build helper

4. What is the Functions Framework?

The Functions Framework is an open-source library, available per language, that wraps your function in a small HTTP server and routes incoming requests or CloudEvents to it.

It is what the managed runtimes use to call your code. Because it is open source, you can run the same function on your laptop, in Docker, or on another platform, which makes local testing simple.

pip install functions-framework
functions-framework --target=hello_http --port=8080

The --target flag names the function to expose.

Because it runs the same code path as production, it catches routing and signature mistakes before you deploy.

Take quiz
What does the Functions Framework mainly let you do?
Provision Eventarc triggers automatically
Replace IAM policies
Encrypt Pub/Sub topics
Run and test your function locally
In functions-framework --target=hello_http, the target is:
the Google Cloud region
the name of the function to expose
the Pub/Sub topic
the service account

5. What is an HTTP function in Cloud Run functions?

An HTTP function is a function that runs in response to an HTTP(S) request. Deploying one automatically provisions a run.app HTTPS endpoint, so no load balancer or routing config is needed.

It receives the request object and must send a response. The caller stays connected until the function returns, so the function has to finish within the configured timeout.

import functions_framework

@functions_framework.http
def hello_http(request):
    name = request.args.get("name", "world")
    return f"Hello {name}!", 200

An unhandled exception in an HTTP function returns a 500 to the caller, so wrap risky calls and return clear status codes for bad input.

Take quiz
What does deploying an HTTP function automatically give you?
A dedicated VPC
A Pub/Sub topic
An HTTPS endpoint URL
A BigQuery dataset
An HTTP function must always:
return a response to the caller
write to Cloud Storage
publish to Pub/Sub
call another function

6. What is an event-driven function in Cloud Run functions?

An event-driven function runs in response to an event from a Google Cloud service, such as an object finalized in Cloud Storage, a Pub/Sub message, or a Firestore write. The event is delivered as a CloudEvent through Eventarc.

Nobody is waiting on a response, so the function does its work and exits. Because delivery is at-least-once, the same event can arrive more than once, which is why these functions should be idempotent.

@functions_framework.cloud_event
def on_upload(cloud_event):
    data = cloud_event.data
    print(f"File: {data['name']} in {data['bucket']}")

Take quiz
Event-driven functions receive their input as a:
raw TCP packet
CloudEvent
SQL result set
gRPC stream only
Why should event-driven functions be idempotent?
They run only on weekends
They cannot read environment variables
They use a fixed IP
Events can be delivered more than once

7. What is Eventarc in Cloud Run functions?

Eventarc is Google Cloud's event routing service and Google's implementation of the CloudEvents spec. For Cloud Run functions it is the delivery layer that connects an event source to your function.

It supports events directly from many Google services and, through Cloud Audit Logs, from 90+ sources. It also handles Pub/Sub events and custom events from your own apps.

When you create an event-driven function, you define a trigger with event filters, for example the event type google.cloud.storage.object.v1.finalized and a bucket name. Eventarc then calls the function whenever a match occurs.

Take quiz
Eventarc implements which open specification?
CloudEvents
OpenAPI
GraphQL
SAML
An Eventarc trigger uses what to decide which events to forward?
Billing labels
Load balancer rules
Event filters
DNS records

8. What is a cold start in Cloud Run functions?

A cold start is the extra latency incurred when a request arrives and no warm instance is available, so Google must create a new one. It includes starting the container, booting the runtime, and running your global initialization code.

Warm instances that are already running skip all of that, so repeat requests are noticeably faster.

Cold starts are most visible after idle periods or sudden traffic spikes. Heavy imports, large dependencies, and slow global setup make them worse.

You can see it in Cloud Trace by comparing the first request after an idle period with the ones that follow.

Take quiz
A cold start happens when:
no warm instance is available for a request
the function is deleted
the IAM policy changes
a secret is rotated
Which factor makes cold starts slower?
A shorter function name
Using fewer environment variables
Heavy dependencies loaded at startup
Deploying in a labeled project

9. What are minimum instances in Cloud Run functions?

Minimum instances is a setting that keeps a chosen number of instances running even when there is no traffic. The default is 0, which allows true scale-to-zero.

Raising it to 1 or more removes most cold starts for the first requests, since a warm instance is always ready. The trade-off is cost, because you pay for those idle instances.

gcloud functions deploy my-func --gen2 --min-instances=1

A good rule is to use it on latency-sensitive endpoints such as a user-facing API, and leave background event handlers at zero, where a short delay rarely matters.

Take quiz
What is the default minimum instances value?
1
10
100
0
The main downside of raising minimum instances is:
the function loses HTTPS
you pay for idle warm instances
events stop being delivered
concurrency is forced to 1

10. What are maximum instances in Cloud Run functions?

Maximum instances caps how many instances a function can scale out to. It protects downstream systems, such as a database with a connection limit, from being overwhelmed by a traffic burst.

For 2nd gen HTTP functions the default limit is 100 and it can be raised to 1,000. Once the cap is reached, extra requests are queued briefly and may then be rejected.

gcloud functions deploy my-func --gen2 --max-instances=20

Size it from your slowest dependency. For example, a database that allows 100 connections supports far fewer than 100 instances if each opens several.

Take quiz
A common reason to set maximum instances is to:
lower the function's cold start
enable HTTPS
protect a downstream database from overload
change the runtime version
The default max instances limit for 2nd gen HTTP functions is:
100
3
3000
unlimited

11. What is the default timeout of a Cloud Run function?

The default request timeout is 60 seconds. You can raise or lower it at deploy time using the --timeout flag.

The ceiling depends on the trigger type: up to 60 minutes (3600 s) for HTTP functions and up to 9 minutes (540 s) for event-driven functions.

gcloud functions deploy my-func --gen2 --timeout=300s

When the timeout is hit, the caller receives an HTTP 504.

Pick a value with headroom over your slowest normal run, but not so large that a hung call ties up an instance for an hour. For event-driven functions remember the 9 minute ceiling, and prefer a shorter timeout so retries start sooner.

Take quiz
What is the default timeout for a Cloud Run function?
10 seconds
60 seconds
9 minutes
24 hours
Which flag changes the timeout at deploy time?
--ttl
--max-wait
--deadline-mode
--timeout

12. What is concurrency in Cloud Run functions?

Concurrency is the number of requests a single function instance can handle at the same time. Cloud Run functions (2nd gen) supports up to 1,000 concurrent requests per instance.

Higher concurrency means fewer instances are needed, fewer cold starts occur, and the bill drops. The catch is that your code must be safe for parallel execution, so shared mutable state needs care.

gcloud functions deploy my-func --gen2 --concurrency=80

Start with the default and tune using load tests. CPU-heavy work often prefers lower concurrency because parallel requests compete for the same cores, while I/O-bound handlers that mostly wait on APIs can use much higher values.

Take quiz
The maximum concurrency per instance in 2nd gen is:
1
1,000
10
10,000
Higher concurrency requires your code to be:
written only in Go
stateless across deployments only
deployed in two regions
safe for parallel execution

13. How do you deploy a Cloud Run function using gcloud?

Use gcloud functions deploy with a name, runtime, entry point, source location, and trigger. Run it from the folder containing your code.

gcloud functions deploy hello-http \
  --gen2 \
  --region=us-central1 \
  --runtime=python312 \
  --source=. \
  --entry-point=hello_http \
  --trigger-http \
  --allow-unauthenticated

Behind the scenes, Cloud Build packages the source into a container and deploys it as a Cloud Run service. Leave off --allow-unauthenticated if the endpoint should be private.

A deploy takes a minute or two because the build runs first. You can pass memory, environment variables, and the service account in the same command, so the whole configuration is reproducible from a script instead of console clicks.

Take quiz
Which flag tells gcloud which function in the source to run?
--entry-point
--target-sa
--ingress-name
--revision-tag
Which service builds the container during a gcloud deploy?
Cloud Deploy
Artifact Analysis
Cloud Build
Cloud Composer

14. How do you create an HTTP function in Python?

Install the Functions Framework, then decorate a function that accepts a Flask request object. In Python, the HTTP function receives a Flask request and returns anything Flask can turn into a response.

import functions_framework
from flask import jsonify

@functions_framework.http
def get_user(request):
    uid = request.args.get("id")
    if not uid:
        return jsonify(error="id required"), 400
    return jsonify(id=uid, active=True)

Put dependencies in requirements.txt beside main.py. The entry point defaults to the function name you point at.

For JSON bodies, use request.get_json(silent=True) so bad input returns None instead of raising, and validate fields before using them. Return an explicit status code so callers can tell client errors from server errors.

Take quiz
In a Python HTTP function, the request argument is a:
Django model
CloudEvent
Pub/Sub message
Flask request object
Where do Python dependencies for the function go?
package.json
requirements.txt
pom.xml
Gemfile

15. How do you trigger a Cloud Run function from Pub/Sub?

Deploy the function with a Pub/Sub topic trigger. The simplest way is the --trigger-topic flag, which wires the topic to your function.

gcloud functions deploy process-orders \
  --gen2 --runtime=nodejs22 --region=us-central1 \
  --source=. --entry-point=processOrder \
  --trigger-topic=orders

Every message published to orders becomes an event. The message payload is base64 encoded inside the CloudEvent, so decode it before use. A failing function can retry delivery if retries are enabled.

Message attributes arrive alongside the payload and are handy for routing. Delivery is at-least-once, so deduplicate on the message ID before doing anything that is not safe to repeat, such as sending an email.

Take quiz
Which flag wires a Pub/Sub topic to a function?
--topic-sink
--pubsub-bind
--trigger-topic
--listen-queue
The Pub/Sub message payload inside the event is:
base64 encoded
encrypted with CMEK always
gzipped JSON only
plain XML

16. How do you trigger a Cloud Run function from Cloud Storage?

Create an event-driven function with an Eventarc trigger filtered to a bucket and an event type. The usual one is google.cloud.storage.object.v1.finalized, which fires when a new object is fully written.

gcloud functions deploy on-upload \
  --gen2 --runtime=python312 --region=us-central1 \
  --source=. --entry-point=on_upload \
  --trigger-bucket=my-uploads

The bucket must be in the same location as the function. The event carries the bucket and object name, not the file content, so your code reads the object using the Storage client.

Large uploads can fire more than one event, so filter on object name prefixes when only certain files matter. Writing output back into the same bucket without such a filter can trigger the function again and create an infinite loop.

Take quiz
Which event type fires when a new object is fully written?
google.cloud.storage.bucket.v1.created
google.cloud.pubsub.topic.v1.published
google.cloud.storage.object.v1.finalized
google.cloud.run.job.v1.done
The Storage event payload contains:
the bucket and object name
the full file content
the user's password
the VPC route table

17. What is the difference between Cloud Run functions 1st gen and 2nd gen?

2nd gen is built on Cloud Run and Eventarc, while 1st gen is the original standalone runtime with limited triggers and tuning.

Feature 1st gen 2nd gen
Concurrency 1 request per instance Up to 1,000 per instance
Max timeout 9 minutes 60 min HTTP, 9 min event
Max resources 8 GiB / 2 vCPU 16 GiB / 4 vCPU
Event sources Limited set 90+ via Eventarc
Built on Legacy infrastructure Cloud Run

New projects should use 2nd gen, and 1st gen functions should be migrated when practical.

A few settings, such as concurrency above 1 and 60 minute HTTP timeouts, simply are not available in 1st gen. Migration usually means redeploying with 2nd gen settings and re-checking each trigger.

Take quiz
Which generation allows up to 1,000 concurrent requests per instance?
1st gen
2nd gen
Both equally
Neither
2nd gen functions are built on top of:
App Engine standard
Cloud Composer
Compute Engine only
Cloud Run and Eventarc

18. What is the difference between Cloud Run functions and Cloud Run?

Both run on the same platform, but they differ in what you hand over. With a function you give Google source code and a function name, and it builds the container for you. With Cloud Run you bring your own container image or build one with a buildpack or Dockerfile.

Aspect Cloud Run functions Cloud Run
Unit of deployment A single function A container (full app)
Packaging Source code, built for you Any container image
Routing One handler per function Many routes in one service
Best for Small event handlers APIs and full apps

Pick a function for a small single-purpose handler, and Cloud Run when you need a custom runtime or a multi-route service.

Take quiz
Which option lets you bring your own container image?
Cloud Run
Cloud Run functions only
Neither
Cloud Scheduler
Cloud Run functions is best suited to:
hosting a full multi-route API
running GPUs for training
small single-purpose handlers
hosting static sites

19. What is the difference between Cloud Run functions and Cloud Run jobs?

A function responds to a request or event and is expected to return quickly. A Cloud Run job runs a task to completion with no request, and can run for much longer.

Aspect Function Cloud Run job
Starts from HTTP request or event Manual run or schedule
Max runtime 60 min HTTP, 9 min event Up to 24 hours
Serves traffic Yes No
Typical use Webhook, file handler Batch, data migration

If an event-driven function keeps hitting the 9-minute limit, a common fix is to have it start a Cloud Run job instead.

Both can be started on a cron schedule from Cloud Scheduler.

Take quiz
Which option can run up to 24 hours?
Event-driven function
HTTP function
Cloud Scheduler
Cloud Run job
A function that exceeds 9 minutes on an event trigger could instead:
raise concurrency to 5000
start a Cloud Run job
disable Eventarc
use a smaller region

20. What is the difference between Cloud Run functions and App Engine?

App Engine hosts an entire web application with its own runtime, routing, and services. Cloud Run functions hosts one small function bound to a trigger.

App Engine fits long-lived web apps with several handlers and background services. A function fits a focused task such as resizing an uploaded image, reacting to a Pub/Sub message, or answering a webhook.

Functions also scale to zero by default and need no app.yaml. For new greenfield work, Google generally points to Cloud Run and Cloud Run functions over App Engine.

Functions also suit teams that want no infrastructure decisions, since the platform picks the build and serving details for you.

Take quiz
Which service is built around a single trigger-bound function?
App Engine standard
Compute Engine
Cloud SQL
Cloud Run functions
Cloud Run functions does not need which config file?
requirements.txt
app.yaml
package.json
go.mod

21. How do you secure an HTTP Cloud Run function?

By default a deployed function requires authentication. Only callers with the roles/run.invoker IAM role can call it, and they must send a Google-signed ID token in the Authorization header.

To open it publicly, deploy with --allow-unauthenticated, which grants invoker to allUsers. For private traffic, also restrict ingress to internal sources, and run the function as a least-privilege service account.

gcloud functions add-invoker-policy-binding my-func \
  --region=us-central1 \
  --member="serviceAccount:caller@my-proj.iam.gserviceaccount.com"

Never leave an internal function open just to make testing easier. Use gcloud auth print-identity-token to get a token for manual calls, and grant invoker only to the specific callers that need it, such as a Cloud Scheduler service account.

Take quiz
Which IAM role lets a caller invoke a function?
roles/viewer
roles/logging.viewer
roles/run.invoker
roles/iam.serviceAccountUser
Authenticated callers pass what in the Authorization header?
A Google-signed ID token
The project billing ID
A Cloud Storage signed URL
An SSH public key

22. How do you pass secrets to a Cloud Run function?

Store the value in Secret Manager and reference it at deploy time. Never hard-code secrets or keep them in plain environment variables in source control.

You can expose a secret as an environment variable or mount it as a file. The function's service account needs roles/secretmanager.secretAccessor on that secret.

gcloud functions deploy my-func --gen2 \
  --set-secrets 'DB_PASS=db-password:latest'

Using latest picks up rotations on the next instance start, while a pinned version stays fixed.

Secrets mounted as files are read when accessed, while env var secrets are resolved when the instance starts. A pinned version never changes until you redeploy with a new one.

Take quiz
Which service should hold an API key used by a function?
Cloud DNS
Secret Manager
Cloud CDN
Cloud Armor
The function's service account needs which role on the secret?
roles/owner
roles/run.invoker
roles/storage.admin
roles/secretmanager.secretAccessor

23. How do you set environment variables in a Cloud Run function?

Use --set-env-vars at deploy time, or --env-vars-file to load a YAML file. Variables are available to your code through the standard environment APIs.

gcloud functions deploy my-func --gen2 \
  --set-env-vars=ENV=prod,REGION=us-central1

import os
env = os.environ.get("ENV", "dev")

Use them for non-sensitive config such as feature flags and endpoints. Anything sensitive belongs in Secret Manager.

Variables are set per revision, so changing one means redeploying. Names like K_SERVICE and K_REVISION are set by the platform and should not be overwritten. Keep a clear naming convention, such as APP_ENV and DB_HOST, so the same code runs unchanged across dev, staging, and production.

Take quiz
Which flag sets environment variables at deploy time?
--set-env-vars
--put-config
--export-vars
--inject-env
Sensitive values should be stored in:
plain env vars in git
function logs
Secret Manager
the Pub/Sub message body

24. How do you connect a Cloud Run function to a VPC network?

Functions run outside your VPC by default, so they cannot reach private IPs such as a Cloud SQL private address or an internal service. To fix that, enable Direct VPC egress or attach a Serverless VPC Access connector.

Direct VPC egress is the newer, simpler option because it needs no connector instances. The connector approach still works and is common in older setups.

gcloud functions deploy my-func --gen2 \
  --vpc-connector=my-connector \
  --egress-settings=private-ranges-only

With private-ranges-only, only private traffic goes through the VPC and public calls leave directly.

Whichever option you use, the VPC needs firewall rules and routes that allow the traffic, otherwise connections will simply time out.

Take quiz
By default, a function can reach private VPC IPs:
No, it needs VPC egress configured
Yes, always
Only in us-central1
Only on Sundays
The egress setting private-ranges-only sends which traffic through the VPC?
All outbound traffic
Only DNS queries
Only traffic to private IP ranges
Only Pub/Sub traffic

25. How do you view logs for a Cloud Run function?

Anything your function writes to stdout or stderr is captured by Cloud Logging automatically. You can view it in the console or from the CLI.

gcloud functions logs read my-func --gen2 --region=us-central1 --limit=50

For structured logs, print JSON with a severity field so entries are filterable. Each log entry is linked to the request through a trace ID, which helps when following one call across services.

Avoid logging full request bodies or secrets, because logs are retained and widely readable. Use levels consistently so alerts can target ERROR entries, and add a request or user ID as a field so one failed call can be traced quickly.

Take quiz
Where do stdout and stderr from a function end up?
Cloud Storage only
BigQuery tables only
Firestore
Cloud Logging
Which JSON field makes a log entry filterable by level?
priority_code
severity
level_id
log_class

26. How does Cloud Run functions scale?

Scaling is automatic and driven by incoming load. When requests arrive and existing instances are busy, Cloud Run adds instances. When traffic drops, it removes them, down to zero unless minimum instances is set.

The number of instances needed depends on request rate, how long each request takes, and your concurrency setting. With concurrency 80, one instance can serve 80 simultaneous requests, so you need far fewer instances than with concurrency 1.

Scaling stops at max instances. Beyond that point, requests queue and may eventually fail.

Scale-out is not instant, so a sudden burst can still hit cold starts before enough instances are ready. Minimum instances smooth that out.

Take quiz
What mainly triggers new instances being added?
A scheduled cron entry
A new IAM binding
Incoming requests exceeding capacity
A log filter match
Raising concurrency usually results in:
fewer instances needed
more cold starts
a higher timeout
no autoscaling at all

27. Why do functions need to be idempotent?

Event delivery is at-least-once, so the same event may reach your function more than once. This happens after a retry, a timeout, or a network hiccup. If running the function twice causes harm, such as double-charging a customer, the function is not idempotent.

To make it safe, use the event ID as an idempotency key. Check whether you already processed it before acting.

def handle(cloud_event):
    event_id = cloud_event["id"]
    if already_done(event_id):
        return
    do_work()
    mark_done(event_id)

Use transactions or conditional writes so the check and the mark happen atomically.

Natural keys also work. If the event says order 42 is paid, setting order 42 to paid twice leaves the same result, so no extra check is needed.

Take quiz
At-least-once delivery means an event may be:
delivered exactly once always
delivered more than once
never delivered
delivered only to one region
A good idempotency key for an event is:
the current timestamp
the instance hostname
a random number
the CloudEvent ID

28. How do retries work for event-driven Cloud Run functions?

Retries are off by default. When you enable them, a failed invocation is retried until it succeeds or the retry window ends. For 2nd gen, that window is 24 hours, with exponential backoff between 10 and 600 seconds.

gcloud functions deploy my-func --gen2 --retry ...

Retries help with transient errors but can loop forever on a bug in your code. To avoid an endless loop, drop events older than a threshold by checking the event timestamp. Pair retries with idempotent code.

Because of the backoff, a function that keeps failing is invoked less and less often as time passes, rather than hammering the failing dependency.

Take quiz
What is the retry window for 2nd gen event-driven functions?
1 hour
24 hours
5 minutes
7 days
Retries are, by default:
enabled with 3 attempts
enabled with no limit
enabled for HTTP only
disabled

29. When should you use Cloud Run functions instead of Cloud Run?

Choose Cloud Run functions when the job is a small, single-purpose handler: reacting to a bucket upload, processing a Pub/Sub message, or answering a simple webhook. You write only the function, and Google handles the packaging.

Choose Cloud Run when you need a custom runtime, system libraries, a multi-route API, or an existing container image.

If you have a function that has outgrown its single handler, you can move it to Cloud Run with little rework because both run on the same platform.

Cost rarely decides it, since both bill on the same usage model. The real question is whether the function packaging gets in your way.

Take quiz
Which task fits Cloud Run functions best?
Resizing an image after upload
Hosting a 30-route REST API
Running a custom C++ binary
Training a large model
You need a custom system library. Which is a better fit?
A Cloud Run function with default runtime
Cloud Scheduler
Cloud Run with a custom container
Pub/Sub

30. How does an HTTP function handle CORS?

Browsers send a preflight OPTIONS request before cross-origin calls, and your function must answer with the right CORS headers. If it does not, the browser blocks the response.

def api(request):
    headers = {"Access-Control-Allow-Origin": "https://app.example.com"}
    if request.method == "OPTIONS":
        headers.update({
            "Access-Control-Allow-Methods": "GET, POST",
            "Access-Control-Allow-Headers": "Content-Type",
            "Access-Control-Max-Age": "3600"})
        return ("", 204, headers)
    return ({"ok": True}, 200, headers)

Avoid a wildcard origin on authenticated endpoints. Also note that IAM-protected functions reject the preflight unless it is allowed, which is a common surprise.

Set Access-Control-Max-Age so browsers cache the preflight and skip it on later calls. Test from a real browser, because curl will never reveal CORS problems.

Take quiz
A browser sends which request type before a cross-origin call?
A HEAD request to DNS
A TRACE request
A PATCH request
A preflight OPTIONS request
Which header controls which origins may call the function?
X-Frame-Options
Access-Control-Allow-Origin
Retry-After
Cache-Control

31. How do you test a Cloud Run function locally?

Run it with the Functions Framework, which starts a local HTTP server that behaves like the managed runtime.

functions-framework --target=hello_http --port=8080
curl "localhost:8080?name=Ana"

For event-driven functions, send a CloudEvent as an HTTP POST with the right headers, using curl or a test script. For unit tests, call the function directly with a mock request or event object. Emulate dependencies such as Pub/Sub or Firestore with their local emulators where available.

Test with the same language version as production, since small version differences cause surprises. A local run does not enforce IAM or use the real service account, so do a final check in a dev project after deploying.

Take quiz
Which tool runs a function locally?
Cloud Debugger
Config Connector
Functions Framework
Cloud Shell Editor only
An event-driven function can be tested locally by sending:
a CloudEvent as an HTTP POST
an SMS
a DNS query
a Terraform plan

32. What is a service account in Cloud Run functions?

Each function runs as a runtime service account, and that identity decides what Google Cloud resources your code can access. By default it is the Compute Engine default service account, which often has broad permissions.

Best practice is to create a dedicated service account per function and grant only the roles it needs, such as roles/storage.objectViewer on one bucket.

gcloud functions deploy my-func --gen2 \
  --service-account=fn-reader@my-proj.iam.gserviceaccount.com

The default account often holds broad project roles, so a bug or compromised dependency could modify unrelated resources. Reviewing the roles on each function's account is a quick, high-value security audit for any team.

Take quiz
A function's runtime service account determines:
the function's URL
the billing region
which Google Cloud resources the code can access
the runtime language
The recommended approach to service accounts is:
a dedicated least-privilege account per function
one owner account for all
no service account at all
the default account with Editor role

33. How do you configure memory and CPU for a Cloud Run function?

Use --memory and --cpu at deploy time. In 2nd gen you can go up to 16 GiB of memory and 4 vCPUs.

gcloud functions deploy my-func --gen2 \
  --memory=1Gi --cpu=2

CPU and memory must be in a valid pairing, so more memory may require more CPU. If you see out-of-memory errors or slow CPU-bound work, increase these. Raising CPU can also shorten cold starts for heavy initialization, though it increases cost per second.

Concurrency interacts with these numbers. Ten parallel requests that each need 100 MiB add up to roughly a gigabyte, so memory has to cover peak parallel load, not just a single request.

Take quiz
Max memory per 2nd gen function is:
512 MiB
16 GiB
2 GiB
128 GiB
Which flag sets vCPU count?
--cores-limit
--vcpu-max
--threads
--cpu

34. What is the structure of a CloudEvent?

A CloudEvent is a standard envelope describing an event. It has required attributes plus a data payload.

Attribute Meaning
id Unique ID of the event
source Where the event originated
type Kind of event, e.g. storage object finalized
specversion CloudEvents spec version
time When the event occurred
data The event payload

Your function gets this object and reads data for the details. Use id for idempotency and time to discard stale events.

The trigger defines the event type and the data schema. A Storage event carries a bucket and name, while a Pub/Sub event carries a message with base64 data and attributes, so check the type before parsing.

Take quiz
Which CloudEvent attribute identifies the kind of event?
type
specversion
time
id
Which attribute is useful as an idempotency key?
source
specversion
id
data

35. What is the purpose of the --entry-point flag?

--entry-point tells Cloud Run functions which function in your source to invoke. A single source file can contain many functions, but only the named one is exposed.

If the value does not match an exported function name, the deploy fails or the container cannot start. In Node.js it matches a registered function name, in Go a registered function, and in Java a fully qualified class name.

gcloud functions deploy hello --gen2 --runtime=python312 \
  --entry-point=hello_http --trigger-http

A mismatch is a common reason a freshly deployed function fails its first startup check. Verify the spelling, and in Python make sure the function sits at the top level of main.py.

Take quiz
The --entry-point flag selects:
the Cloud region
the IAM role
the VPC subnet
the function in the source to invoke
In Java, the entry point is typically:
a Maven repo URL
a fully qualified class name
a bucket name
a pom.xml tag

36. Explain the execution flow of an event-driven Cloud Run function?

When something happens at the event source, Eventarc matches it against your trigger filters, wraps it as a CloudEvent, and sends it to the function's underlying Cloud Run service over HTTP.

The Functions Framework inside the instance parses that request and calls your handler. If the handler returns normally, the delivery counts as successful. If it throws or times out, and retries are on, Eventarc redelivers the event.

sequenceDiagram
  participant S as Event source
  participant E as Eventarc
  participant F as Functions Framework
  participant H as Your handler
  S->>E: Event occurs
  E->>E: Match trigger filters
  E->>F: HTTP POST with CloudEvent
  F->>H: Call handler(cloud_event)
  alt Success
    H-->>F: Return
    F-->>E: 2xx response
  else Error or timeout
    H-->>F: Exception
    F-->>E: Error response
    E->>F: Retry if enabled
  end
Take quiz
What does Eventarc do first when an event occurs?
Deletes the event
Starts a Cloud Run job
Rotates the secret
Matches it against trigger filters
If the handler throws and retries are on, then:
the function is deleted
the event is redelivered
the IAM role is revoked
the event is converted to HTTP GET

37. How can you reduce cold start latency in Cloud Run functions?

Start by attacking what happens at startup, then use platform settings for what remains.

  1. Set --min-instances to 1 or more so a warm instance is always ready.
  2. Trim dependencies and import heavy libraries lazily, only inside the code path that needs them.
  3. Keep global initialization small and avoid blocking network calls at startup.
  4. Raise CPU if startup is compute-bound.
  5. Increase concurrency so fewer new instances are needed under load.

Measure first. Logs and traces show whether the delay is container start or your own init code.

Cold starts also differ by language. Go and Node.js usually start faster than a large Java application, so factor that in when latency matters. Keep the source small, and make sure startup does not block on a slow dependency.

Take quiz
Which setting keeps a warm instance always available?
max-instances of 1
timeout of 0
min-instances of 1 or more
ingress internal
Lazy importing helps cold starts because it:
skips heavy imports on code paths that don't need them
compresses the container image
disables Cloud Logging
pins the CPU architecture

38. What happens when a Cloud Run function exceeds its timeout?

The caller immediately gets an HTTP 504 response. Any response your code later produces is discarded.

The catch is that the instance is not necessarily killed. It may be throttled but keep running until your code exits by itself. This can make work and log lines from one request appear during a later one, which is confusing to debug.

To avoid it, set a timeout comfortably above your expected runtime, track the time remaining, and return early with cleanup when you are close to the limit.

For example, if a job needs about 90 seconds, set the timeout to 120 seconds rather than leaving 60. If runtime is unpredictable, split the work into smaller pieces that each fit comfortably, and log elapsed time at key steps to see where it goes.

Take quiz
What does the caller see when the timeout is exceeded?
HTTP 201
HTTP 504
HTTP 301
HTTP 418
After a timeout, the instance may:
be wiped instantly with no logs
restart the whole region
double its memory
keep running until the code exits

39. How do you troubleshoot an out-of-memory error in a function?

An OOM shows up as the instance being terminated, often with a log line saying the memory limit was exceeded. Start by checking the memory utilization metric in Cloud Monitoring around the failure time.

  1. Compare peak usage with the configured --memory value.
  2. Check concurrency. Each parallel request adds to the instance's memory use, so lowering concurrency can fix it.
  3. Look for large files read fully into memory. Stream them instead.
  4. Remember that files written to /tmp live in memory and count toward the limit.
  5. Raise memory if the workload genuinely needs it.

After the fix, add an alert on memory utilization above roughly 80 percent so you hear about it before instances start crashing. Heap profiling tools for your language help find leaks when usage climbs request after request.

Take quiz
Files written to /tmp in a function are stored:
in memory
on a persistent disk
in Cloud Storage
in Firestore
Which setting can reduce memory pressure besides raising memory?
Raising max instances
Adding labels
Lowering concurrency
Changing the region

40. Why should you initialize clients in global scope?

Code in global scope runs once per instance, not once per request. Creating an expensive object there, like a database pool or a Storage client, lets later requests on the same warm instance reuse it.

from google.cloud import storage
client = storage.Client()   # created once per instance

def handler(request):
    bucket = client.bucket("my-bucket")
    ...

Doing the same inside the handler would rebuild the client on every call, adding latency and wasting connections. The trade-off is that heavy global code lengthens the cold start, so initialize lazily if the object is only used on some paths.

A related trap is storing per-request data in global variables. Since one instance can serve many requests, one user's data may leak into another response, so keep request state inside the handler.

Take quiz
Global scope code runs:
once per instance
once per request
once per day
once per deploy region
The downside of heavy global initialization is:
it breaks IAM
it disables retries
it slows cold starts
it prevents logging

41. Why should you avoid background work after returning a response?

Once an HTTP function returns its response, the request is considered finished and the instance's CPU can be throttled. Threads, timers, or async tasks left running may slow to a crawl or stop entirely until the next request wakes the instance.

So work like sending an email or writing an audit record may never complete, or may complete at a random later time.

Finish everything before returning. For work that really can happen later, publish a message to Pub/Sub or create a Cloud Task, and let a second function handle it with its own retries.

The same applies to unflushed logs or metric buffers. Flush or close them before returning, otherwise the last entries from a request may be lost when CPU is throttled.

Take quiz
After an HTTP function responds, its CPU may be:
doubled
moved to another region
exclusive to that request
throttled
A safe way to defer work is to:
start a detached thread
publish a Pub/Sub message or create a Cloud Task
use a global timer
write to a local file

42. How do you handle long-running work triggered by an event?

Event-driven functions are capped at 9 minutes, so anything longer needs a different shape.

The cleanest fix is to hand the work to a Cloud Run job, which can run up to 24 hours. The function becomes a thin launcher that starts the job and exits.

Another option is to split the work into chunks. The function processes one chunk, then publishes a message for the next, which keeps every invocation short and retryable. For multi-step flows with branching and waiting, use Workflows to coordinate the pieces.

Pass only a reference through the event, such as a file path, not the file itself. The job reads the data directly, which keeps messages small. Log the job execution ID inside the function so you can link the two later.

Take quiz
The best place to run work longer than 9 minutes is:
a larger event function
a Cloud DNS zone
a Cloud Run job
Cloud Armor
Chunking work with Pub/Sub keeps each invocation:
short and retryable
unauthenticated
stateful
region-locked

43. How do you roll back a bad Cloud Run function deployment?

Every deploy of a 2nd gen function creates a new revision of the underlying Cloud Run service, and earlier revisions are kept. To roll back, point traffic back to the last known good revision.

gcloud run services update-traffic my-func \
  --region=us-central1 \
  --to-revisions=my-func-00012-abc=100

If you cannot find a clean revision, redeploy the previous version of your source from version control. For safer releases, route a small share of traffic to the new revision first, watch error rates, and then shift the rest.

Rollback is fast because the old revision is already built, so no rebuild is needed. After rolling back, check logs from the failed revision to find the cause. Revision tags also let you test a candidate at its own URL without sending it production traffic.

Take quiz
Each deploy of a 2nd gen function creates a new:
VPC network
revision
Pub/Sub topic
Billing account
A safer release strategy is to:
deploy to all regions at once
delete the old revision first
disable logging
send a small share of traffic to the new revision first

44. How do you deploy Cloud Run functions with Terraform?

Use the google_cloudfunctions2_function resource. You upload zipped source to a Cloud Storage bucket, then reference it in the function's build config.

resource "google_cloudfunctions2_function" "fn" {
  name     = "hello"
  location = "us-central1"

  build_config {
    runtime     = "python312"
    entry_point = "hello_http"
    source {
      storage_source {
        bucket = google_storage_bucket.src.name
        object = google_storage_bucket_object.zip.name
      }
    }
  }

  service_config {
    max_instance_count = 20
    available_memory   = "512Mi"
    timeout_seconds    = 60
  }
}

Remember to grant invoker access with a separate IAM resource if the endpoint needs to be callable.

Tie the source object name to a content hash so Terraform notices when the code changes and redeploys. Manage the service account and IAM bindings in the same module, which makes the function's access reviewable in a pull request.

Take quiz
Which Terraform resource deploys 2nd gen functions?
google_compute_instance
google_cloudfunctions2_function
google_app_engine_app
google_bigquery_table
Where is the zipped source typically uploaded for Terraform deploys?
A Firestore collection
A Pub/Sub topic
A Cloud SQL table
A Cloud Storage bucket

45. How do you handle poison messages in a Pub/Sub-triggered function?

A poison message is one that always fails, such as malformed JSON. With retries enabled it will be redelivered over and over until the retry window closes, wasting invocations.

Handle it in code. Catch errors that can never succeed, such as validation failures, log them, and return normally so the message is acknowledged. Send the payload to a separate dead-letter topic or a storage location for review.

Keep real retries only for transient failures, like a timeout calling a downstream API. Also drop events older than a sensible age so a stuck message does not loop for 24 hours.

Tracking error counts by type helps you spot a bad producer. If most failures come from one malformed field, fixing the sender is better than tuning retries.

Take quiz
A poison message is one that:
always fails when processed
is delivered too quickly
is larger than 1 KB
has no attributes
For validation failures that can never succeed, you should:
throw so it retries forever
increase memory
log, divert to a dead-letter location, and return normally
restart the instance

46. How does service-to-service authentication work between Cloud Run functions?

The caller fetches a Google-signed ID token whose audience is the target function's URL, then sends it as a bearer token. The target verifies it against the roles/run.invoker binding on the caller's service account.

import google.auth.transport.requests
import google.oauth2.id_token
import requests

url = "https://target-abc.a.run.app"
req = google.auth.transport.requests.Request()
token = google.oauth2.id_token.fetch_id_token(req, url)
r = requests.get(url, headers={"Authorization": f"Bearer {token}"})

Inside Google Cloud the token comes from the metadata server, so no key files are needed.

A frequent mistake is mixing audiences, because a token minted for one function's URL is rejected by another. The caller's service account also needs the invoker role on the target, otherwise you get a 403 even with a valid token. For manual tests, gcloud auth print-identity-token gives you a token to use with curl.

Take quiz
The ID token's audience should be set to:
the caller's project number
the caller's IP
the bucket name
the target function's URL
Inside Google Cloud, the ID token is obtained from:
a downloaded JSON key in git
the metadata server
Cloud DNS
Cloud Scheduler

47. How does pricing work for Cloud Run functions?

Pricing is usage based and follows Cloud Run's model. You are billed for the number of invocations, the compute time (vCPU-seconds and GiB-seconds while handling requests), and network egress. A monthly free tier applies.

Minimum instances add cost because idle warm instances are billed too. Build time in Cloud Build and logging volume are charged separately.

To cut costs, right-size memory and CPU, raise concurrency so one instance serves more requests, and avoid unnecessary min instances. Check the current price list for exact rates, since they change by region.

A function that mostly waits on slow APIs still bills for that waiting time, so tight timeouts and async clients can reduce spend. Compare cost per thousand invocations at your real memory setting instead of guessing.

Take quiz
Which is part of Cloud Run functions billing?
Number of IAM roles
Length of function name
Invocations and compute time
Count of environment variables
Raising concurrency can lower cost because:
one instance serves more requests
it disables billing
it removes egress
it hides logs

48. How do you set up CI/CD for Cloud Run functions?

A common pattern is a Cloud Build trigger on your repository's main branch. Each push runs tests, then deploys with gcloud functions deploy.

steps:
  - name: python:3.12
    entrypoint: bash
    args: ["-c", "pip install -r requirements.txt pytest && pytest"]
  - name: gcr.io/google.com/cloudsdktool/cloud-sdk
    args: ["gcloud", "functions", "deploy", "my-func",
           "--gen2", "--region=us-central1", "--runtime=python312",
           "--source=.", "--entry-point=handler", "--trigger-http"]

GitHub Actions works too using Google's auth action with Workload Identity Federation, which avoids long-lived keys. Give the deploy identity only the roles it needs.

Deploy to a staging project first and run a smoke test against the new URL before promoting. Keep the deploy command in the pipeline rather than typed by hand, so every environment uses identical flags. If the smoke test fails, the pipeline stops and production stays untouched.

Take quiz
A common deploy trigger in Cloud Build is:
a DNS change
a billing alert
a push to the main branch
a Pub/Sub topic deletion
Which approach avoids long-lived service account keys in GitHub Actions?
Workload Identity Federation
Committing JSON keys
Using the owner role
Public buckets

49. How do you monitor and alert on a Cloud Run function?

Cloud Monitoring collects metrics for the underlying Cloud Run service automatically. The useful ones are request count, request latency, container instance count, and CPU and memory utilization.

Build alerting policies on symptoms users feel: a rising 5xx error ratio, p95 latency above your target, or instance count hitting the max-instances cap. For event-driven functions, also watch the age of the oldest unacknowledged message on the Pub/Sub subscription.

Add a logs-based metric for application errors that do not surface as HTTP codes, and use Cloud Trace to follow a slow request across services.

Send alerts to a channel the team actually watches, and attach a short runbook link to each policy. A dashboard that shows errors, latency, and instance count together makes triage much quicker during an incident.

Take quiz
Which signal best reflects user-visible failures?
Function name length
5xx error ratio
Number of labels
Region count
For Pub/Sub-triggered functions, a useful backlog signal is:
bucket location
CPU architecture
log retention days
age of the oldest unacknowledged message

50. When would you choose Workflows over chaining functions directly?

Chaining functions by having one call another over HTTP spreads logic across code, hides failures, and makes retries hard to reason about. If step 3 fails, nobody knows the state of steps 1 and 2.

Choose Workflows when you have several steps, branching, waiting, or need per-step retries and visible execution history. The workflow calls each function, tracks state, and handles errors in one place.

flowchart LR
  A[Start] --> B["Validate order function"]
  B --> C{Valid?}
  C -- Yes --> D["Charge payment function"]
  C -- No --> G[Reject]
  D --> E["Ship function"]
  E --> F[Done]

For a single trigger and a single action, a plain function is simpler and cheaper.

Workflows also lets you set a retry policy per call and keeps a record of every execution, which simplifies debugging a failed order.

Take quiz
Workflows is a better fit than direct chaining when you need:
branching and per-step retries with visible history
a single trivial action
no error handling
faster cold starts
A downside of function-calls-function chains is:
they require no IAM
they cannot use HTTP
failures leave unclear state across steps
they only run once per year
«
»

Comments & Discussions