Serverless cost optimization comes down to three variables: invocations, duration, and memory. Every platform bills for these same things. Cold starts alone add 200 to 1,500 milliseconds of billed duration per request, and costs scale linearly with traffic. This tutorial gives you concrete techniques to cut each cost component with real numbers from Vercel, Cloudflare Workers, and AWS Lambda.
The Three Things You Actually Pay For
Every serverless bill is a simple equation: (invocations x duration x memory) = cost. Understanding each variable tells you exactly where to optimize.
Invocations are the number of times your function runs. AWS Lambda charges $0.20 per million invocations. Cloudflare Workers charges $0.30 per million on the paid plan after the first 10 million. Vercel bundles invocations into your plan but charges overages.
Duration is how long each invocation runs, measured in milliseconds. AWS Lambda charges $0.0000166667 per GB-second. A function that runs for 3 seconds instead of 300 milliseconds costs 10x more per call. Sounds tiny per invocation, but multiply by a million requests and the difference is real.
Memory allocation is the multiplier on duration cost. A Lambda function configured for 1,024 MB costs twice as much per millisecond as one at 512 MB. Most AI-generated functions default to 1,024 MB. For many, 256 MB is plenty.
What Cold Starts Actually Cost You
A cold start happens when your cloud provider spins up a new execution environment for your function. It loads your code, initializes the runtime, runs your imports, then executes your handler. This initialization is billed as part of your function duration.
If your Lambda function has a 1-second cold start and 10% of requests hit cold functions, that adds an average of 100ms to your billed duration across all requests. At 10 million requests per month with 1 GB memory, the cold start tax costs roughly $16.70. For a function that otherwise runs in 200ms, cold starts increase your duration bill by 50%.
What causes cold starts to be slow:
Node.js functions with large node_modules bundles take longer to initialize. A function that imports the full AWS SDK (47 MB) cold-starts in 800 to 1,200ms. The same function importing only @aws-sdk/client-s3 (3 MB) cold-starts in 200 to 400ms. Python functions with heavy dependencies like pandas or numpy see similar patterns.
Tree-shaking and bundle optimization are not just performance niceties. They are direct cost reducers. Every megabyte you trim from your function bundle saves real money at scale.
Cold starts are not just a performance problem. They are a billing problem. A 1-second cold start on 10% of requests increases your total duration costs by up to 50%. The single most effective fix is reducing your function bundle size through tree-shaking and selective imports.
Four ways to reduce cold start costs:
First, use selective imports instead of barrel imports. Replace import AWS from 'aws-sdk' with import { S3Client } from '@aws-sdk/client-s3'. This alone can cut cold start time by 60%.
Second, keep your function bundles under 5 MB. Use your bundler's analyzer to identify what is bloating your package. Heavy dependencies like moment.js, lodash (full import), or the complete AWS SDK are common offenders in AI-generated code.
Third, consider provisioned concurrency on AWS Lambda for predictable traffic. AWS charges about 25% of the on-demand price for pre-warmed instances. For functions handling 100+ requests per minute, this is cheaper than paying for cold starts.
Fourth, use edge functions for latency-sensitive paths. Cloudflare Workers and Vercel Edge Functions run on V8 isolates that cold-start in under 5ms. The tradeoff is a more limited runtime, but for lightweight work like auth checks or redirects, edge is dramatically cheaper.
Reducing Invocations Through Smarter Caching
The cheapest function invocation is the one that never happens. Caching is the most effective way to reduce your invocation count, and most vibe-coded apps have zero caching strategy.

