Lambda Function URLs for single-function endpoints such as webhooks and internal tools, API Gateway HTTP APIs for most public serverless APIs, REST APIs when access is contractual (usage plans, API keys, WAF), and an ALB once traffic is steady enough that per-request billing loses to an hourly cost. Raw capability is rarely the differentiator: all four can put HTTPS in front of Lambda. The real differences are auth options, throttling, WAF support and cost shape.
When is a Lambda Function URL enough?
A Function URL is enough when a single Lambda function serves the whole endpoint and its callers can authenticate with AWS IAM, or need no authentication at all. The URL itself costs nothing: you only pay the Lambda invocation. In exchange you give up throttling, quotas, WAF attachment and custom domains.
A Function URL is an HTTPS endpoint bolted directly onto one function, with response streaming support and none of API Gateway's routing layer (see the Lambda documentation). That absence cuts both ways: nothing to configure, but also nothing between the internet and your function. A public URL with auth set to NONE lets anyone drive your invocations and concurrency, and reserved concurrency is the only brake. Keep unauthenticated URLs for webhooks that verify signatures in code, and prefer AWS_IAM for service-to-service calls.
What does an API Gateway HTTP API add on top?
An HTTP API adds a real front door: routes across many functions, JWT authorizers for Cognito or any OIDC issuer, per-route throttling, custom domains and stages. Its cost shape is purely per-request, so a spiky or low-traffic API costs close to nothing when idle.
That per-request shape is the point (the tiers are detailed on the official pricing page). There is no hourly floor and no capacity planning, and the JWT authorizer rejects bad tokens before your code runs, so you do not pay Lambda for unauthenticated noise. Throttling applies per stage or per route, which is enough to protect a backend, but there are no API keys, no usage plans and no direct WAF attachment. For most public serverless APIs in 2026, this is the default we reach for.
When do you still need the REST API flavor?
Choose a REST API when access is contractual: usage plans meter and throttle each API key, request validation rejects malformed payloads before invocation, AWS WAF attaches directly to a stage, and private endpoints keep the API inside a VPC. You accept a higher per-request rate for that management layer.
Commercially, usage plans are the feature that matters. Per-client quotas and throttles are the mechanical basis of partner tiers, and we covered how to turn them into contractual commitments in our guide to partner API SLA design. Request validation and WAF move cheap rejections out of your code. AWS maintains a feature-by-feature comparison of the two flavors: read it before assuming you need REST, because many teams only need JWT auth and throttling.
Hesitating between per-request and hourly cost shapes for your API? Describe your system: a one-page diagnosis within 48 hours.
Get my diagnosis →When does an ALB beat API Gateway?
An ALB wins when traffic is steady and high, or when Lambda sits next to containers and instances in one VPC. Its cost shape combines an hourly charge with capacity units (LCUs), so request volume does not multiply the bill the way per-request pricing does.
The trade-off is symmetrical. At low volume the ALB idles at its hourly floor while an HTTP API costs pennies; past a sustained request rate the curves cross and the ALB gets cheaper, so model both shapes against your real traffic (see the ELB pricing page). An ALB routes one hostname to Lambda targets and VPC targets alike, supports WAF directly, and authenticates users via OIDC or Cognito at the balancer. It has no throttling, quotas or API keys, and responses from Lambda targets are capped at 1 MB at the time of writing.
How do the four options compare?
The table below compares auth, throttling, WAF support and cost shape. Read the last column first: each option has a traffic and security profile where it clearly wins, and the wrong pick usually shows up either as an oversized bill or as a missing protection you end up rebuilding by hand.
| Option | Auth options | Throttling and quotas | WAF | Cost shape | When it wins |
|---|---|---|---|---|---|
| Function URL | AWS_IAM or none | None (reserved concurrency only) | No (only via CloudFront) | Free, pay Lambda only | Single-function webhooks, internal endpoints |
| HTTP API | JWT, IAM, Lambda authorizer | Per-stage and per-route throttling, no keys or quotas | No direct attachment | Low per-request | Public serverless APIs, spiky or modest traffic |
| REST API | IAM, Cognito, Lambda authorizer, API keys | Throttling plus usage plans and quotas | Yes, direct | Higher per-request | Partner and monetized APIs, private endpoints |
| ALB | OIDC or Cognito at the balancer | None | Yes, direct | Hourly plus capacity units | Steady high volume, mixed Lambda and VPC targets |
Should you put CloudFront in front of a Function URL?
Yes, when you like the free Function URL but miss a custom domain, caching or WAF. CloudFront provides all three: attach WAF to the distribution, point it at the URL, and lock the origin down with origin access control (OAC) so callers cannot bypass the edge.
With OAC, CloudFront signs origin requests with IAM and the Function URL stays on AWS_IAM auth, so the only path in runs through the distribution. This setup covers a surprising share of HTTP API use cases at a different cost shape. Know when to stop, though: the moment you need per-client quotas, API keys or request validation, you are rebuilding API Gateway by hand. Choosing and wiring this edge layer is part of our API development work.
Decision checklist
Run through these in order and stop at the first match:
- One function, IAM or signature-verified callers: Function URL.
- Public API, spiky or modest traffic, OIDC tokens: HTTP API.
- Contractual or paying consumers, keys, quotas, WAF, private endpoints: REST API.
- Steady high volume, or Lambda mixed with VPC targets: ALB.
- Free origin but custom domain, caching or WAF needed: CloudFront plus Function URL with OAC.
- Crossover unclear: model a month of real traffic against the per-request and hourly shapes before committing.