Cloud Run vs Cloud Functions vs App Engine

Google Cloud has three ways to run code without managing servers, and they have converged: functions are now deployed on Cloud Run, and Google recommends Cloud Run over App Engine for new work. This guide explains what each is today, where Cloud Run jobs fit for data work, what scaling to zero saves and how to choose.

GloryTecks Team

Training & Placement Faculty

6 May 2026 8 min read

Last updated: 2 October 2026

Share:

Ask how to run code on Google Cloud without managing servers and you will hear three names: App Engine, Cloud Functions and Cloud Run. They arrived in that order, each closer to "give us your code and we will run it", and for years choosing between them was a real decision. It is much less of one now. The three have converged, and the comparison is best understood as history plus one platform.

What each is today

App Engine is the oldest: a platform for web applications where you deploy code and it handles servers and scaling. It still works and is still supported. Google's own documentation, though, now opens with a recommendation that new users choose Cloud Run instead, and calls Cloud Run a newer and better alternative (Google Cloud: App Engine overview).

Cloud Functions has been renamed Cloud Run functions. A function is now built into a container and deployed as a service on Cloud Run (Google Cloud: compare Cloud Run functions). It is a way of using Cloud Run, not a separate platform.

Cloud Run is the platform underneath: it runs containers, built from your source code or supplied by you, and scales them automatically (Google Cloud: what is Cloud Run).

So the practical question in 2026 is not which of three products, but which form of Cloud Run, and whether you have a reason to be on App Engine at all.

The forms of Cloud Run

FormWhat it doesEnds when
ServiceAnswers HTTP requests and events at a stable URLNever; scales with traffic, down to zero
FunctionA service built from one function of source codeSame as a service
JobRuns a task, or many in parallel, to completionThe work is done
Worker poolRuns always-on background workers that pull workYou stop it

A service is the default. It has an HTTPS endpoint, handles many requests per instance, and adds or removes instances as traffic changes. A request can run for up to 60 minutes (Google Cloud: Cloud Run quotas and limits).

A function is the same thing with less ceremony: you write one function and Cloud Run builds the container. Google's resource model describes functions as a specialized version of source deployment for single-purpose, event-driven code (Google Cloud: deployment options). See Cloud Functions on GCP.

A job is the form data engineers should know and often overlook. It does not listen for requests. It runs your container, the container does its work and exits. A job can be split into as many as 10,000 independent tasks run in parallel, and each task can run for up to 168 hours, which is seven days (Google Cloud: create jobs). A nightly export script, a backfill, a batch of files to convert: these are jobs, and they need neither a cluster nor a web server.

bash
# A service, built from the source in the current directory
gcloud run deploy orders-api --source . --region asia-south1

# A job with 50 parallel tasks, then one execution of it
gcloud run jobs create convert-files \
  --image asia-south1-docker.pkg.dev/analytics-prod/jobs/convert:latest \
  --tasks 50 --region asia-south1
gcloud run jobs execute convert-files --region asia-south1

# A function
gcloud run deploy on-file --source . --function on_file \
  --base-image python314 --region asia-south1

App Engine's two environments

If you meet App Engine, it will be in one of two forms (Google Cloud: App Engine environments):

StandardFlexible
Runs your code inA sandbox with supported language runtimesDocker containers on virtual machines
Instance startupSecondsMinutes
Scale to zeroYesNo, at least one instance
Custom runtimeNoYes

The standard environment was the original serverless offer: cheap, fast to scale, restricted. The flexible environment relaxed the restrictions at the price of always running something. Cloud Run offers the flexibility of the second with the scaling of the first, which is why it is the recommendation.

Reasons to stay on App Engine are reasons of inertia, and they are legitimate: an application that already runs there, uses its bundled services and works. Migration has a cost, and there is no deadline forcing it.

What scaling to zero is worth

The feature that separates these options economically is whether an idle service costs money. Cloud Run lets you choose: request-based billing charges only while requests are being handled and scales to zero; instance-based billing charges for the whole life of an instance, at a lower rate per second.

The script prices one small service both ways at list prices for us-central1 (Google Cloud: Cloud Run pricing). It is a calculation under stated assumptions, not a bill, and it ignores concurrency, which would make the request-based figures lower still.

python
# What one small web service costs on Cloud Run under two billing modes, from the list prices on
# Google's pricing page for us-central1 on 2 October 2026. A calculation, not a bill. Assumptions:
# 1 vCPU and 0.5 GiB per instance, 200 ms of instance time per request, one request at a time.
import math

VCPU, GIB, SECONDS_PER_REQUEST = 1, 0.5, 0.2
MONTH = 730 * 3600                                           # seconds

