Vercel’s managed platform isn’t just about convenience; it’s a fundamentally different approach to serving your Next.js app than traditional self-hosting, optimizing for edge delivery and developer experience in ways that are hard to replicate manually.
Let’s see what that looks like.
Imagine a user in Tokyo requesting a page from your Next.js app.
Vercel’s Edge Network:
When you deploy to Vercel, your Next.js application’s static assets (HTML, CSS, JS, images) are distributed to hundreds of Points of Presence (PoPs) globally. When the Tokyo user requests your page, their request is routed to the nearest PoP, which might be in Tokyo itself. This PoP serves the cached static assets directly, resulting in near-instantaneous load times.
For dynamic routes or API routes, Vercel uses Serverless Functions. These functions are also deployed to the edge. When the Tokyo user’s request hits the nearest PoP, if it’s for a dynamic route, the request is handed off to a Serverless Function running in that same PoP. This means the computation happens extremely close to the user, minimizing latency.
Here’s a simplified look at the vercel.json configuration that enables this:
{
"version": 2,
"builds": [
{
"src": "package.json",
"use": "@vercel/next"
}
],
"routes": [
{
"src": "/(.*)",
"dest": "/index.html",
"fallback": false
},
{
"src": "/api/(.*)",
"dest": "/api/$1"
}
]
}
"version": 2: Specifies the Vercel configuration schema version."builds": Defines how your project is built."@vercel/next"is Vercel’s optimized builder for Next.js, handling static export, SSR, and API routes automatically."routes": This is where the edge routing magic happens.- The first route
{"src": "/(.*)", "dest": "/index.html", "fallback": false}tells Vercel to serveindex.html(your Next.js app’s entry point) for any static file request."fallback": falseis crucial for SPAs; it prevents Vercel from trying to find a server-side route if a static file isn’t found. - The second route
{"src": "/api/(.*)", "dest": "/api/$1"}maps any request starting with/api/to your Next.js API routes defined in thepages/apidirectory. Vercel automatically bundles these into Serverless Functions at the edge.
- The first route
Self-Hosting (e.g., with a traditional server):
Now, consider self-hosting your Next.js app, perhaps on an EC2 instance in us-east-1 (N. Virginia).
When that same Tokyo user requests your page:
- Their request travels across the internet to your EC2 instance in
us-east-1. This is already a significant distance and introduces latency. - Your server (e.g., Node.js running
next start) receives the request. - If it’s a static asset, it’s served from the EC2 instance.
- If it’s a dynamic route or API route, your Node.js process on the EC2 instance needs to render the page or execute the API logic. This computation happens in
us-east-1. - The generated HTML or API response then travels all the way back to Tokyo.
To even approach Vercel’s performance, you’d need to:
- Set up a CDN: Like Cloudflare or AWS CloudFront, to cache your static assets globally. This adds complexity to your deployment pipeline and configuration.
- Deploy to multiple regions: To serve dynamic content closer to users, you’d need to deploy your Next.js application to servers in various geographical locations. This requires sophisticated load balancing and traffic routing.
- Manage Serverless Functions: If you want to replicate Vercel’s Serverless Functions for API routes, you’d need to set up and manage AWS Lambda, Google Cloud Functions, or similar services, potentially across multiple regions, and handle their orchestration.
- Configure DNS and Routing: To direct users to the nearest deployment, you’d need to configure GeoDNS or a global load balancer.
The Mental Model: Edge vs. Centralized Compute
Vercel fundamentally shifts compute and delivery to the edge. Instead of one central server or a few regional servers handling all requests, Vercel distributes your application’s static assets and compute capabilities (Serverless Functions) to hundreds of locations worldwide. When a user makes a request, it’s handled by the geographically closest PoP.
This means:
- Static Assets: Served from the nearest PoP, often within milliseconds.
- Dynamic Routes/API Routes: Serverless Functions execute in the nearest PoP, meaning computation happens close to the user.
This "edge-first" architecture drastically reduces latency for both static and dynamic content.
The "Build" is the Deployment Artifact
The next build command in Next.js creates a public directory for static files and a .next directory containing optimized JavaScript bundles, serverless function definitions (for pages/api routes), and static HTML pages for pre-rendered routes. Vercel’s @vercel/next builder takes this output and intelligently deploys it: static files go to their CDN, and serverless function definitions are deployed to their edge network. When you self-host, you typically run next start which uses these build artifacts, but the "server" is still a single point (or a few points) of compute you manage.
The most surprising thing about Vercel’s edge network is that it’s not just a CDN for static files; it’s also where your dynamic JavaScript code (API routes and SSR pages) runs. Vercel’s infrastructure dynamically routes requests to the nearest available Serverless Function instance, abstracting away the complexities of multi-region deployments and global load balancing for your application logic.
The next hurdle you’ll likely encounter is managing custom domains and SSL certificates across multiple regions if you decide to optimize further with a multi-region self-hosted setup.