Serverless Functions Compared: Lambda, Cloud Functions, and Azure Functions
AWS Lambda, Google Cloud Run functions, and Azure Functions compared on triggers, packaging, hosting options, identity, and billing, with clear guidance on when functions fit and when containers are better.
Serverless functions let you deploy a piece of code that runs in response to an event, scales from zero to many copies without any servers to manage, and bills only for the time it executes. AWS Lambda, Google Cloud Run functions (the current name for Cloud Functions), and Azure Functions are the three hyperscaler implementations, and they are similar enough that the differences matter more than the basics. This guide compares how each service is triggered, packaged, limited, and priced, and gives an honest view of where functions fit and where a container or a VM is the better tool.
How serverless functions work
You upload code and a small amount of configuration: the runtime, the entry point, the memory size, a timeout, and the identity the function runs as. The platform keeps that package ready and, when an event arrives, starts an isolated execution environment, runs your handler, and keeps the environment warm for a while in case another event follows. When demand rises, more environments start in parallel; when it falls, they are discarded. You never see the underlying host.
The first request to a cold environment pays a start up penalty known as a cold start. Its length depends on the runtime, the package size, and whether the function must attach to a private network. Interpreted runtimes with small packages start quickest; large Java or .NET packages take longer unless the platform’s warm up features are used.
Lambda, Cloud Run functions, and Azure Functions compared
Lambda is the oldest and has the widest set of native event sources inside AWS: API Gateway and Lambda function URLs for HTTP, S3 object events, SQS queues, DynamoDB streams, EventBridge schedules and rules, and many more. Functions are packaged as a zip archive or a container image, and a single invocation is capped at 15 minutes. Google’s offering has been rebuilt on Cloud Run, so a function is now a Cloud Run service with a function shaped entry point; HTTP triggers are native and other events arrive through Eventarc or Pub/Sub. Azure Functions is organised around a function app that groups several functions on one hosting plan, with bindings that declaratively connect triggers and outputs to services such as Blob Storage, Cosmos DB, Service Bus, and Event Grid.
| Concern | AWS Lambda | Google Cloud Run functions | Azure Functions |
|---|---|---|---|
| HTTP entry point | Function URL, API Gateway, or an Application Load Balancer | Built in HTTPS endpoint on the Cloud Run service | HTTP trigger, optionally behind API Management |
| Event sources | S3, SQS, SNS, DynamoDB streams, Kinesis, EventBridge, and others | Eventarc, Pub/Sub, Cloud Storage, Firestore, scheduler jobs | Bindings for Blob, Queue, Service Bus, Event Grid, Cosmos DB, timers |
| Packaging | Zip archive or container image | Source deployed and built with buildpacks, or a container image | Zip deploy or container image, depending on plan |
| Hosting choices | On demand, with provisioned concurrency to reduce cold starts | Cloud Run instance settings, including minimum instances | Consumption, Flex Consumption, Premium, or Dedicated plans |
| Identity | IAM execution role per function | Service account per service | Managed identity on the function app |
| Private networking | VPC attachment through elastic network interfaces | Direct VPC egress or a Serverless VPC Access connector | Virtual network integration on Premium and Flex plans |
Limits on memory, timeout, package size, and concurrency differ and change over time, so check each provider’s current documentation before designing around a specific figure. The one to watch first is the timeout, because a job that runs longer than the platform allows must be split or moved to a container service.
How functions are billed
All three bill on two meters: the number of invocations and the compute consumed, measured as memory allocated multiplied by execution time. Each provider includes a monthly free allowance of both, set by the provider and subject to change, which makes functions close to free for low traffic APIs, scheduled jobs, and glue code between services. Costs appear elsewhere: the API gateway in front of the function, data transfer out, the logging service that stores every invocation’s output, and any always on option such as provisioned concurrency or minimum instances.
The billing model rewards short, frequent work and punishes long, steady work. A function that runs continuously to poll a queue costs more than a small VM doing the same job, so use native triggers instead of polling wherever the platform offers them.
When functions fit and when they do not
- Good fit: webhooks, image and file processing on upload, scheduled housekeeping, thin APIs with bursty traffic, and event handlers that connect two managed services.
- Good fit: workloads with long idle periods where scale to zero saves real money.
- Poor fit: long running batch jobs, anything that needs a persistent connection such as a WebSocket server without a managed gateway, and latency sensitive paths that cannot tolerate cold starts.
- Poor fit: applications with heavy database connection use, unless a connection pooler or proxy such as RDS Proxy sits between the function and the database.
- Consider containers instead: when the code needs more than the function timeout, a large dependency set, or a runtime the platform does not offer. Cloud Run, AWS Fargate, and Azure Container Apps keep most of the operational simplicity.
Security hygiene for functions
Every function runs under an identity, and the default identities are often broader than the function needs. Give each function its own execution role, service account, or managed identity with permissions limited to the resources it touches. Pull secrets at runtime from AWS Secrets Manager, Google Secret Manager, or Azure Key Vault rather than baking them into environment variables that appear in the console and in deployment packages. Keep the HTTP entry point behind authentication unless it is intentionally public, and put a rate limit on public endpoints because a function that scales without limit can also bill without limit. Set a concurrency cap and a budget alert before the first production deploy.
Where to go next
Functions are available on every hyperscaler account, and a quota increase is the usual first request as traffic grows. The marketplace lists AWS accounts for Lambda, Google Cloud accounts for Cloud Run functions, and Azure accounts for Azure Functions, with the exact variant labels on each product page.
For the identity model that function permissions depend on, read IAM basics across providers. If your workload turns out to need containers rather than functions, managed Kubernetes compared covers the next step up. The Cloud Library hub lists every developer workflow guide.