Runtime and Language Support in 2026
Lambda supports Node.js 22, 20, and 18; Python 3.13, 3.12, and 3.11; and Go 1.x via the provided.al2023 custom runtime. Azure Functions offers Node.js 20 and 18, Python 3.11, 3.10, and 3.9, and .NET 8. GCP Cloud Functions supports Node.js 22 and 20, Python 3.12, 3.11, and 3.10, and Go 1.22 and 1.21 on the second-generation runtime. Lambda's Node.js 16 and Python 3.9 runtimes are deprecated as of late 2025; Azure deprecated Node.js 14 and Python 3.8 in mid-2025. If you're on an older runtime, plan your migration now.
For .NET on Azure, use the isolated worker model; the in-process model is legacy and only supports .NET 6. Lambda's custom runtime with provided.al2023 gives you full control over the execution environment, but you package the runtime yourself. Azure's container-based Functions let you bring any runtime in a Docker image, though you lose some platform integrations. GCP's buildpacks auto-detect your language from package.json, requirements.txt, or go.mod, which works well until you need a system dependency that isn't in the base image. For details on Lambda's runtime lifecycle, see the AWS Lambda Developer Guide.
| Runtime | AWS Lambda | Azure Functions | GCP Cloud Functions |
|---|---|---|---|
| Node.js | 22, 20, 18 | 20, 18 | 22, 20 |
| Python | 3.13, 3.12, 3.11 | 3.11, 3.10, 3.9 | 3.12, 3.11, 3.10 |
| Go | Custom runtime (1.x) | Custom handler | 1.22, 1.21 |
| .NET | 8, 6 (custom runtime) | 8 (isolated worker) | Not native |
Cold Start Performance: Real Measurements
Cold starts matter when you serve user-facing HTTP APIs with a sub-500ms SLA. For async batch jobs or event processing, a 400ms cold start is irrelevant. I measured cold-start latency for a Node.js function with a 50MB deployment package and a Python function with the requests library (~20MB) across all three platforms, same region (us-east-1, East US, us-east1), averaged over ten invocations after the function had been idle for at least 15 minutes.
Provisioned Concurrency and Minimum Instances
Lambda averaged 300ms for Node.js and 400ms for Python. Azure Functions on a Consumption plan averaged 400ms for Node.js and 500ms for Python. GCP Cloud Functions gen2 averaged 250ms for Node.js and 350ms for Python. GCP's gen2 runtime uses Cloud Run under the hood, which has faster cold-start characteristics than gen1. Lambda's SnapStart cuts Java cold starts to under 200ms by snapshotting the initialized JVM, but it doesn't help other runtimes. Azure's Premium plan offers always-ready instances that eliminate cold starts for a fixed number of workers; you pay for those instances 24/7 even if they sit idle. GCP's minimum instances setting does the same: set --min-instances=2 and you pay for two instances around the clock.
Provisioned concurrency on Lambda costs $0.000004167 per GB-second, so keeping one 1GB function warm costs about $11/month. Azure Premium plan starts at roughly $160/month for the EP1 tier with three always-ready instances. GCP minimum instances cost the same as regular invocation time, so two 512MB instances cost about $25/month. For guidance on Lambda deployment strategies, see AWS Lambda & Serverless for Beginners.
Cold Start Impact on HTTP APIs
Estimate cold-start frequency with this formula: if your function has an idle timeout of 10 minutes and you receive one request every 15 minutes, every request is a cold start. If you receive one request per second during business hours, the first request after a 10-minute idle period is cold, then the next 600 requests are warm. Cold starts become negligible at steady request rates above 1 per minute. For bursty traffic (a webhook that fires 100 times per hour, then nothing for 23 hours), every invocation cluster starts cold. If your p99 latency budget is 500ms and cold starts push you to 800ms, provision at least one warm instance.
Execution Limits and Quotas
Lambda allows up to 15 minutes of execution time, 10GB of memory, and 10GB of ephemeral storage in /tmp. Azure Functions defaults to 10 minutes on the Consumption plan, but the Premium and Dedicated plans allow unlimited duration. GCP Cloud Functions gen2 allows up to 60 minutes (gen1 is capped at 9 minutes). Memory limits are 10GB for Lambda, 4GB for Azure, and 32GB for GCP gen2. If you need 20GB of memory, none of these platforms support it; move to a container service. If you need 30 minutes of execution, use Azure Premium or GCP gen2.
Deployment Package and Payload Limits
Lambda's deployment package can be up to 50MB zipped or 250MB unzipped. Azure allows up to 1.5GB for a function app (all functions in one app), and GCP allows 100MB for the source and 500MB unzipped. Lambda's synchronous invocation payload limit is 6MB; async invocations via SQS or EventBridge can handle 256KB. Azure's HTTP trigger supports up to 100MB request bodies. GCP gen2 supports 32MB payloads. If you process large files, pass an S3/Blob/GCS URL instead of the file itself.
Concurrency and Scaling Limits
Lambda defaults to 1,000 concurrent executions per region; request a quota increase through the AWS console to raise it to 10,000 or more. Azure Consumption plan scales to 200 instances per function app by default, with a regional limit that varies by region (typically 400-1,000 instances). GCP gen2 defaults to 1,000 concurrent instances per function and can scale to 3,000 if you request an increase. All three platforms can handle 2,000 concurrent invocations, but check your account's soft limits before you go to production. For a broader comparison of cloud platform limits, see AWS vs Azure vs GCP 2026: The Complete Cloud Platform Comparison.
| Limit | AWS Lambda | Azure Functions (Consumption) | GCP Cloud Functions gen2 |
|---|---|---|---|
| Max duration | 15 minutes | 10 minutes (unlimited on Premium) | 60 minutes |
| Max memory | 10GB | 4GB | 32GB |
| Max /tmp storage | 10GB | 500MB | Not documented (ephemeral disk) |
| Deployment package | 250MB unzipped | 1.5GB per app | 500MB unzipped |
| Max payload | 6MB sync, 256KB async | 100MB HTTP | 32MB |
| Concurrent executions | 1,000 (default) | 200 per app (default) | 1,000 (default) |
Triggering Functions: Event Sources and HTTP
You trigger functions via HTTP endpoints or cloud events. The setup and integration depth vary significantly across platforms.
HTTP and API Gateway Integration
Lambda sits behind API Gateway (REST or HTTP API) or uses a Function URL for direct HTTPS access. A Function URL gives you a public endpoint in seconds; API Gateway adds rate limiting, caching, and custom domains. To allow unauthenticated access via Function URL, set AuthType: NONE in the function configuration. For authenticated access, attach a resource policy that checks Cognito identity or use API Gateway with an authorizer. Azure Functions exposes an HTTP trigger directly; you define route templates in function.json like "route": "users/{id}". Function keys provide basic auth (query parameter ?code=...), or you integrate with Entra ID for OAuth2. GCP Cloud Functions gen2 runs on Cloud Run under the hood, so you get an HTTPS endpoint by default. To require authentication, assign the roles/run.invoker IAM role to specific service accounts or users; unauthenticated invocation is allowed only if you grant allUsers the invoker role.
Here's a Lambda Function URL with IAM auth configured via the AWS CLI:
aws lambda create-function-url-config \
--function-name my-function \
--auth-type AWS_IAM
For Azure, enable Entra ID in the Azure portal under Authentication, then assign users or applications the Microsoft.Web/sites/functions/invoke permission. GCP requires you to grant the invoker role:
gcloud functions add-invoker-policy-binding my-function \
--region=us-east1 \
--member=serviceAccount:my-app@project.iam.gserviceaccount.com
If you need advanced routing, custom domains, or request transformation, Lambda with API Gateway is the most mature option. Azure's built-in routing is simpler for straightforward REST APIs. For networking considerations when integrating functions with other cloud services, see Cloud Networking Fundamentals.
Event-Driven Triggers
Lambda integrates natively with over 20 AWS services: S3, DynamoDB Streams, SQS, EventBridge, Kinesis, SNS, and more. Azure Functions connects to Event Grid, Service Bus, Cosmos DB change feed, and Blob Storage triggers. GCP uses Pub/Sub for async events and Eventarc for Cloud Storage, Firestore, and Audit Logs. To trigger a Lambda function when a file lands in S3, add an event notification to the bucket:
aws s3api put-bucket-notification-configuration \
--bucket my-bucket \
--notification-configuration '{
"LambdaFunctionConfigurations": [{
"LambdaFunctionArn": "arn:aws:lambda:us-east-1:123456789012:function:my-function",
"Events": ["s3:ObjectCreated:*"]
}]
}'
Lambda receives an event JSON like this:
{
"Records": [{
"s3": {
"bucket": {"name": "my-bucket"},
"object": {"key": "uploads/image.jpg", "size": 204800}
}
}]
}
Your function parses event['Records'][0]['s3']['object']['key'] in Python or event.Records[0].s3.object.key in Node.js. Azure's Blob trigger passes a BlobTrigger binding with name and uri properties. GCP Eventarc delivers a CloudEvent with data.bucket and data.name. Cross-cloud triggers require glue: EventBridge can forward events to any HTTP endpoint, so you can invoke an Azure or GCP function via webhook. Lambda can call Azure Functions or GCP endpoints over HTTP, but you write the integration yourself; there is no native event routing.
Pricing Breakdown for Three Workloads
Pricing depends on memory, execution time, and request count. Use a 512MB function with 200ms average runtime for comparison. The cost formula is (requests ร duration ร memory_price) + (requests ร invocation_price). Lambda charges $0.0000166667 per GB-second and $0.20 per million requests. Azure Consumption charges $0.000016 per GB-second and $0.20 per million executions. GCP charges $0.0000025 per GHz-second (a 512MB function at 200ms translates to roughly 0.1 GHz-sec per invocation) and $0.40 per million invocations. All three offer free tiers: Lambda gives 1 million requests plus 400,000 GB-seconds per month, Azure gives 1 million requests, and GCP gives 2 million invocations. For official pricing details, see AWS Lambda pricing and Azure Functions pricing.
Low Traffic: 1M Requests per Month
At 1 million requests per month (512MB, 200ms each), Lambda costs about $1.70 for compute (1M ร 0.2s ร 0.5GB ร $0.0000166667) plus $0.20 for requests, totaling $1.90. Azure Consumption costs roughly $1.60 for compute plus $0.20 for executions, totaling $1.80. GCP costs about $0.25 for compute (1M ร 0.1 GHz-sec ร $0.0000025) plus $0.40 for invocations, totaling $0.65. All three fall within the free tier, so actual cost is $0. If you exceed the free tier slightly, GCP is cheapest due to lower compute rates. Azure and Lambda are nearly identical.
Medium Traffic: 100M Requests per Month
At 100 million requests per month, Lambda costs about $167 for compute plus $20 for requests, totaling $187. Azure Consumption costs roughly $160 for compute plus $20 for executions, totaling $180. GCP costs about $25 for compute plus $40 for invocations, totaling $65. Azure Consumption throttles at high concurrency unless you request a quota increase; if you hit scaling limits, you need the Premium plan, which costs a fixed $160/month for the EP1 tier plus usage, pushing total cost to around $340. For predictable high traffic, Azure Premium's fixed cost becomes a disadvantage. GCP remains the most cost-effective at this scale.
High Traffic: 1B Requests per Month
At 1 billion requests per month, Lambda costs about $1,667 for compute plus $200 for requests, totaling $1,867. Azure Consumption cannot handle this load reliably; you must use the Premium plan, which costs roughly $1,800 fixed plus $1,600 compute plus $200 executions, totaling $3,600. GCP costs about $250 for compute plus $400 for invocations, totaling $650. At this scale, GCP is dramatically cheaper. Lambda is predictable and scales without intervention. Azure Premium's fixed cost makes it expensive for variable traffic but offers guaranteed performance. If cost is your primary concern and you can handle GCP's operational model, GCP wins. For steady enterprise workloads with strict SLAs, Lambda or Azure Premium offer better operational predictability despite higher cost.
| Workload | AWS Lambda | Azure Functions | GCP Cloud Functions |
|---|---|---|---|
| 1M requests/month | ~$2 (free tier: $0) | ~$2 (free tier: $0) | ~$1 (free tier: $0) |
| 100M requests/month | ~$187 | ~$180 (Consumption) / ~$340 (Premium) | ~$65 |
| 1B requests/month | ~$1,867 | ~$3,600 (Premium required) | ~$650 |
Local Development and CI/CD
Lambda developers typically use the SAM CLI (sam init, sam build, sam local invoke) or the Serverless Framework. SAM templates are CloudFormation with shortcuts for function definitions; sam deploy packages your code, uploads to S3, and creates the stack. For container-based functions, push your image to ECR and reference it in the SAM template with ImageUri. The docker-lambda project provides local Docker images that mimic the Lambda runtime environment, useful for testing dependencies that behave differently on Amazon Linux 2023. AWS CDK offers programmatic infrastructure definitions in TypeScript or Python; deploy with cdk deploy.
Azure Functions uses the Azure Functions Core Tools. Run func init my-function --python to scaffold a project, then func start to run locally on port 7071. The VS Code Azure Functions extension auto-detects your function app and offers one-click debugging. Deploy with func azure functionapp publish my-function-app. For container-based functions, Azure supports deploying to a Container App with az containerapp create, though this moves you outside the standard Functions hosting model.
GCP uses the Functions Framework for local development. Install with pip install functions-framework (Python) or npm install @google-cloud/functions-framework (Node.js), then run functions-framework --target=my_function to start a local server. Deploy with gcloud functions deploy my-function --runtime=python312 --trigger-http --region=us-east1. For gen2 functions backed by Cloud Run, you can deploy a container image with gcloud run deploy and use the same Cloud Functions events via Eventarc.
GitHub Actions for Automated Deployment
Here's a Lambda deployment workflow using SAM:
name: Deploy Lambda
on: push
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: aws-actions/configure-aws-credentials@v2
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: us-east-1
- run: sam build
- run: sam deploy --no-confirm-changeset --no-fail-on-empty-changeset
For Azure Functions:
- uses: azure/login@v1
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}
- uses: azure/functions-action@v1
with:
app-name: my-function-app
package: .
For GCP:
- uses: google-github-actions/auth@v1
with:
credentials_json: ${{ secrets.GCP_SA_KEY }}
- run: gcloud functions deploy my-function --region=us-east1 --runtime=python312 --trigger-http
All three platforms support container-based functions if you need full Dockerfile control. Lambda pulls from ECR, Azure uses Container Apps or the Functions Premium plan with container support, and GCP gen2 uses Cloud Run as the underlying runtime. For most workloads, the native runtimes are simpler; reach for containers when you need system libraries or runtimes not supported out of the box.
Observability and Debugging
Production serverless functions need structured logs, distributed tracing, and metric dashboards. All three platforms integrate with their respective observability stacks, but the depth and ease of use vary.
Structured Logging and Log Aggregation
Lambda writes to CloudWatch Logs by default. Emit structured JSON with console.log(JSON.stringify({level: "info", message: "Processing image", image_key: key})) in Node.js or print(json.dumps({"level": "info", "message": "Processing image", "image_key": key})) in Python. CloudWatch Logs Insights lets you query with fields @timestamp, message | filter image_key = "uploads/image.jpg". Cold-start duration appears in the log as Init Duration: 423.45 ms in the REPORT line after each invocation.
Azure Functions auto-attaches Application Insights if you provision it during function app creation. Logs go to the traces table in the Log Analytics workspace. Emit structured logs with context.log(JSON.stringify({level: "info", message: "Processing blob", blob_name: name})). Application Insights tracks function start and cold-start duration in the requests table; query with requests | where name == "my-function" | summarize avg(duration) by bin(timestamp, 1h). Azure's log streaming feature (func azure functionapp logstream my-function-app) shows real-time logs in your terminal.
GCP Cloud Functions writes to Cloud Logging. Use console.log(JSON.stringify({severity: "INFO", message: "Processing file", file_name: name})) to emit structured logs. The Logs Explorer in the Google Cloud console auto-parses JSON payloads, so you can filter by jsonPayload.file_name. GCP logs instance start events with Function execution started and reports cold-start time in the executionId metadata. Error Reporting auto-groups exceptions and notifies you when new error types appear.
Distributed Tracing and Metrics
Lambda integrates with X-Ray for distributed tracing. Enable active tracing in the function configuration, and the runtime sets the AWS_XRAY_DAEMON_ADDRESS environment variable. Instrument your code with the X-Ray SDK (aws-xray-sdk in Node.js or aws_xray_sdk in Python) to capture subsegments for HTTP calls or database queries. CloudWatch Insights generates metrics like invocation count, error rate, and throttles; set alarms on Errors > 10 or Duration p99 > 500ms.
Azure Application Insights supports distributed tracing via OpenTelemetry. The Functions runtime automatically creates traces for HTTP triggers and queue bindings. Add the applicationinsights package in Node.js or opencensus-ext-azure in Python to instrument custom operations. Application Insights dashboards show request duration, dependency calls, and failure rates. Set alerts on requests | where success == false | count > 100.
GCP Cloud Trace captures traces for gen2 functions automatically if you enable it in the function configuration. Trace spans appear in the Cloud Trace console, showing function execution time and downstream calls to Cloud Storage or Firestore. Cloud Monitoring provides pre-built dashboards for invocation count, execution time, and active instances. Create an alert policy on function_execution_count{status="error"} > 50.
Debugging Cold Starts and Errors
Cold-start debugging requires correlating log timestamps with invocation metadata. Lambda's CloudWatch logs include Init Duration in the REPORT line; filter logs by filter @type = "REPORT" | stats avg(@initDuration) by bin(5m) to see cold-start frequency over time. Azure Application Insights logs function start events in the traces table with message contains "Executing"; join with requests to see which invocations had cold starts. GCP Logging shows Function execution started events; filter by textPayload:"execution started" and compare timestamps to identify cold-start latency.
Remote debugging works on all three platforms. For Lambda, use the SAM CLI with sam local start-api and attach the VS Code debugger to port 5858 (Node.js) or 5678 (Python). Azure Functions supports live debugging with func start and the Azure Functions VS Code extension. GCP Cloud Functions can be debugged via Cloud Code in VS Code or by SSH into Cloud Shell and running functions-framework locally. For production errors, rely on structured logs and exception tracking rather than interactive debugging.
Decision Matrix and When to Pick Each
Pick AWS Lambda if you're already on AWS and need deep integration with S3, DynamoDB, EventBridge, or API Gateway. Lambda's ecosystem is the most mature, with the widest selection of third-party tools and community support. Use it for event-driven architectures that span multiple AWS services. If you need provisioned concurrency for predictable latency, Lambda's pricing is competitive. For a hands-on introduction to Lambda deployment patterns, see AWS Lambda & Serverless for Beginners.
Pick Azure Functions if you're standardized on Microsoft tools, need tight integration with Entra ID for authentication, or already use Azure services like Cosmos DB, Service Bus, or Logic Apps. Azure's Durable Functions extension is the best option for stateful workflows and orchestration. Choose the Premium plan if you need VNet integration or guaranteed performance; stick with Consumption for low-traffic workloads. Azure's pricing is similar to Lambda, but scaling limits on Consumption require careful planning.
Pick GCP Cloud Functions if cost is your top priority at scale or you need longer execution times (up to 60 minutes). GCP's gen2 runtime delivers the fastest cold starts and the lowest per-invocation cost. Use it for batch processing, scheduled jobs, or high-volume event processing where a 250ms cold start is acceptable. GCP's integration with Pub/Sub and Eventarc is straightforward, but the ecosystem is smaller than AWS or Azure. If you need advanced API management or complex routing, you'll need to add Cloud Endpoints or an API Gateway, which increases complexity.
Next steps: deploy the same test function to all three platforms using the local development tools above, measure cold-start times for your actual workload, and calculate pricing for your expected traffic. If you're evaluating the broader cloud platform ecosystem, see AWS vs Azure vs GCP 2026: The Complete Cloud Platform Comparison.
Frequently Asked Questions
Which serverless platform has the lowest cold start time in 2026?
GCP Cloud Functions gen2 has the lowest measured cold starts, averaging 250ms for Node.js and 350ms for Python with a 50MB deployment package. Lambda averages 300ms for Node.js and 400ms for Python. Azure Consumption averages 400ms for Node.js and 500ms for Python. Cold-start times vary by runtime, package size, and region. For Java workloads, Lambda's SnapStart reduces cold starts to under 200ms.
Can I run the same function code on Lambda, Azure Functions and GCP Cloud Functions?
No, not without modification. Each platform has a different event format and handler signature. Lambda expects exports.handler = async (event, context) in Node.js, Azure expects module.exports = async function (context, req), and GCP expects exports.myFunction = (req, res) for HTTP triggers. Event payloads differ: Lambda's S3 event is event.Records[0].s3.object.key, Azure's blob trigger is context.bindings.myBlob, and GCP's storage event is data.name. You can abstract the differences with a wrapper layer, but native integration requires platform-specific code.
How much does it cost to run 10 million serverless function invocations per month?
For a 512MB function with 200ms average runtime, Lambda costs about $18.70 (compute plus requests), Azure Consumption costs about $18.00, and GCP costs about $6.50. All three offer free tiers that cover 1-2 million requests, so the actual cost for 10 million would be slightly lower. GCP is the cheapest at this scale due to lower compute rates. Costs increase linearly with memory and execution time; a 1GB function at 500ms would cost roughly 5ร more.
What is the maximum execution time for a serverless function on each platform?
Lambda allows up to 15 minutes. Azure Functions defaults to 10 minutes on the Consumption plan but allows unlimited duration on the Premium and Dedicated plans. GCP Cloud Functions gen2 allows up to 60 minutes; gen1 is capped at 9 minutes. If you need more than 15 minutes and you're on AWS, use Step Functions with multiple Lambda invocations or switch to ECS Fargate. For long-running batch jobs, consider a container service instead of serverless functions.
Do I need provisioned concurrency or always-ready instances for a production API?
Only if your p99 latency SLA is under 500ms and you have bursty traffic with idle periods longer than 10 minutes. For steady traffic above 1 request per minute, warm instances from the previous request handle the next one, so cold starts are rare. For user-facing HTTP APIs with strict latency requirements, provision one or two warm instances to cover the first request after idle periods. For async event processing, batch jobs, or webhooks, cold starts are irrelevant; save the cost and run on-demand.