# Request-based billing: pay while handling requests; scales to zero when idle.
CPU_ACTIVE, MEM_ACTIVE, PER_MILLION = 0.000024, 0.0000025, 0.40
FREE_CPU, FREE_MEM, FREE_REQUESTS = 180_000, 360_000, 2_000_000

# Instance-based billing: pay for the whole time an instance exists.
CPU_INSTANCE, MEM_INSTANCE = 0.000018, 0.000002
FREE_CPU_I, FREE_MEM_I = 240_000, 450_000


def request_based(requests):
    busy = requests * SECONDS_PER_REQUEST
    cpu = max(0, busy * VCPU - FREE_CPU) * CPU_ACTIVE
    memory = max(0, busy * GIB - FREE_MEM) * MEM_ACTIVE
    calls = max(0, requests - FREE_REQUESTS) / 1_000_000 * PER_MILLION
    return cpu + memory + calls


def always_on(requests):
    instances = max(1, math.ceil(requests * SECONDS_PER_REQUEST / MONTH))
    seconds = instances * MONTH
    cost = max(0, seconds * VCPU - FREE_CPU_I) * CPU_INSTANCE + max(0, seconds * GIB - FREE_MEM_I) * MEM_INSTANCE
    return instances, cost


print(f"{'requests a month':>16} {'busy share':>11} {'scale to zero':>14} {'always on':>10}  instances")
for requests in (100_000, 1_000_000, 5_000_000, 10_000_000, 13_000_000):
    instances, fixed = always_on(requests)
    share = requests * SECONDS_PER_REQUEST / MONTH
    print(f"{requests:16,} {share:11.1%} {request_based(requests):14.2f} {fixed:10.2f}  {instances}")
text
requests a month  busy share  scale to zero  always on  instances
         100,000        0.8%           0.00      44.71  1
       1,000,000        7.6%           0.48      44.71  1
       5,000,000       38.1%          21.23      44.71  1
      10,000,000       76.1%          48.48      44.71  1
      13,000,000       98.9%          64.83      44.71  1
  • At low traffic, scale to zero is nearly free. A service handling 100,000 requests a month is busy less than 1% of the time and falls inside the free tier. Keeping an instance on for it costs about USD 45.
  • The lines cross at about three-quarters busy. At 10 million requests the two cost roughly the same.
  • A constantly busy service is cheaper kept on. Past the crossover, the lower per-second rate of instance-based billing wins.

Most internal tools, webhooks and data utilities sit firmly in the first row. That is the argument for serverless in one table, and also its limit: steady, heavy traffic gains nothing from scaling to zero.

Choosing

  1. A new web service or API? A Cloud Run service.
  2. A small piece of code reacting to an event, such as a file arriving or a message published? A Cloud Run function.
  3. A script that runs and finishes, on a schedule or on demand? A Cloud Run job.
  4. Workers that continuously pull from a queue? A worker pool, or for data streams a pipeline service such as Dataflow.
  5. An existing App Engine application? Leave it until there is a reason to move.
  6. Large-scale data transformation? None of these. Use BigQuery, Dataflow or Spark, and use Cloud Run for the glue around them.

For the data-processing options in the last line, see Dataproc vs Dataflow. For orchestrating jobs and functions together, see Cloud Composer. And whichever form you use, run it as a dedicated identity: service accounts and workload identity.

Is Cloud Functions being replaced by Cloud Run?

It has been folded into it. Cloud Functions is now called Cloud Run functions, and a function is built into a container and deployed as a Cloud Run service. The older first generation still exists under the name Cloud Run functions (1st gen).

Should I use App Engine or Cloud Run for a new project?

Cloud Run. Google's App Engine documentation recommends Cloud Run as the preferred alternative for new users. App Engine remains supported for existing applications.

What is a Cloud Run job?

A container that runs to completion instead of serving requests. A job can be divided into up to 10,000 parallel tasks, and each task can run for up to seven days. It suits scripts, batch processing and scheduled work.

Does Cloud Run cost money when nothing is using it?

Not with request-based billing, where a service scales to zero and you pay only while requests are handled. With instance-based billing or a minimum number of instances, you pay for the time instances exist.

Deploying and operating pipeline code is covered in the Data Engineering course.

Sources

GloryTecks Team

Training & Placement Faculty

The GloryTecks faculty team mentors learners across Data Science, AI and Data Engineering, with a focus on real-time projects and placement readiness in Hyderabad.

Want to master GCP?

Join GloryTecks’ expert-led Data Engineering training in Hyderabad with real-time projects and 100% placement support.

Explore course