Deployment & Infrastructure

How to Deploy Next.js to AWS Lambda: A Complete Guide to Serverless Deployment (2026)

A real-world case study of deploying Next.js 16 to AWS Lambda. Learn from actual problems, solutions, and why serverless architecture cuts hosting costs to $0/month while improving performance.

Sjors Verhoef15 min read

Why Serverless Deployment Matters for Your Business

When building modern web applications, hosting costs can quickly spiral out of control. Traditional VPS hosting runs 24/7 whether you have traffic or not. For a freelance portfolio or business website with inconsistent traffic, you're paying for idle servers most of the time.

Serverless changes the game. Pay only when someone visits your site. Scale automatically during traffic spikes. Stay within free tier with typical portfolio traffic. That's the promise of AWS Lambda.

After building a modern Next.js 16 freelance portfolio website, I needed production-grade hosting that wouldn't break the bank. This is the complete technical story of deploying to AWS Lambda - including every mistake, dead-end, and eventual solution.

The Business Case for Serverless

Before diving into the technical details, here's why this matters:

  • $0/month hosting for sites with normal traffic (within AWS free tier)
  • Automatic scaling - handles traffic spikes without configuration
  • Global CDN - CloudFront delivers content from edge locations worldwide
  • Zero server maintenance - no OS updates, no security patches
  • Production-grade infrastructure - AWS reliability without enterprise costs

For freelancers and agencies, this means you can offer clients enterprise infrastructure at startup prices. Let me show you how it's done.

Attempt 1: Manual Lambda Handler (The Hard Way)

The first approach was the DIY route - writing a custom Lambda handler to wrap the Next.js standalone output.

The Setup

We configured next.config.ts with output: 'standalone' and created a custom index.js handler that would:

  • Convert API Gateway events to HTTP requests
  • Initialize Next.js's internal server
  • Process requests and return responses

The Problems

This approach immediately ran into issues:

  • Promise Rejections - Next.js created background promises that never settled, causing Lambda to crash with Runtime.NodeJsExit errors
  • Missing Methods - The mock response object was missing methods like appendHeader() and flushHeaders() that Next.js expected
  • Event Listener Leaks - MaxListenersExceededWarning errors showed memory leaks in the event handling
  • Intermittent 502 Errors - The site would work on first load but fail on subsequent requests

After hours of debugging, adding missing methods, and configuring event listeners, we achieved partial success - the site would load sometimes, but remained unreliable.

Lesson for clients: Sometimes the cheapest approach (DIY) costs more in time and reliability. Professional tooling matters.

Attempt 2: OpenNext Integration

Realizing the manual approach was too fragile, we turned to OpenNext - a tool specifically designed to adapt Next.js for AWS Lambda.

Why OpenNext?

OpenNext is purpose-built to solve the exact problems we encountered:

  • Handles Next.js's server lifecycle properly
  • Manages Promise resolution correctly
  • Supports all Next.js features (ISR, middleware, etc.)
  • Active development and community

The Installation

npm install --save-dev open-next@latest
npx open-next@latest build

OpenNext generated a .open-next directory with:

  • server-functions/default/ - The Lambda function code
  • assets/ - Static files (CSS, JS, images)
  • image-optimization-function/ - Optional image handler

The React Module Error

Deployment initially failed with:

Error: Cannot find module './cjs/react.development.js'

The issue? The Lambda runtime wasn't setting NODE_ENV=production, so React tried to load development files that don't exist in the production build.

Solution: Set NODE_ENV=production as a Lambda environment variable.

The Static Asset Problem

The site loaded, but with a critical issue - no CSS or JavaScript! The browser console showed 404 errors for all /_next/static/ files.

Here's the fundamental problem with OpenNext: It separates static assets from the Lambda function by design. The assets are meant to be uploaded to S3 and served via CloudFront, not bundled with Lambda.

We tried bundling assets manually:

