Serverless on AWS vs Azure: The Real Differences

Most serverless comparisons stop at the marketing layer: Lambda versus Functions, API Gateway versus API Management. The differences that change how you actually build something only surface once you have deployed on both platforms. Here they are, mapped directly.

The core services

AWS Azure Equivalent?
Lambda Function App Not quite (see below)
API Gateway API Management / Function App routing Depends on scale
Cognito Entra ID (Azure AD) Yes, broadly
S3 Blob Storage Yes
RDS (Postgres) Azure Database for PostgreSQL Flexible Server Yes
SQS Storage Queues Yes
Step Functions Logic Apps Loosely

Most of that table is a fair trade. The first row carries the weight, and it’s the row that catches migrations out.

Lambda vs Function App

AWS Lambda treats each function as an independent unit: one function, one deployment, one ARN. Azure Functions work differently. A Function App is a container for several related functions, sharing a runtime, a host process, and a deployment unit.

The naming looks trivial. The architecture underneath it isn’t. Migrate a set of Lambdas by creating one Function App per Lambda and you end up fighting Azure’s deployment model at every step: provisioning overhead per function, cold-start multiplication, an infrastructure layer that assumes grouping and gets none. The fix is to group related endpoints (search, chat, ingest, whatever the domain boundaries are) into a small number of Function Apps, each exposing several routes.

One project migrating around two dozen Lambdas built two dozen separate Function Apps first, then consolidated down to a handful once the mismatch surfaced. Twice the infrastructure work, for one architectural assumption carried over from the wrong platform.

Auth: Cognito vs Entra ID

This is a clean swap, provided the migration uses MSAL rather than mapping Cognito concepts onto Entra ID directly. The practical shifts:

Storage

S3 to Blob Storage is close to a drop-in swap at the API level. Buckets become containers, keys become blob names, and the SDK change (boto3 to azure-storage-blob) is mechanical rather than conceptual. This is the part of the migration that behaves as advertised.

Database

Postgres with pgvector on RDS moves to Azure Database for PostgreSQL Flexible Server on close to a connection-string change. pg_dump/pg_restore cross the boundary without drama, provided the target extensions (pgvector, uuid-ossp, whichever the project uses) exist before the restore runs.

The effort curve

Plot actual migration effort against the marketing comparison and the picture is uneven. Storage and database are close to free. Auth is a moderate, well-trodden path. Compute (the part everyone assumes is easy, because “it’s serverless either way”) is where the architectural rework lives.

Scope a serverless migration with that curve in mind. The services that sound the same are not always structured the same, and the row that reads like a rename is usually the one that costs the most. (Migrating and want a second opinion on the Function App boundaries before you build them? Get in touch.)


Questions about this? Get in touch.