# From next build to a Production Request

> Follow a Next.js application from source code through build artifacts, platform routing, caching, server execution, and self-hosting.

- Author: Aman Kumar Gupta (akgbytes)
- Published: 2026-06-23
- Tags: Next.js, Deployment, Infrastructure
- Series: Modern Web Systems from First Principles, part 8
- Canonical source: https://akgbytes.in/blogs/from-next-build-to-a-production-request

You run `next build`, deploy the result, and receive a URL. Behind that short workflow, the application changes shape several times.

Some code becomes browser JavaScript. Some remains server-only. Some routes can be prepared ahead of time, while others need a server when a request arrives.

The deployment platform must place each output somewhere useful and route every request to the correct destination.

This article follows that journey from source files to a production response.

## A build is a translation step

During development, your application is organized for people:

```text
app/
  layout.tsx
  page.tsx
  products/[id]/page.tsx
  api/search/route.ts
public/
  logo.svg
proxy.ts
```

A production platform needs a different view. It needs executable server entries, browser bundles, static files, prerendered responses, routing metadata, and cache instructions.

`next build` translates the source-oriented project into that production-oriented representation.

The build also reports how routes were prepared. A route may be prerendered, rendered on demand, or contain a static shell with work deferred until request time.

That report is not merely a performance score. It previews which parts of the application will need runtime infrastructure.

## What `next build` produces

A normal Next.js production build writes framework output into `.next`.

The exact files are implementation details, but they represent several useful categories:

- Server code for pages, Route Handlers, Server Functions, and rendering
- Browser JavaScript for interactive Client Components
- CSS, fonts, images, and other static assets
- HTML and React Server Component payloads produced during prerendering
- Route, dependency, and cache metadata
- Proxy code and matcher information, when configured

The same source route can contribute to more than one category.

A page might have server code that reads data, a prerendered HTML shell, an RSC payload for navigation, and a small browser bundle for one interactive component.

This is why “one page becomes one HTML file” is no longer a sufficient model for a modern Next.js application.

## Framework output is not platform output

`.next` describes what Next.js built. It does not prescribe the exact cloud service that must run each artifact.

A platform adapter translates that framework output into deployable platform primitives.

Those primitives may include:

- Files served directly by a CDN
- Server functions or long-running Node.js processes
- Prerendered entries backed by a cache
- Image optimization handlers
- Routing and rewrite configuration
- Shared cache and revalidation integrations

For Vercel, the documented Build Output API uses `.vercel/output`. Running `vercel build` can produce this representation for inspection or a prebuilt deployment.

Do not confuse the two directories:

```text
next build    → .next            Next.js production output
vercel build  → .vercel/output   Vercel deployment representation
```

Other platforms can use the Next.js Deployment Adapter API to generate a representation suited to their own infrastructure.

