Options for teams whose Cloud Run functions have grown into a backend, compared on time limits, local development, databases and queues, and where the code runs.
Google Cloud Functions, now called Cloud Run functions, is often the first backend a team ships on Google Cloud. Write a handler, deploy it, and an HTTP request or Pub/Sub message runs it. For webhooks, glue code and small APIs, it is the right size.
Problems show up when the functions start to look like an application. These are the usual reasons teams look for alternatives:
Each option is covered below, starting with Encore.
Encore combines an open source infrastructure SDK for TypeScript and Go with a platform that provisions and deploys into your own AWS or GCP account. Where a Cloud Functions project has one deployment per handler, Encore groups endpoints and subscribers into services and declares the infrastructure they use in code. On GCP, Encore deploys to Cloud Run or GKE and creates Cloud SQL, Pub/Sub topics and subscriptions with dead-letter topics, Cloud Storage buckets, Secret Manager entries and a service account per service.

An HTTP function plus a Pub/Sub-triggered function, as one Encore service:
// invoicing/invoicing.ts
import { api } from "encore.dev/api";
import { Topic, Subscription } from "encore.dev/pubsub";
import { Bucket } from "encore.dev/storage/objects";
interface OrderPaid {
orderId: string;
totalCents: number;
}
// Pub/Sub on GCP, SNS and SQS on AWS.
export const orderPaid = new Topic<OrderPaid>("order-paid", {
deliveryGuarantee: "at-least-once",
});
// Cloud Storage on GCP, S3 on AWS.
const invoices = new Bucket("invoices", { versioned: false });
// What used to be an HTTP-triggered function.
export const markPaid = api(
{ expose: true, method: "POST", path: "/orders/:orderId/paid" },
async ({ orderId, totalCents }: { orderId: string; totalCents: number }): Promise<void> => {
await orderPaid.publish({ orderId, totalCents });
},
);
// What used to be an event-driven function.
const _ = new Subscription(orderPaid, "render-invoice", {
handler: async (e) => {
const key = `${e.orderId}.txt`;
// Writing the same key twice is harmless, so redelivery is safe.
const body = `Invoice for order ${e.orderId}: ${(e.totalCents / 100).toFixed(2)} USD`;
await invoices.upload(key, Buffer.from(body), { contentType: "text/plain" });
},
ackDeadline: "15m",
});
Run in your terminal to get started locally.
The subscriber runs inside the service on Cloud Run or GKE, and its time per message is set by ackDeadline instead of a fixed function limit. encore run runs the endpoint, the topic and the bucket locally, so a curl to /orders/123/paid shows the publish and the upload in the local trace view. The same code deploys to AWS if you add an AWS environment later.
encore run. The same declaration is used in every cloud environment.If all you have is two webhooks and a scheduled cleanup, Cloud Run functions is simpler. Encore pays off when there are many handlers sharing databases, queues and secrets.
Cloud Run functions are Cloud Run services underneath, so the smallest step is to deploy a container to Cloud Run yourself. One service can hold many routes, a single instance can serve up to 1,000 concurrent requests, and Cloud Run jobs handle batch work that does not fit a request.
You take on the Dockerfile or buildpacks and the HTTP server, and the infrastructure around the service is still separate work: Cloud SQL, Pub/Sub push subscriptions, Secret Manager and IAM.
Lambda is the AWS equivalent, with more event sources and a 15-minute limit for every invocation. It suits teams moving to AWS who want to keep a function-per-handler design.
It does not solve the sprawl problem, because each function still has its own role, configuration and triggers, and databases need RDS Proxy or careful connection handling because every concurrent invocation is its own environment.
Cloudflare Workers run JavaScript, TypeScript and WebAssembly on V8 isolates in Cloudflare's network, with fast startup and storage options such as KV, D1, R2 and Queues. Per the Workers limits, each Worker gets 128 MB of memory and a capped amount of CPU time per request.
It is a strong fit for request routing, auth at the edge and lightweight APIs. It is a different runtime from Node.js, and data in Google Cloud means requests travel back to a region anyway.
Vercel Functions deploy with a Next.js or other frontend project, so API routes ship with the UI that calls them. Billing is based on active CPU time and provisioned memory, and the maximum duration depends on your plan, per the function limits.
It works well for frontend-adjacent endpoints. Databases, queues and background work come from separate providers or integrations, and the code runs on Vercel's platform, not in your own cloud account.
Pick Encore when your Cloud Functions have grown into a backend with shared databases, queues and secrets, and you want it defined in TypeScript or Go, testable locally and deployed to your own GCP or AWS account. Pick Cloud Run services to stay on Google's platform with containers, Lambda if you are moving to AWS, Cloudflare Workers for edge logic, and Vercel Functions for APIs that belong to a frontend.
Google renamed Cloud Functions (2nd gen) to Cloud Run functions in August 2024. Functions now deploy as Cloud Run services, so they share Cloud Run's settings, and HTTP-triggered functions can run for up to 60 minutes while event-driven functions are limited to 9 minutes.
Encore if your functions have become a backend and you want services, Postgres, Pub/Sub and cron declared in TypeScript or Go and deployed to your own GCP or AWS account. Cloud Run services for containers without the function model. AWS Lambda if you are moving to AWS, Cloudflare Workers for edge logic, and Vercel Functions for frontend-adjacent APIs.
Move the work out of the event-driven function. Options include having the function start a Cloud Run job for the long-running part, or moving the work to an HTTP-triggered function, which can run for up to 60 minutes.
Deploy to your cloud on AWS and Google Cloud
without managing infrastructure
Encore lets developers and agents define application infrastructure directly in code, then automatically provisions it from local development to production in your AWS or GCP account.