The Deployment Decision Nobody Warned You About
Picking where to host your Next.js app feels like it should be a five-minute decision. You've got the code working, the coffee is fresh, and you just want the thing to be live. Then you start comparing platforms, and suddenly you're reading pricing pages written in corporate hieroglyphics, trying to figure out whether "function invocations" and "edge middleware executions" mean the same thing.
I've been through this with multiple teams — solo projects, early-stage startups, and mid-sized companies burning through cloud budgets — and the honest truth is that both Vercel and AWS can be the right answer depending on what you're building. But they're right in completely different ways. The cost difference isn't just about the monthly invoice. It's about your time, your team's expertise, your traffic patterns, and how much unpredictable scaling genuinely keeps you up at night.
This breakdown is going to get into the real numbers, the hidden trade-offs, and the actual deployment code you'd write for each platform. Let's get into it.
Understanding Vercel's Pricing Model
Vercel built its entire business around Next.js. They literally created the framework, so it should come as no surprise that deploying there is a remarkably smooth experience. You push to GitHub, Vercel detects your Next.js project, builds it, and serves it globally through their CDN (Content Delivery Network — a network of servers spread around the world so your content loads fast, no matter where the user is). No YAML files. No IAM roles. No sobbing quietly at your desk.
The pricing model, though, requires some unpacking. The free Hobby tier is genuinely useful for personal projects. The Pro tier starts at $20/user/month, which feels reasonable until you hit their usage thresholds. Here's where it gets interesting: Vercel charges per unit for things like function invocations (every time a server-side function runs), bandwidth, build minutes, and Edge Middleware executions. On the Pro plan, you get 1 million function invocations per month. Sounds like a lot. If you have a moderately active app with server-side rendering on key pages, a flash of traffic — say, a ProductHunt launch or a newsletter drop — can burn through that budget in hours.
The other thing to understand is Vercel's pricing for teams. Enterprise pricing is custom and intentionally opaque, but I've spoken to founders who've seen quotes ranging from $500 to $5,000+ per month once you factor in seats, usage, and SLA requirements. For early teams, Vercel Pro is often completely fine. For companies past Series A with significant traffic, the math frequently starts working against you. That's not a criticism — it's just reality.
What AWS Actually Looks Like for Next.js
AWS doesn't give you a "deploy Next.js" button. What it gives you is a toolbox the size of a small aircraft carrier, and you have to figure out which tools to use. The main options for hosting Next.js on AWS are: EC2 (virtual machines you manage yourself), ECS (containers running on managed infrastructure), Lambda + API Gateway (serverless functions), and AWS Amplify (their attempt at a Vercel-like experience).
AWS Amplify deserves its own mention because it's often the first thing people try when they want Vercel-style simplicity on AWS. It handles Git integration, preview deployments, and CI/CD pipelines. The pricing is similar in structure to Vercel — you pay per build minute, per GB of storage, and per request served. For small- to medium-sized apps, Amplify can be cheaper than Vercel, but it has a reputation for lagging on Next.js App Router support. I've found that Amplify often works great until you hit some feature at the edge of the Next.js API, then it becomes a painful afternoon of reading GitHub issues.
The more powerful AWS approach for production-grade Next.js apps is using the OpenNext project — an open-source adapter that packages Next.js for deployment on Lambda, CloudFront (AWS's CDN), and S3. It's become the de facto standard for teams that want the full Next.js feature set without paying Vercel prices. The trade-off is that you're taking on infrastructure responsibility. You need to set it up, monitor it, and debug it when something breaks at 2 am.
Real Cost Comparison With Actual Numbers
Let's ground this in something concrete. Imagine a SaaS application with 50,000 monthly active users. Pages are server-side rendered. You have some API routes, some static pages, and you're using Next.js Image Optimization. Here's roughly what you're looking at.
On Vercel Pro, assuming roughly 10 million function invocations per month (reasonable for that traffic level with SSR), you'd be looking at the base $20/seat plus around $150–300 in overage costs. Add in bandwidth, and you're probably sitting at $400–600/month. That number scales uncomfortably fast with traffic spikes.
On AWS with OpenNext, the equivalent setup using Lambda, CloudFront, and S3 would cost significantly less at the same traffic level. Lambda pricing is $0.20 per million requests plus compute time, CloudFront runs about $0.0085 per GB of data transfer, and S3 is nearly free at this scale. Realistic total: $80–150/month. The gap is real. But you've also spent 20–40 engineering hours setting it up, and you'll spend maybe 5–10 hours per month on maintenance and monitoring. Factor in an engineer's time at $100/hour and the math shifts considerably. It's not a free lunch.
Deploying to Vercel — The Baseline
To give you a sense of how simple Vercel is, here's a complete next.config.js workflow you'd follow. For most apps, you don't even need special configuration.
// next.config.js — minimal Vercel-ready config
/** @type {import('next').NextConfig} */
const nextConfig = {
images: {
remotePatterns: [
{
protocol: 'https',
hostname: 'your-cdn-domain.com',
},
],
},
// Vercel handles this automatically, but being explicit is good
output: 'standalone',
experimental: {
serverComponentsExternalPackages: ['your-heavy-library'],
},
};
module.exports = nextConfig;Then your deployment is literally just:
# Install Vercel CLI
npm install -g vercel
# Deploy (first time sets up the project)
vercel
# For production
vercel --prodThat's it. Vercel reads your Next.js config, handles the build, distributes static assets to their CDN, spins up serverless functions for your API routes and SSR pages, and gives you a URL. Preview deployments for every pull request happen automatically. It's genuinely impressive. The simplicity is the product.
Deploying to AWS with OpenNext
Now let's look at what a real AWS deployment looks like using OpenNext and AWS CDK (Cloud Development Kit — a way to define your cloud infrastructure using actual code instead of clicking through dashboards). This is more complex but gives you serious control.
// open-next.config.ts — tells OpenNext how to build your app for AWS
import type { OpenNextConfig } from "open-next/types/open-next";
const config: OpenNextConfig = {
default: {
// This becomes your main Lambda function
override: {
wrapper: "aws-lambda-streaming", // enables streaming responses
converter: "aws-apigw-v2",
},
},
middleware: {
// Edge middleware runs on CloudFront, closer to users
external: true,
},
};
export default config;// lib/nextjs-stack.ts — CDK stack that wires everything together
import * as cdk from "aws-cdk-lib";
import * as s3 from "aws-cdk-lib/aws-s3";
import * as cloudfront from "aws-cdk-lib/aws-cloudfront";
import * as lambda from "aws-cdk-lib/aws-lambda";
import { Construct } from "constructs";
export class NextjsStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
// S3 bucket holds your static assets (JS, CSS, images)
const assetBucket = new s3.Bucket(this, "StaticAssets", {
removalPolicy: cdk.RemovalPolicy.DESTROY,
autoDeleteObjects: true,
});
// Lambda function handles SSR and API routes
const serverFunction = new lambda.Function(this, "NextjsServer", {
runtime: lambda.Runtime.NODEJS_20_X,
handler: "index.handler",
// Point to the .open-next/server-function directory after build
code: lambda.Code.fromAsset(".open-next/server-function"),
memorySize: 1024, // 1GB RAM — tune this based on your app
timeout: cdk.Duration.seconds(30),
environment: {
NODE_ENV: "production",
// Add your env vars here or use SSM Parameter Store
},
});
// CloudFront distribution sits in front of everything
// Routes static requests to S3, dynamic requests to Lambda
const distribution = new cloudfront.Distribution(this, "Distribution", {
defaultBehavior: {
origin: new cdk.aws_cloudfront_origins.HttpOrigin(
`${serverFunction.functionArn}.lambda-url.us-east-1.on.aws`
),
viewerProtocolPolicy:
cloudfront.ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
cachePolicy: cloudfront.CachePolicy.CACHING_DISABLED, // for SSR
},
});
new cdk.CfnOutput(this, "DistributionURL", {
value: `https://${distribution.distributionDomainName}`,
});
}
}This is a simplified version — production setups also need WAF (Web Application Firewall) rules, custom domain configuration, cache invalidation logic, and CI/CD pipelines. My point isn't to overwhelm you. It's to show you the kind of work involved. This is real infrastructure code that you own, version control, and maintain.
The Hidden Costs Nobody Puts in a Pricing Table
The AWS vs Vercel cost conversation usually focuses on the monthly bill. That's the wrong frame. The real cost is the total cost of ownership, which includes the engineering time to set things up, the cognitive overhead of keeping it running, the time lost debugging infrastructure versus building features, and the cost of incidents.
When something breaks on Vercel, you open their status page and check if it's a platform issue. When something breaks on your AWS setup, you start pulling CloudWatch logs (AWS's monitoring service), checking Lambda cold start times, looking at CloudFront cache behaviors, and wondering if you messed up your IAM permissions. I've spent entire mornings debugging an AWS issue that turned out to be a misconfigured security group — a firewall rule that was blocking traffic on a specific port. On Vercel, that issue doesn't exist.
On the other hand, I've seen teams hit Vercel's function timeout limits (10 seconds on Pro, 300 on Enterprise) and realize there's nothing they can do without upgrading their plan or rearchitecting their app. On AWS Lambda, you can set timeouts up to 15 minutes. You control memory allocation, which directly affects CPU performance. You can use container images up to 10GB if your app has heavy native dependencies. That flexibility has genuine business value that you can't easily put a dollar figure on.
When Vercel Wins
Vercel makes the most sense when developer velocity is your primary constraint. If you're a small team, a solo developer, or an agency shipping client sites at pace, the hours you save on infrastructure work directly translate to more features shipped, more clients served, and less burnout. The DX (developer experience) on Vercel is legitimately world-class. Preview deployments on every PR, instant rollbacks, automatic image optimization, Edge Functions that work exactly as documented — these things matter.
It's also the right answer when your traffic is relatively predictable, and you're not pushing past their plan limits regularly. A marketing site, a documentation site, an early-stage B2B SaaS with a few hundred customers — Vercel Pro handles all of this gracefully without costing you sleep. The $20/month baseline is basically a rounding error in a startup's budget.
Where Vercel starts to hurt is at scale. If you're running an e-commerce platform that gets millions of page views per month, or a media site with spiky traffic, the usage-based pricing becomes a financial liability rather than a feature. Teams in this situation often tell me they feel held hostage — migrating away is painful, but staying is increasingly expensive.
When AWS Wins
AWS is the right call when you have the engineering capacity to manage infrastructure, when your traffic volume makes the Vercel bill genuinely painful, or when compliance and data residency requirements mean you need more control over where your compute actually runs. Healthcare companies, fintech startups, and government contractors often have to use AWS or Azure because their customers require it contractually.
It's also worth considering AWS when you're already deeply invested in the AWS ecosystem. If you have an RDS database, SQS queues, S3 buckets, and Lambda functions all wired together, keeping your Next.js app in the same environment simplifies your security model, your networking, and your cost optimization strategies. You can keep traffic internal, avoid egress costs (the fees for data leaving the cloud — often the sneakiest AWS cost), and use one tool for all your observability.
In my experience, the teams that thrive on AWS for Next.js are those who treat infrastructure as a core competency, not a necessary evil. They have engineers who like working with CDK or Terraform, they invest in good monitoring from day one, and they view the initial setup cost as a long-term investment in cost efficiency and control.
A Framework for Making the Decision
Rather than giving you a rigid recommendation, here's the mental model I use when advising teams on this choice. Think about two variables: your current traffic cost on Vercel (estimated), and your team's infrastructure maturity. If estimated Vercel costs would be under $500/month and your team doesn't have dedicated DevOps experience, start on Vercel and revisit when the bill starts hurting. The migration pain is real but manageable with tools like OpenNext and SST (a framework built on CDK that makes AWS deployments of Next.js apps significantly easier).
If your estimated costs on Vercel would exceed $1,000/month, or if you already have infrastructure engineers on the team, AWS is very likely the more economical long-term choice. The setup investment pays off within a few months of operation, and the operational cost savings compound over time. Teams I've worked with that made this switch at the right moment have cut their infrastructure costs by 60–70% without meaningfully increasing operational burden.
The most expensive mistake you can make is choosing the wrong platform and then waiting too long to reconsider. Migrating off Vercel when you're doing $3,000/month in usage is painful. Migrating off when you're at $400/month is a manageable weekend project. Pay attention to your bill trajectory, not just your current number.
The Honest Bottom Line
Neither platform is obviously superior. Vercel is paying for simplicity, speed to production, and a tight integration with the framework they built. You're getting real value for that price — just make sure the price makes sense at your scale. AWS is paying for control, flexibility, and long-term cost efficiency. You're giving up convenience and accepting operational responsibility in exchange.
The worst outcome is picking a platform based on what you've heard in podcasts or what looks cool on Twitter. Run the actual numbers for your expected traffic. Be honest about your team's infrastructure experience. And whatever you choose, invest early in monitoring — whether that's Vercel Analytics, AWS CloudWatch with proper dashboards, or a third-party tool like Datadog. You can't optimize what you can't see, and understanding your cost drivers is the only way to make a genuinely informed decision down the road.