ISR (Incremental Static Regeneration) is the simplest win for Next.js apps on Vercel. Instead of running a serverless function for every page request, ISR generates the page once and serves it from the CDN. A blog page with revalidate: 3600 generates one function invocation per hour instead of one per visitor. If that page gets 10,000 visits per hour, you just reduced invocations by 99.99%.
SWR (stale-while-revalidate) headers work at the HTTP layer and apply to any serverless platform. Set Cache-Control: public, s-maxage=60, stale-while-revalidate=300 on your API responses and the CDN serves cached responses for 60 seconds, then revalidates in the background. Users always get fast responses, and your function only runs once per minute instead of once per request.
Client-side caching with libraries like TanStack Query or SWR (the React library) prevents redundant API calls from the browser. If a user navigates between pages that fetch the same data, client-side caching serves the stored response instead of making another network request. For apps with repetitive data patterns, this alone can cut invocations by 30 to 50%.
API route consolidation is an underrated optimization. AI-generated code often creates one API route per data need: /api/user, /api/settings, /api/preferences. Each page load triggers three separate function invocations. Consolidate these into a single /api/user-data route that returns everything in one call. Three invocations become one. Your bill drops by 66% for that interaction.
Optimizing Function Duration
Duration is the most controllable cost variable. Every millisecond you shave off your function execution time saves money proportional to your traffic volume.
Database connection pooling is critical for serverless. Without pooling, every function invocation opens a new database connection, which takes 50 to 200ms. A connection pooler like PgBouncer, Supabase's built-in pooler, or Neon's serverless driver maintains a pool of warm connections. Your function grabs an existing connection in 1 to 5ms instead of establishing a new one. That saves 50 to 200ms per invocation, which at scale is significant.
Streaming responses reduce billed duration on platforms that support it. For AI-powered endpoints that call Claude or GPT, streaming means the function duration equals the actual generation time rather than holding the connection open while the client waits.
Move computation to the right layer. Image resizing, PDF generation, and data aggregation are better handled by dedicated services or background jobs. A function that resizes an image might run for 3 seconds. Offloading that to Cloudflare Image Optimization or a dedicated worker frees your function to return immediately.
Right-size your memory allocation. AWS Lambda lets you configure memory from 128 MB to 10,240 MB, and CPU scales proportionally with memory. Many functions run perfectly on 256 MB but are deployed at 1,024 MB because the developer never tested lower settings. Start at 256 MB, load test, and increase only if you see timeout errors or slow execution. Going from 1,024 MB to 256 MB cuts your duration cost by 75%.

Vercel vs Cloudflare Workers Pricing Compared
The platform you choose determines your cost floor. Here is a real comparison for a typical workload of 2 million requests per month with an average function duration of 200ms.
| Metric | Vercel Pro | Cloudflare Workers Paid | AWS Lambda |
|---|---|---|---|
| Monthly base | $20/user | $5 | $0 |
| Included requests | Bundled | 10M | 1M free tier |
| Cost per 1M requests | Bundled | $0.30 | $0.20 |
| Duration billing | GB-hours | CPU-ms | GB-seconds |
| Cold start time | 250-1500ms | Less than 5ms | 200-1500ms |
| 2M req/mo estimate | $20 | $5 | $3.60 |
Cloudflare Workers win on raw price and cold starts. Their V8 isolate architecture eliminates cold starts entirely. The tradeoff is a more constrained runtime with no native Node.js modules and a 128 MB memory limit.
Vercel is more expensive but gives you the full Node.js runtime and tight Next.js integration. If your app is a standard Next.js project, the serverless costs are bundled into your $20 monthly fee until you exceed included limits.
AWS Lambda offers the most control and lowest per-unit pricing, but you manage everything yourself. The operational overhead can easily cost more in developer time than you save in infrastructure dollars.
Choosing a serverless platform based only on the per-request price. Cloudflare Workers at $0.30 per million requests looks more expensive than Lambda at $0.20, but Workers have near-zero cold starts and include 10 million free requests. At 2 million requests per month, Workers costs $5 total while Lambda costs $3.60 plus the operational overhead of managing your own infrastructure. Factor in the full picture, not just the unit price.
When Serverless Stops Making Sense
Serverless costs scale linearly. A VPS does not. At some point, the lines cross.
A $20-per-month Hetzner VPS can handle roughly 1,000 concurrent requests. On AWS Lambda at 30 million requests per month, you would pay approximately $56. At that traffic level, the costs are roughly equal.
The crossover point for most apps is between 10 million and 50 million requests per month. Below that, serverless wins on simplicity. Above that, dedicated compute wins on raw economics. The hybrid approach also works well: keep serverless for spiky workloads (webhooks, user-triggered actions) and move steady-state workloads (background jobs, scheduled tasks) to a VPS.
Understanding serverless billing is one piece of the cost puzzle.
See all guidesWhat This Means For You
Serverless cost optimization comes down to three levers, and you should pull them in this order.
Reduce invocations first. Caching with ISR, SWR headers, and client-side caching is the highest-leverage change. Eliminating 80% of invocations through caching reduces your bill by 80%, regardless of how long each function runs.
Shrink duration second. Connection pooling, streaming responses, and right-sizing memory allocation compound into significant savings. A function that runs in 200ms instead of 2,000ms costs 90% less per call.
Fix cold starts third. Bundle optimization and selective imports reduce cold start penalties. For apps on Cloudflare Workers or Vercel Edge Functions, cold starts are essentially free, so this matters most on Lambda and traditional serverless Node.js runtimes.
The builders who keep their serverless bills low are not the ones obsessing over per-request pricing. They are the ones who understand that every unnecessary invocation, every bloated function, and every unoptimized database connection is money leaving their account. Measure your actual costs, apply these techniques in order, and you will see the numbers drop within a billing cycle.
Serverless is just one part of your monthly infrastructure spend.
Explore more guides