cp -r .open-next/assets/* .open-next/server-functions/default/
zip -r opennext-lambda-with-assets.zip .

But OpenNext's handler didn't know to serve these files - they were there, but the Lambda function had no route to access them.

The Realization: OpenNext Needs Infrastructure

After multiple failed attempts, the core problem became clear:

OpenNext is not a complete deployment solution - it's an adapter that requires proper infrastructure.

You can't just upload OpenNext output to Lambda and expect it to work. You need:

  • S3 bucket for static assets
  • CloudFront distribution for routing and caching
  • Proper environment configuration
  • Lambda function properly configured
  • SSL certificates and DNS

Manually setting all this up in AWS Console would take hours and introduce errors. This is where professional deployment tools become invaluable.

The Solution: SST (Serverless Stack)

Enter SST - a framework that uses OpenNext under the hood but handles all the infrastructure automatically.

What SST Does for You

SST takes care of the entire deployment:

  • Creates Lambda function with OpenNext
  • Sets up S3 bucket for assets
  • Configures CloudFront distribution with edge caching
  • Generates SSL certificates automatically
  • Manages Route 53 DNS records
  • Handles environment variables securely
  • Enables one-command deployments

All with a single configuration file. This is infrastructure-as-code done right.

The Setup

npm install --save-dev sst@latest aws-cdk-lib@^2.172.0

Create sst.config.ts:

export default $config({
  app(input) {
    return {
      name: "my-nextjs-app",
      removal: input?.stage === "production" ? "retain" : "remove",
      home: "aws",
    };
  },
  async run() {
    new sst.aws.Nextjs("MyNextSite", {
      domain: {
        name: "example.com",
        aliases: ["www.example.com"],
      },
      environment: {
        // Add your environment variables here
        MY_API_KEY: process.env.MY_API_KEY || "",
      },
    });
  },
});

The Deployment Challenges

Even with SST, we encountered issues that teach important lessons:

1. TypeScript Checking SST's Internal Files

Next.js's build was type-checking SST's .sst/platform/ directory, causing errors.

Solution: Added to next.config.ts:

typescript: {
  ignoreBuildErrors: true,
}

2. Existing Certificate Validation Records

Route 53 had old CNAME records from previous SSL certificates that conflicted with new ones.

Solution: Deleted all _*.acm-validations.aws CNAME records from Route 53.

3. DNS Records Already Existed

Existing A and AAAA records pointing to the old CloudFront distribution prevented SST from creating new ones.

Solution: Deleted old A/AAAA records from all hosted zones, letting SST create fresh ones.

Success!

After clearing these obstacles:

npm run deploy

SST automatically:

  • Built the Next.js app with OpenNext
  • Created SSL certificates for all 6 domains
  • Validated certificates via DNS
  • Uploaded static assets to S3
  • Deployed Lambda functions
  • Configured CloudFront distribution with edge caching
  • Updated Route 53 DNS records

The entire site went live on all domains with HTTPS, global CDN, and automatic scaling.

Key Lessons for Professional Deployments

1. Don't Fight the Framework

Next.js is complex. Writing a custom Lambda wrapper is possible but fragile. Use proven tools like OpenNext that understand Next.js internals.

2. OpenNext Alone Isn't Enough

OpenNext is a crucial adapter, but it needs infrastructure. Don't try to bundle everything into Lambda - embrace the S3 + CloudFront architecture for best performance and cost.

3. SST is the Complete Solution

For production Next.js deployments to AWS, SST provides:

  • Infrastructure as code
  • Automatic SSL/DNS management
  • Proper caching configuration
  • One-command deployments
  • Easy updates and rollbacks
  • Multi-stage environments (dev, staging, production)

4. Clean Up Old Resources First

When migrating to new infrastructure, remove old CloudFront distributions and DNS records to avoid conflicts. Start fresh for cleaner results.

The Final Architecture (What Your Clients Get)

The successful deployment provides enterprise-grade infrastructure:

  • Lambda@Edge - Runs Next.js server code on-demand
  • S3 - Stores static assets with 99.999999999% durability
  • CloudFront - Global CDN with 450+ edge locations
  • Route 53 - Managed DNS with 100% uptime SLA
  • ACM - Free SSL certificates with auto-renewal

All automatically managed by SST, all staying within AWS free tier limits for typical sites.

Real-World Cost Analysis

AWS Free Tier includes monthly:

  • Lambda: 1M requests + 400,000 GB-seconds compute
  • S3: 5GB storage + 20,000 GET requests
  • CloudFront: 1TB data transfer out

For a freelance portfolio with 10,000 monthly visits:

  • Lambda requests: ~30,000 (97% under free tier)
  • S3 storage: 920KB (99.98% under free tier)
  • CloudFront: ~5GB transfer (99.5% under free tier)

Total monthly cost: $0

Compare this to traditional hosting:

  • Basic VPS: $5-20/month
  • Managed hosting: $20-50/month
  • Enterprise CDN: $100+/month

Serverless gives you better infrastructure at a fraction of the cost.

The Deployment Workflow

Now, updating the live site is simple:

# Make changes to code or content
npm run deploy

SST handles everything - build, upload, cache invalidation, and deployment. No zip files, no manual uploads, no AWS console clicking.

For agencies managing multiple client sites, this workflow scales perfectly. Each client gets isolated infrastructure with the same deployment simplicity.

Performance Benefits

Beyond cost savings, serverless delivers measurable performance improvements:

  • Global edge caching - Content served from 450+ locations worldwide
  • Automatic scaling - Handles traffic spikes without configuration
  • Cold start optimization - OpenNext minimizes Lambda initialization time
  • Asset optimization - Automatic compression and caching headers

Your users get faster page loads regardless of their location.

Recommendations for Your Next Deployment

If you're deploying Next.js to AWS Lambda (or helping clients do so):

  1. Start with SST from day one - Don't waste time on manual approaches or partial solutions
  2. Use custom domains immediately - SST makes SSL and DNS trivial, so do it from the start
  3. Clean up old infrastructure first - Avoid DNS/SSL conflicts by removing old resources
  4. Trust the process - Certificate validation takes 5-10 minutes, be patient
  5. Monitor CloudWatch - Essential for debugging and understanding real-world usage
  6. Set up staging environments - SST makes multi-stage deployments easy

When to Hire a Professional

While this guide shows the technical path, deployment is just one piece of a successful web project. Consider professional help when:

  • You need it done right the first time
  • Your time is better spent on business activities
  • You want optimization for your specific use case
  • You need ongoing maintenance and updates
  • Compliance or security requirements are critical

A freelance developer experienced with serverless can save you hours of troubleshooting and deliver optimized results faster.

Conclusion: Why This Matters

Deploying Next.js to serverless infrastructure is not trivial. The framework's complexity requires proper tooling and understanding of cloud architecture. After trying manual handlers and OpenNext alone, SST emerged as the clear winner - providing the complete infrastructure automation needed for production deployments.

The journey taught valuable lessons about Next.js internals, AWS services, modern DevOps practices, and the importance of using the right tools for the job. What started as a simple deployment task became an educational exploration of serverless architecture.

The result? A blazing-fast, globally distributed website running on AWS Lambda, costing $0/month, deployed with a single command, and delivering enterprise-grade performance to users worldwide.

For businesses: This architecture delivers premium results at budget-friendly costs.

For developers: This approach is the future of web deployment - scalable, cost-effective, and maintainable.

Sometimes the path to success involves trying what doesn't work, learning why, and finding the right solution. For Next.js on AWS Lambda in 2026, that solution is SST.

Ready to deploy your Next.js project to serverless? Let's talk about making it happen.

S
Sjors Verhoef
Freelance Developer

Share this article

Related Posts

Interested in Working Together?

Let's discuss your next project.

Contact Me
How to Deploy Next.js to AWS Lambda: A Complete Guide to Serverless Deployment (2026) | dev-end - Sjors Verhoef