Cloud Run vs Cloud Functions: What Changed and Which to Use

Cloud Run vs Cloud Functions on Google Cloud, with functions deployed as Cloud Run services

How a Cloud Run function and a Cloud Run service both end up as Cloud Run services

Cloud Functions is now Cloud Run functions, and that changes the cloud run vs cloud functions question. A function you deploy today runs as a Cloud Run service. So the real choice is between handing Google your source code or handing it a container. Pick a function for a small event or HTTP handler. Pick a plain Cloud Run service when you need your own container or several routes in one app.

I didn’t deploy anything to a Google Cloud project for this guide. The limits and commands come from Google’s current docs, which I read on November 5, 2026. The two code samples ran locally, and I say so where it matters.

What Is the Difference Between Cloud Run vs Cloud Functions?

With a Cloud Run function you write source code and Google builds the container for you. With Cloud Run you bring a container you build yourself. Google’s Cloud Run functions comparison page says functions are built as containers and deployed as Cloud Run services, so both end up on the same platform.

Cloud Run functions Cloud Run (container)
What you deploy Source code and an entry point A container image
Runtime and web server Chosen from a list of base images Anything you can containerize
Typical triggers HTTP, plus any Eventarc event type HTTP, gRPC, and web traffic
Request timeout 60 minutes for HTTP, 9 minutes for event-driven 300 seconds by default, configurable
Concurrency per instance Up to 1,000 80 by default, configurable
Best for Glue code and event handlers APIs, apps, custom runtimes

The function rows come from that comparison page. The service rows come from Google’s concurrency and request timeout docs, which list 3,600 seconds as the maximum timeout. Its gcloud section says the value “must be less than 60 minutes,” so I wouldn’t count on the full hour.

Did Google Rename Cloud Functions?

Yes. Cloud Run functions is the new name for Cloud Functions 2nd gen. What was called Cloud Functions 1st gen is now Cloud Run functions (1st gen). Both names still appear in older tutorials, and mixing them up is how people end up following the wrong deploy command.

The 1st gen version is much more limited. According to the same comparison page:

  • Timeout: 9 minutes
  • Concurrency: 1 request per instance
  • Size: up to 8 GB of RAM and 2 vCPUs, against 16 GiB and 4 vCPUs for the current version
  • Event triggers: direct support for events from 7 sources, against any Eventarc-supported event type

The pages I read give no end-of-life date for 1st gen. However, they do describe it as the original version with “limited event triggers, runtimes, and configurability,” and they link to an upgrade guide. So for anything new, skip 1st gen.

How Do You Deploy a Function vs a Container?

Both deploy with gcloud run deploy. A function adds two flags that tell Cloud Run to treat your source as a function. This is the command from Google’s deploy-functions guide:

gcloud run deploy FUNCTION \
       --source . \
       --function FUNCTION_ENTRYPOINT \
       --base-image BASE_IMAGE \
       --region REGION

FUNCTION_ENTRYPOINT is the function name in your code. BASE_IMAGE picks the runtime, and the docs list examples such as nodejs24, python314, go127, java25, dotnet10, ruby40 and php85. Also, add --allow-unauthenticated only if the function should be public.

A container you built yourself skips the function flags and points at an image instead:

gcloud run deploy my-service --image IMAGE_URL --region REGION

Two setup steps trip people up before the first deploy works. First, enable the APIs, including cloudbuild.googleapis.com and artifactregistry.googleapis.com. Second, the deploy guide says to grant roles/run.builder to the Compute Engine default service account, and that this “takes a couple of minutes to propagate.” If your first source deploy fails right after the grant, wait a few minutes before you change anything else. The GCP service account guide covers the account side.

⚠️ Note: gcloud run deploy creates or updates a live service in your current project. Check gcloud config get project before you run it.

What Do You Write for Each One?

A function is a single handler, but a container is a whole web server plus a Dockerfile. Here is the HTTP function from Google’s Python Functions Framework README:

import flask
import functions_framework

@functions_framework.http
def hello(request: flask.Request) -> flask.typing.ResponseReturnValue:
    return "Hello world!"

I ran it locally with functions-framework --target hello. Version 3.10.2 answered 200 OK with Hello world!. The same behavior as a container service needs a web server and a Dockerfile. This is the one I built:

