API Gateway vs ALB: Choosing What Sits in Front of Lambda

5 min read

Once you build an API on Lambda, the next question is what goes in front: API Gateway, an ALB, or a bare Function URL. The conclusion up front: low or variable traffic goes to the per-request-priced API Gateway HTTP API; sustained heavy traffic, or any setup that already has an ALB, goes to the fixed-cost ALB; and single-function webhooks that handle their own auth go to the free Function URL. Because the pricing models split into per-request and per-hour, knowing your monthly request count settles most of the decision. The ALB itself is covered in ALB vs NLB. Prices are for us-east-1.

Side-by-side comparison #

AspectHTTP APIREST APIALBFunction URL
Pricing modelPer requestPer requestHourly + LCUFree (Lambda charges only)
Rate~$1.00 per million~$3.50 per million~$16/month + $0.008 per LCU-hourNone
Idle cost00From ~$16/month0
AuthJWT, IAM, Lambda authorizerIAM, Cognito, API keys, Lambda authorizerOIDC, CognitoIAM or none
Usage plans and API keysNoYesNoNo
Response cachingNoStage cacheNoNo
WAF attachmentNo (needs CloudFront in front)YesYesNo
Mixing VPC targetsVia VPC LinkVia VPC LinkNative (route to EC2 and ECS too)No

Pricing models: the crossover sits near 16 million requests #

The HTTP API is pure per-request billing at about $1.00 per million. No traffic, no cost; a spike bills exactly the requests it brings. An ALB is the opposite: about $16 a month (at $0.0225/hour) just for existing, plus LCU charges ($0.008 per LCU-hour) that scale with load.

Setting fixed against variable cost, the ALB’s base fee of about $16 equals 16 million HTTP API requests. Below a few million requests a month, the HTTP API wins clearly; in the tens of millions and beyond, the ALB’s fixed-cost structure takes over. At 100 million requests a month, the HTTP API bills about $100 while an ALB, LCUs included, often stays in the tens of dollars. One caveat: LCUs are computed from the maximum of new connections, active connections, processed bytes, and rule evaluations, so workloads with large responses or many connections need the LCU math checked separately.

The REST API costs 3.5 times the HTTP API. What that buys is features: API keys with usage plans (per-customer quotas and throttling), stage caching, request and response transformation, and direct WAF attachment exist only on the REST API. If you sell your API as a product to external customers, the premium is the price of those features; for internal service APIs you will not use them, and the HTTP API is the default.

The Function URL attaches an HTTPS endpoint to a function for free. Auth is IAM or nothing, and there are no custom domains, throttling, or WAF, which makes it right for single-function endpoints with a known caller, such as receiving GitHub webhooks. As the front door of a public API it simply lacks protection.

The decision factors beyond price #

Is there already an ALB? If ECS or EC2 services are running behind one, adding a Lambda target group with a path rule is the cheapest and simplest move. The fixed cost is already being paid, so the marginal cost of the Lambda path is just the LCU increase, and domains and certificates stay managed in one place. Migrating gradually between containers and Lambda, shifting traffic rule by rule, is another thing this setup does well.

Where does auth happen? If JWT validation is all you need, the HTTP API’s JWT authorizer is configuration-only and the simplest option. An ALB can also handle OIDC at the listener. Cognito user pools, custom authorizers, and API key distribution point to the API Gateway family.

Do you need limits and protection? Throttling is a built-in of the API Gateway family; an ALB has no request limiting of its own and relies on WAF rate-based rules. The HTTP API has the opposite hole: it cannot take WAF directly, so if WAF is mandatory, the options are REST API, ALB, or CloudFront layered in front.

Timeouts differ too. API Gateway’s integration timeout is 29 seconds, which rules out long requests. An ALB allows longer idle timeouts, though details like response size limits for Lambda targets need checking on both. Cold starts eat into the timeout budget as well; remedies are in the previous post.

Decision order #

  1. Is it a webhook with a single caller? Then a Function URL ends the discussion: free, nothing to manage.
  2. Pick the pricing model from monthly volume: a few million requests or less, or highly variable, means HTTP API; sustained tens of millions means pricing out the ALB.
  3. Check for an existing ALB: if one is there, a Lambda target group is the minimum marginal cost. Creating a new ALB is justified only when traffic covers its fixed cost.
  4. Upgrade to REST API for keys, usage plans, or caching: the external customer-facing API product is the typical case. If an internal API is on REST API today, moving it down to HTTP API is an easy saving.
  5. Verify WAF and throttling requirements last: needing WAF on an HTTP API forces a structural change (CloudFront on top, or a switch to REST API or ALB), so confirm it before locking the architecture.

Summary #

  • The pricing model is the substance: HTTP API is variable cost at ~$1.00 per million requests, ALB is fixed cost at ~$16 a month plus LCUs, and the crossover sits near 16 million requests a month.
  • The default for internal APIs is the HTTP API. The REST API’s 3.5x premium pays for API keys, usage plans, caching, and direct WAF, and only makes sense when those are needed.
  • With an ALB already in place, a Lambda target group is the cheapest option and mixes containers and functions under one domain.
  • The Function URL is free but IAM-auth-only, which limits it to known-caller webhooks rather than public fronts.
  • The three late-discovered constraints: the 29-second timeout, WAF attachability, and the LCU math. Check them before the architecture is fixed.
X