Next.js 16 on Azure: 4 Hosting Options for Production
Next.js 16 on Azure: 4 Hosting Options for Production
Compare Azure Container Apps, App Service, AKS, and Static Web Apps to pick the best production hosting model for…
·Updated on:··
⚡ Next.js Implementation Guides
In-depth Next.js guides covering App Router, RSC, ISR, and deployment. Get code examples, optimization checklists, and prompts to accelerate development.
Azure gives a Next.js 16 application four realistic hosting options: Azure Container Apps, Azure App Service, Azure Kubernetes Service (AKS), and Azure Static Web Apps. For a new production deployment, I default to Azure Container Apps. It packages the application as a normal container and adds autoscaling, health probes, and revision-based deployments without introducing the operational weight of Kubernetes. App Service is the right call when an organization has already standardized on it. AKS is the right call when Kubernetes is already the organization's platform. Static Web Apps works well for a genuinely static Next.js export. This guide walks through what each service actually manages, the deployment decisions Next.js 16 introduces once you run more than one replica, and a reference architecture for a production Azure deployment.
I recently had to answer this question for a client already standardized on Azure: what's the right way to host a modern Next.js 16 application inside that platform? Azure's documentation offers several plausible services, and they overlap enough that picking one isn't obvious from a quick read. Next.js 16 has also become far more explicit about what a self-hosted production environment needs — shared caching, Server Action encryption keys, version skew during deployments — so the decision now involves more than which service can start a Node process. I went through the current Azure and Next.js documentation to work out an answer, and this is the reasoning behind it.
The short answer
Here's how I currently approach the decision:
Microsoft positions each of these services for a different job. App Service targets HTTP-based web applications and APIs. Container Apps provides managed container orchestration without exposing Kubernetes directly. AKS hands you Kubernetes itself, along with the infrastructure control that comes with it. The fit between the service and how your team already operates matters more than which platform can technically start a Node.js process.
Next.js 16 makes self-hosting straightforward
Next.js 16's documentation states the minimum platform requirement plainly: you need a Node.js server. A single next start process runs Server Components, ISR, Partial Prerendering, Cache Components, Server Actions, Proxy, and after(). Streaming and shared caching grow more important as the architecture spreads across replicas, and the application itself runs on a normal Node.js runtime.
For container deployments, enable standalone output:
This tells Next.js to use output file tracing and produce .next/standalone, a directory containing the production server and only the dependencies it actually needs. The resulting container is far leaner than one built by copying the whole project and node_modules into the image.
Once you have that standalone build, Azure's job simplifies to reliably running a container. That's the frame worth keeping while comparing the four services below: each one runs the same container differently, not a different application.
Azure Container Apps packages Next.js into a normal container and runs it without asking your team to operate a Kubernetes cluster. It provides the pieces a production web application actually needs:
horizontal replicas
HTTP-based autoscaling through KEDA
readiness and liveness probes
immutable deployment revisions
zero-downtime revision changes
traffic splitting
private networking
managed identities
KEDA scales replicas based on concurrent HTTP requests, CPU, memory, or other event sources, and you can set a minimum replica count if you want at least one instance running permanently instead of scaling to zero.
The revision model fits Next.js particularly well. Each deployment creates an immutable revision. In single-revision mode, Container Apps keeps the previous revision serving traffic until the new one starts successfully and passes its readiness checks. In multiple-revision mode, you can run two versions at once and split traffic between them.
text
Git repository
|
v
CI/CD pipeline
|
v
Container Registry
|
v
Azure Container Apps
|
+---- Next.js replica 1
|
+---- Next.js replica 2
|
+---- Next.js replica N
I'd start here when the application already has a Docker deployment model, Azure is a requirement, there's no existing organizational standard for another runtime, horizontal scaling is expected, private networking may eventually matter, and Kubernetes isn't otherwise needed. Container Apps solves the multi-replica problem on its own, which removes the usual reason teams reach for Kubernetes in the first place.
Option 2: Azure App Service
Microsoft positions App Service as a fully managed platform for HTTP-based web applications and APIs, and it can run from code directly or from a container. Next.js fits that description well.
App Service starts from the assumption that you have a web application you need Azure to run. Container Apps starts from the assumption that you have a containerized workload you need Azure to operate. Both cover a single Next.js application comfortably.
If an infrastructure team already has App Service plans, networking, monitoring, and deployment pipelines in place, I'd want a concrete reason before introducing Container Apps as an additional platform standard. Architecture fits the organization that has to operate it.
I'd choose App Service when the organization already uses it extensively, the workload is one conventional web application, existing security and networking patterns already exist around App Service, the operations team is comfortable supporting it, and advanced container orchestration features aren't particularly important. For many enterprise systems, fitting the established operating model carries more weight than picking the theoretically cleanest platform on its own.
Option 3: Azure Kubernetes Service
AKS gives you Kubernetes itself: the Kubernetes API, cluster-level configuration, namespaces, networking policies, operators, ingress controllers, and a substantially larger orchestration surface than Container Apps exposes. Microsoft describes AKS as leaning toward control, with the compute infrastructure and a larger share of the operational model staying visible to your team.
AKS control matters most for organizations that already operate a Kubernetes platform. Adding a Next.js deployment to an existing AKS platform running a customer portal, identity services, internal APIs, message processors, and an observability stack is a natural extension of infrastructure that's already there. A standalone stack of Next.js, PostgreSQL, Redis, and object storage rarely needs a Kubernetes platform built specifically to host it.
Microsoft also documents a real limitation of Container Apps worth knowing here: applications inside one Container Apps environment share an environment-level boundary. For workloads that need stronger separation between unrelated components, Microsoft recommends separate environments or AKS.
I'd choose AKS when Kubernetes is already part of the organization's platform strategy, the infrastructure team already operates clusters, the application forms part of a wider Kubernetes ecosystem, and you need Kubernetes-level networking, security, or isolation controls that Container Apps doesn't expose.
Option 4: Azure Static Web Apps
For a genuinely static Next.js application using HTML export, Static Web Apps is a natural deployment target. For a modern hybrid Next.js application, the picture is more limited.
Azure Static Web Apps supports App Router, React Server Components, SSR, Route Handlers, image optimization, middleware, and hybrid rendering, and Microsoft currently marks hybrid Next.js support as Preview. The documented limitations include a maximum application size of 250 MB for hybrid deployments and no support for ISR image caching, along with some Static Web Apps features and linked API scenarios that aren't available in the hybrid preview.
The architecture underneath is worth understanding on its own terms. Microsoft's hybrid model serves static content from the globally distributed Static Web Apps host while running Next.js backend functions on a dedicated App Service instance behind the scenes. It's a valid managed architecture, and it explains the current Preview label on the hybrid feature set.
For a substantial production application that needs Node.js execution, database access, private networking, and enterprise infrastructure controls, I'd currently make that runtime explicit through Container Apps or App Service.
I'd choose Static Web Apps for static Next.js websites, content-oriented sites that export cleanly to HTML, and teams specifically comfortable with the current hybrid Preview limitations.
Comparing the four services
This table isn't a checklist where one product wins on points. The right Azure service depends heavily on what your organization already knows how to operate, which is why the "best fit" row carries more weight than the others.
A reference architecture for production
For a substantial Next.js 16 application in an Azure-first organization, this is roughly where I'd start:
text
Internet
|
v
Azure Front Door Premium
TLS / CDN / WAF
|
Private Link
|
v
Azure Container Apps
Next.js 16
/ | \
/ | \
replica 1 replica 2 replica N
\ | /
\ | /
shared services
|
+-------------+-------------+
| | |
Database Object Store Shared Cache
Microsoft documents this pattern directly: Azure Front Door Premium reaches an internal Container Apps environment over Private Link, public network access to the Container Apps environment stays disabled, and the configuration can support zone redundancy. That setup earns its complexity in environments that need stronger network controls over time.
It's modular in both directions. A smaller application can start with Container Apps' own external ingress and skip Front Door entirely. A larger deployment can add Front Door, WAF, private networking, centralized identity, and managed secrets — I'd fold Infisical or another secrets manager into that layer rather than administer environment variables by hand; I go through that setup in Self-Host Infisical: Ultimate VPS Guide for Secrets. The container image stays the same across all of these variations.
The runtime is only one part of this picture. Database HA, backups, object storage, Managed Identity, private networking, and observability all sit around whichever compute service you pick, and I cover that surrounding architecture in full in Azure Web App Architecture: A Practical Production Reference Architecture.
What changes once you run more than one replica
Getting a Next.js container online is the easy part. The homepage loads, Lighthouse passes, everything looks fine with exactly one replica running. Once the application scales past one replica, several architecture decisions become unavoidable, and Next.js 16's documentation is far more explicit about them than earlier versions were.
Build once, deploy the same artifact everywhere
Next.js generates build-specific information during next build, and the framework recommends building once and starting every replica from that same artifact rather than rebuilding independently per instance:
text
Commit
|
v
next build
|
v
Docker image
|
v
Container Registry
|
+---- replica A
+---- replica B
+---- replica C
One immutable image represents one application deployment. Rebuilding per replica risks subtle mismatches between instances that are supposed to be identical.
Server Actions need a shared encryption key
Server Functions can contain encrypted closure variables, and Next.js generates an encryption key during the build for that purpose. In a multi-server environment, every instance in the deployment needs the same key, or one instance may receive a Server Action it can't decrypt. Next.js exposes this through an environment variable:
text
NEXT_SERVER_ACTIONS_ENCRYPTION_KEY
I'd manage this key through the organization's existing secrets-management approach, the same place API keys and database credentials already live.
Rolling deployments introduce version skew
During a rollout, a browser can hold assets and Server Function references from build A while its next request lands on build B — a mismatch that can produce missing assets, incompatible Server Function calls, or broken client-side navigation data. Next.js provides deploymentId specifically to catch this:
When the browser and server deployment IDs differ, Next.js falls back to a full page navigation instead of continuing an incompatible client-side transition. This pairs naturally with Container Apps revisions: Azure handles the infrastructure rollout while Next.js handles the moment two application versions briefly coexist in front of the same user.
Your cache becomes distributed state
By default, Next.js caching lives on the local server instance, and Next.js explicitly warns that multiple containers can end up holding different caches with different invalidation state. Next.js 16 addresses this with cacheHandlers for Cache Components and 'use cache: remote', letting you move the cache to an external store such as a key-value database when several instances need to share cached output.
text
Azure Container Apps
/ \
/ \
Next.js A Next.js B
\ /
\ /
shared cache
|
database
Next.js itself notes that most applications don't need a custom cache handler. Good reasons to add one include coordinating cache across replicas, protecting an expensive upstream API, or cutting repeated database load.
Streaming has to survive everything in front of Next.js
Server Components, Suspense, and Partial Prerendering progressively stream content to the browser instead of waiting for the full response. Self-hosted Next.js supports this natively, and Next.js explicitly calls out reverse proxies and load balancers as places where that streaming can get buffered away. The whole chain — browser, Front Door, Azure ingress, Next.js — needs to pass streamed responses through intact, and a passing HTTP 200 alone doesn't confirm that it does. I'd test streaming end to end rather than assume it from a health check.
Graceful shutdown needs enough drain time
Next.js documents graceful shutdown behavior for self-hosted environments: on SIGINT or SIGTERM, the server can finish in-flight requests and pending after() callbacks before terminating. The platform needs to allow enough drain time during a deployment or scale-in event for that to actually happen. It's a small infrastructure detail, and it's one someone now has to own explicitly.
Does Next.js 16 run natively on Azure without extra tooling?
Yes. Next.js needs a Node.js server, and all four Azure services covered here can provide one — Container Apps and AKS through containers, App Service through code or containers, and Static Web Apps through its hybrid Preview runtime for SSR features.
Is Azure Container Apps a good fit for a small Next.js project?
Yes, and it scales down cleanly. You can set a minimum replica count of zero for a low-traffic application and let KEDA scale up under load, which keeps costs close to App Service for small workloads while leaving room to grow into more replicas later.
Do I need Kubernetes to run Next.js in production on Azure?
No. Container Apps and App Service both handle autoscaling, health checks, and zero-downtime deployments without exposing Kubernetes. AKS becomes worth its complexity when Kubernetes is already the organization's platform or the application needs Kubernetes-specific networking or isolation controls.
Is hybrid Next.js on Azure Static Web Apps production-ready?
Microsoft currently marks hybrid Next.js support on Static Web Apps as Preview, with a 250 MB application size limit and no ISR image caching support. It's usable for teams comfortable with those constraints, and I'd currently prefer Container Apps or App Service for a substantial production application that needs the full Node.js runtime.
What's the biggest mistake teams make when self-hosting Next.js across multiple replicas?
Treating caching as automatically consistent across instances. Next.js caching defaults to the local server, so multiple replicas can silently diverge in what they've cached and invalidated unless you deliberately move to a shared cache handler.
Wrapping up
Every one of these four services can run a Next.js 16 application. What differs is which part of the Next.js operating model each one takes off your team's plate. App Service manages a web application platform. Container Apps manages a container platform. AKS hands you a Kubernetes platform directly. Static Web Apps offers a more opinionated deployment abstraction that's still catching up to hybrid Next.js.
For a new production Next.js 16 application inside an Azure-first organization, Container Apps currently gives me enough infrastructure abstraction to avoid managing Kubernetes directly, while still leaving room for Azure-native networking, identity, and operational controls as the application grows. When an organization already has a standard around App Service or AKS, following that standard beats introducing another platform for its own sake.
Let me know in the comments if you're running Next.js on Azure and which deployment model you settled on — I'm particularly interested in how other teams are handling multi-instance caching and rolling deployments with Next.js 16.
Thanks,
Matija
Scenario
Azure service I'd start with
New containerized production Next.js 16 application
Azure Container Apps
Organization already standardized on Azure App Service
Azure App Service
Organization already operates Kubernetes as a platform