FROM python:3.14-slim
WORKDIR /app
RUN pip install --no-cache-dir flask gunicorn
COPY app.py .
CMD exec gunicorn --bind 0.0.0.0:${PORT:-8080} app:app

Built and run with -e PORT=8082, it also returned 200 OK and Hello world!. The function needed one file. The container needed two, and you also have to choose a server. Cloud Run’s container contract explains the 0.0.0.0 and PORT parts: the container must listen on 0.0.0.0 on the port Cloud Run sends requests to, and PORT tells your server which one. Binding to 127.0.0.1 won’t work.

Both ran on my machine only, because I haven’t deployed either one.

When Do the Limits Force the Choice?

Rarely. Because functions run as Cloud Run services, Google says you keep access to things like Direct VPC, GPUs and volume mounts. The deciding factors are usually your language, how many routes you serve, and how the work starts.

  • Choose a container when your runtime isn’t on the base image list, when you need a system binary, or when the app serves many routes. A function is one entry point.
  • Choose a function when Cloud Storage, Pub/Sub or Eventarc events start the work. Functions support any Eventarc event type, so there is no custom trigger plumbing to write.
  • Check the timeout if a job runs longer than 9 minutes and starts from an event. That limit applies to event-driven functions, not HTTP-triggered ones.

Long batch work is a different problem. Both options are built around requests and events, so a job that runs for hours doesn’t fit either one. I didn’t look into Cloud Run jobs for this guide.

Cloud Run vs Cloud Functions: Which Should You Use?

Use Cloud Run functions for small event handlers, webhooks and glue between services. Use Cloud Run with a container for APIs, full apps and anything with a custom runtime. If you’re unsure, start with a function. Google’s own blog says the second generation is built on Cloud Run’s infrastructure, so you can move to a container later when you need more control.

Situation Use
Resize an image when it lands in a bucket Function
Receive a GitHub or Stripe webhook Function
REST API with many routes Cloud Run container
Legacy app that already has a Dockerfile Cloud Run container
Language or binary not on the base image list Cloud Run container
New code on 1st gen Neither. Use current Cloud Run functions

I couldn’t get exact numbers from Google’s Cloud Run pricing page in my fetch, so I haven’t compared costs here. Check that page before you estimate a bill. For deploying either one from CI, the serverless deployments with GitHub Actions guide shows the pipeline side, and the multi-cloud Docker image guide covers pushing images.

Frequently Asked Questions

Q: Is Cloud Functions the same as Cloud Run functions?
A: Yes. Cloud Run functions is the new name for Cloud Functions 2nd gen, and 1st gen is now Cloud Run functions (1st gen). Functions deploy as Cloud Run services, which is why they share features with Cloud Run.

Q: Should I use Cloud Run or Cloud Functions for a new project?
A: Use a function for small event handlers and webhooks, and a Cloud Run container for APIs and apps. Both run on Cloud Run, so you can start with a function and move to a container later.

Q: What are the timeout limits for Cloud Run functions?
A: Google’s comparison page lists 60 minutes for HTTP-triggered functions and 9 minutes for event-driven functions on the v2 API. 1st gen functions are capped at 9 minutes.

Q: How many requests can one instance handle?
A: Up to 1,000 concurrent requests for a Cloud Run function. A 1st gen function handles 1. For Cloud Run services, the default is 80, and you change it with --concurrency.

Q: Do I need Docker to deploy a function?
A: No. You deploy source code with gcloud run deploy FUNCTION --source . --function FUNCTION_ENTRYPOINT --base-image BASE_IMAGE, and Google builds the container. A plain Cloud Run service needs a container image you build.

Quick Summary:
– Cloud Functions is now Cloud Run functions, and a function deploys as a Cloud Run service
– Functions take source code and a base image. Cloud Run takes a container you build
– Functions allow 60 minutes for HTTP triggers and 9 minutes for event-driven ones
– Concurrency is up to 1,000 for functions and 80 by default for services
– 1st gen allows 1 request per instance and 9 minutes, and Google gives no end-of-life date in the pages I read
– My Python function and container sample both returned Hello world! locally, but I didn’t deploy either

Before you settle cloud run vs cloud functions, answer one question: could this be a single handler in one of the supported base images? If so, deploy a function. If not, write the Dockerfile and use Cloud Run.

Related guides

Leave a Reply