Run in production
Production deployment guide for the mod_pagespeed 2.1 ASP.NET Core middleware: configuration, health probes, multi-instance scale, and zero-downtime restarts.
On this page
This page is for teams shipping the mod_pagespeed 2.1 ASP.NET Core middleware
(WeAmp.PageSpeed.AspNetCore) into a production ASP.NET Core deployment. If you
are still evaluating the middleware locally, start with
Install ASP.NET Core middleware instead.
The current NuGet release is v2.1.0. The middleware runs
in-process in your request pipeline and, by default, launches the factory_worker
binary from the same package as a child process to do the expensive work — image
transcoding and critical-CSS extraction — out of process. If you need an in-process
native module for Apache, nginx or IIS instead, see mod_pagespeed 2.1, where
the module runs in-process in the web server. The IIS package ships from the 1.15
packaging channel.
Prerequisites
- .NET 8 or .NET 10 runtime on your production host.
- An ASP.NET Core application that serves HTML responses.
- A supported runtime identifier —
linux-x64,linux-arm64,osx-arm64, orwin-x64. The meta-package resolves the matching native asset automatically at restore time.
Install
Add the NuGet package to your project. CI restores the correct native library for the target RID — no per-platform branching in your build.
dotnet add package WeAmp.PageSpeed.AspNetCore
If your build container differs from the deployment target, restore with an explicit RID so the native asset matches the production host:
dotnet publish -c Release -r linux-x64 --self-contained false
Wire up the middleware
Register the services and add UsePageSpeed() early in the pipeline, before
any middleware that writes to the response body:
using WeAmp.PageSpeed.AspNetCore;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddPageSpeed(builder.Configuration);
var app = builder.Build();
app.UsePageSpeed();
app.MapHealthChecks("/healthz");
app.MapRazorPages();
app.Run();
Bind a PageSpeed section in your configuration. For the full set of
PageSpeedOptions properties and hot-reload semantics, see the
ASP.NET Core configuration reference.
Cache backing
The middleware writes a single memory-mapped Cyclone volume file under
PageSpeed.Cache.VolumePath (default: /var/cache/pagespeed/volume.dat,
1 GB). For production:
- Set an explicit
PageSpeed__Cache__VolumePath(double-underscore for nesting) on a persistent volume so the cache survives container restarts and isn’t billed against ephemeral disk. The path is a single file, pre-sized toPageSpeed__Cache__VolumeSizeBytes. - Ensure the application user has read/write access to the file’s parent directory.
- Leave
CacheModeatSafefor the initial rollout. Safe mode addsmust-revalidateto asset responses so a misconfigured option recovers in minutes rather than hours. Switch toAggressiveonly after a stable baseline and with a CDN purge path available — see Choose a cache mode for the full trade-off.
Validate the deployment
After deploy, confirm the middleware is active:
curl -I https://your-app.example.com/
# X-PageSpeed: WeAmp.PageSpeed/2.1.0
curl -s https://your-app.example.com/healthz | jq .
# "status": "Healthy"
# entries, version
The /healthz endpoint reports Healthy, with the cache entry count and the
middleware version, while the cache is operational, and Unhealthy when the
cache cannot be opened — wire your monitoring to alert on Unhealthy.
The worker process exposes its own diagnostic console SPA out-of-process. The
middleware starts the worker with --api-no-auth on a loopback-only management
port (PageSpeed.Worker.ApiPort; an ephemeral port when left at 0), so the
API answers anything on the host and is never reachable off-host — the worker
refuses a non-loopback bind without a token. Reach it from the host or through
an SSH tunnel rather than by publishing the port.
Scale across multiple instances
mod_pagespeed 2.1 is licensed under Apache-2.0 and free to run in development and in production, so scaling out adds no software cost. Size replica counts for your traffic and availability needs.
Each instance maintains its own on-disk cache. There is no shared cache backing across replicas; each replica builds its own warm cache, which isolates cache state across instances.
Zero-downtime restarts
The middleware honors ASP.NET Core’s standard graceful-shutdown semantics.
On SIGTERM, in-flight requests complete against the existing cache before
the worker shuts down; new requests route to a fresh instance. Configure
your orchestrator’s terminationGracePeriodSeconds (Kubernetes) or
equivalent to at least 30 seconds so any mid-flight HTML rewrites complete
cleanly.
For container deployments, the Deploy to production guide covers the Docker / Helm shipping path; the systemd and Kubernetes patterns there apply equally to the NuGet middleware when wrapped in your own container image.
See also
- ASP.NET Core configuration reference — full options table, hot reload, environment-specific layering.
- License — Apache License 2.0, support subscriptions.
- Choose a cache mode —
SafevsAggressivetrade-offs and CDN guidance. - Troubleshoot common issues — diagnostic flow for cache and worker problems.
Frequently asked questions
Does scaling the ASP.NET Core middleware across multiple instances add per-server cost?
No. mod_pagespeed 2.1 is licensed under Apache-2.0 and free to run in development and in production, so scaling out adds no software cost — size replica counts for traffic and availability.
What does the /healthz check report?
Healthy, with the cache entry count and the middleware version, while the cache is operational; Unhealthy when the cache cannot be opened — wire monitoring to alert on Unhealthy.