TL;DR: A Function URL gives any Lambda a direct HTTPS endpoint — https://<id>.lambda-url.<region>.on.aws/ — with zero routing cost and 10–30 ms less latency than going through API Gateway. For webhook receivers, internal service-to-service calls, and single-endpoint backends that never used gateway features, API Gateway is a paid hop doing nothing. The cargo-cult habit of "gateway in front of every Lambda" is the whole reason this sheet exists.
The numbers
- Routing cost: Function URL $0 vs HTTP API $1.00/M requests vs REST $3.50/M vs ALB's fixed ~$16+/month regardless of traffic
- 100M requests/month → $100/month of pure routing tax removed (1B → $1,000/month); Lambda compute is identical either way
- Field examples: 30 webhook receivers migrated in an afternoon ($600/year + ~15 ms faster + one less service in the debugging path); an internal 8-service mesh dropped $200/month of API Gateway spend on traffic that never left AWS, with 20–25 ms lower inter-service latency
- Response streaming supported — lower time-to-first-byte for big responses and AI output, same cost
Do this
-
Find the "dumb proxy" endpoints: API Gateway APIs with one route to one Lambda — webhook receivers (Stripe/GitHub/Slack/Twilio), internal callbacks, single-endpoint app backends, IoT ingestion. Those use no gateway feature you'd miss.
-
Enable the URL (console: Configuration → Function URL, or two lines of SAM):
FunctionUrlConfig: AuthType: NONE # or AWS_IAM -
Pick auth deliberately:
AWS_IAM(SigV4) for internal service-to-service via execution roles;NONEfor third-party webhooks — then validate the provider's signature in code, which you should be doing behind API Gateway anyway. -
Configure CORS on the URL itself for browser SPAs — allowed origins/methods/headers are native settings, no OPTIONS-route wiring.
-
Migrate incrementally: default every new simple endpoint to a Function URL; move existing ones opportunistically. No big-bang required.
-
Add the missing safety net: without gateway throttling, CloudWatch alarms on Lambda errors and concurrency matter more — set them as part of each migration.
Gotchas
- No throttling, usage plans, API keys, VTL, WebSockets, or native custom domains. Any of those being load-bearing keeps that endpoint on API Gateway — and that's fine.
- Custom domain or DDoS shielding wanted? CloudFront in front of a Function URL adds domains, WAF, and caching — still usually cheaper than REST.
NONEauth is public to anyone with the URL — exactly like a default API Gateway endpoint; the security is your signature/token validation, not obscurity.- ALB remains competitive only at high steady volume where its fixed cost amortizes; spiky/low traffic favors URLs decisively.
Skip this if
- The API is a real multi-route product API with per-consumer throttling, keys, or transformation needs — that's gateway work.
- You need WebSockets — API Gateway only.
- Traffic is enormous and you already negotiated gateway pricing — run the math; free routing still usually wins, but migration effort counts.