![How source files become Next.js build output and deployment primitives.](https://akgbytes.in/articles/diagrams/next-build.svg)

## Static files take the shortest path

Hashed JavaScript and CSS bundles can be cached for a long time because changing their content changes their filename.

Files from `public/` are also static, but their names may remain unchanged when their contents change. They need a more careful cache policy.

Prerendered output can often be served without executing the route’s server code for every request.

A deployment platform can place these artifacts behind a CDN so a nearby cache handles most requests.

The durable origin might be object storage, a platform-managed asset store, or a regular web server. Application code should not assume a specific vendor implementation.

The important property is simpler: **the request can be answered as a file or cached entry without running the application server**.

## Dynamic work needs a server runtime

Some requests depend on information that only exists at request time.

Cookies, request headers, authenticated user data, a search query, or a fresh database read may require server execution.

The platform packages the relevant server entry and its traced dependencies for a supported runtime.

That runtime might be a platform function, a container, or a long-running Node.js process. Next.js needs a compatible server; serverless infrastructure is an optimization and operating choice.

When a dynamic request arrives, the routing layer sends it to that server entry. The server renders the response or runs the Route Handler, then returns the result upstream.

Whether the result may be cached depends on its semantics and cache policy. Personalized output must not enter a shared public cache.

## Routing stitches the outputs together

One domain can serve static files, cached pages, API endpoints, dynamic routes, optimized images, and redirects.

The platform needs a routing table that tells it which output handles each request.

Build metadata supplies patterns for static routes, dynamic segments, rewrites, redirects, headers, Proxy matchers, and generated endpoints such as image optimization.

For example, these URLs may share a domain but require different work:

| Request              | Likely destination                                        |
| -------------------- | --------------------------------------------------------- |
| `/_next/static/...`  | Immutable static asset                                    |
| `/logo.svg`          | Public static file                                        |
| `/products/42`       | Prerendered, cached, partially rendered, or dynamic route |
| `/api/search?q=book` | Route Handler                                             |
| `/_next/image?...`   | Image optimization handler                                |

“Likely” matters. The application’s rendering and caching decisions determine the actual path; the pathname alone does not reveal everything.

## Where Proxy fits

Next.js 16 renamed the `middleware` file convention to `proxy` to emphasize its position at the request boundary.

Proxy can inspect an incoming request before route rendering. It can redirect, rewrite, change headers, set cookies, or return a response directly.

```typescript
import { NextResponse } from "next/server"
import type { NextRequest } from "next/server"

export function proxy(request: NextRequest) {
  if (!request.cookies.has("session")) {
    return NextResponse.redirect(new URL("/login", request.url))
  }

  return NextResponse.next()
}

export const config = {
  matcher: "/dashboard/:path*",
}
```

In current Next.js, Proxy defaults to the Node.js runtime. A deployment platform may place boundary logic near users when its integration supports that optimization.

Proxy should remain focused. Running expensive database work before many requests can turn a convenient boundary into a latency bottleneck.

It should not be the only authorization layer. Server Functions and Route Handlers must verify permission for the operation they perform.

## Following one production request

Imagine a signed-in user opens `/dashboard`.

The precise infrastructure varies by platform, but the logical request lifecycle looks like this:

1. The platform receives the request through its network or CDN.
2. Configured headers and redirects are evaluated.
3. Proxy runs if its matcher includes `/dashboard`.
4. The router resolves the rewritten or original pathname.
5. A valid cached response may be returned immediately.
6. Otherwise, the matching server entry runs.
7. Server code reads the required data and renders the response.
8. The response travels back through the platform to the browser.
9. Eligible layers store it according to its cache policy.

Not every request visits every step.

A static asset can stop at the CDN. Proxy can return a redirect. A cache hit can skip server execution. A dynamic dashboard normally continues to the server and database.

![The lifecycle of a production request through the network, routing, cache, and server.](https://akgbytes.in/articles/diagrams/next-request-lifecycle.svg)

## Keep compute close to its data

Running code near the user sounds ideal, but most dynamic code is not independent.

If a function in Mumbai queries a database in Virginia, every query still crosses that distance. Moving only the function may add complexity without removing the dominant latency.

Database-heavy compute usually belongs near the database. Cacheable output can then move outward through the CDN.

Globally distributed compute works best with data that is also distributed, replicated for local reads, or unnecessary for that request.

Choose regions by following the slowest required dependency, not by moving every function as close to the browser as possible.

## Self-hosting does not require rebuilding Vercel

The minimum production environment for Next.js is a compatible Node.js server. A single `next start` process can provide the framework’s features with high functional fidelity.

Place a reverse proxy such as nginx in front of that process for TLS termination, request limits, rate limiting, and protection from malformed or slow requests.

At larger scale, multiple server instances create coordination work.

Each instance can otherwise hold a different cache. A revalidation on one instance may not immediately reach the others.

A robust multi-instance deployment needs a shared cache strategy, coordinated tag invalidation, consistent encryption keys, a deployment identifier, and graceful shutdown behavior.

Streaming must pass through proxies without buffering if you want the performance benefits of Server Components and partial prerendering.

Image optimization works with `next start`, although a platform may choose to run it as a separate service.

Self-hosting is therefore a spectrum:

1. One Node.js process behind a reverse proxy
2. Replicated containers with shared caching
3. A platform adapter that maps outputs to cloud-native services

Start with the simplest topology that satisfies your reliability and scaling requirements.

## Where OpenNext and adapters help

OpenNext converts a Next.js build into packages for deployment targets outside Vercel.

For AWS, it can separate static assets, server handlers, cache data, image optimization, and revalidation support into deployable outputs.

OpenNext does not purchase, configure, or operate the underlying infrastructure by itself. Tools such as SST, CDK, Terraform, or another deployment system consume those outputs.

Next.js 16.2 also provides a stable Deployment Adapter API. This gives platform integrations a public contract for reading build outputs and preparing platform-specific artifacts.

An adapter can provide functional support without copying Vercel’s private architecture. Different platforms can make different performance trade-offs while preserving Next.js behavior.

## Build-time and request-time are one system

The build decides what can be prepared early and records what the platform needs to run later.

The adapter turns that information into deployable units. The routing layer connects incoming requests to those units. The cache decides how often the runtime must execute them.

These are not separate topics. A rendering choice changes build output, deployment requirements, request routing, caching behavior, latency, and cost.

That gives us the complete mental model for the series:

```text
source code
  → framework build
  → platform adaptation
  → deployed files, caches, and runtimes
  → request routing
  → cached response or server execution
  → data access
  → response
```

## Key takeaways

- `next build` creates framework output in `.next`.
- Platform tools translate that output into deployable infrastructure.
- `vercel build` can create Vercel’s `.vercel/output` representation.
- Static files and valid cached output avoid server execution.
- Dynamic work runs in a compatible server runtime.
- Routing metadata connects one domain to many output types.
- Proxy runs before rendering but should not replace authorization at the operation boundary.
- Compute should usually remain close to the data it needs.
- Self-hosting can begin with one Node.js server and deepen only when scale requires it.

## Further reading

- [Next.js: deploying to platforms](https://nextjs.org/docs/app/guides/deploying-to-platforms)
- [Next.js: self-hosting](https://nextjs.org/docs/app/guides/self-hosting)
- [Next.js Proxy reference](https://nextjs.org/docs/app/api-reference/file-conventions/proxy)
- [Vercel Build Output API](https://vercel.com/docs/build-output-api)
- [OpenNext architecture](https://opennext.js.org/aws/inner_workings/architecture)