# Getting started

Pick an integration and get mod_pagespeed 2.1 serving optimized pages: Apache or nginx module, Docker, IIS or ASP.NET Core, then run the same check.

Canonical URL: https://modpagespeed.com/docs/getting-started/

mod_pagespeed 2.1 is one product in two parts: a module that runs inside your
web server and an optimizer worker that does the heavy work beside it. Pick the
integration that matches how you serve pages, run the few lines under it, then
check the result with the same two requests. Every path below is free to
install and run; the software is licensed under the Apache License 2.0.

## Pick an integration

| You run                                                        | Install this                                                                               | Guide                                                                                                       |
| -------------------------------------------------------------- | ------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------- |
| Apache or nginx on Debian, Ubuntu or Enterprise Linux          | the native module and the `pagespeed-optimizer` worker from the signed package repository | [Install the module on Apache and nginx](https://modpagespeed.com/docs/installation-module/)                                        |
| cPanel / WHM with EasyApache 4                                 | the signed EA4 RPM                                                                         | [cPanel / EasyApache 4](https://modpagespeed.com/docs/cpanel/)                                                                      |
| Containers, Kubernetes, or an origin that is not Apache or nginx | the Docker reverse proxy, or the Helm chart, in front of your origin                     | [Install with Docker](https://modpagespeed.com/docs/installation-docker/) · [Deploy with Helm](https://modpagespeed.com/docs/helm-deployment/)              |
| IIS on Windows Server                                          | the native IIS module (MSI)                                                                | [Install on IIS](https://modpagespeed.com/docs/install-iis/)                                                                        |
| An ASP.NET Core application                                    | the `WeAmp.PageSpeed.AspNetCore` NuGet middleware                                          | [Install ASP.NET Core middleware](https://modpagespeed.com/docs/aspnet-getting-started/)                                            |

Already running a predecessor? The [upgrade and migration pages](https://modpagespeed.com/docs/upgrade/)
cover mod_pagespeed 1.15, ModPageSpeed 2.0, ngx_pagespeed, IISpeed and the
archived open-source module.

Installing with a coding agent? [Install with a coding agent](https://modpagespeed.com/docs/agent-install/) lists one machine-readable recipe per server, indexed at [modpagespeed.com/recipes/README.md](https://modpagespeed.com/recipes/README.md).

## Prerequisites

- **Native module:** Debian 12 or 13, Ubuntu 22.04 or 24.04, or RHEL, AlmaLinux
  or Rocky 9 or 10, with Apache 2.4 or newer or the distribution's stock nginx.
- **Docker reverse proxy:** Docker 24 or newer and Docker Compose v2; nginx
  ships inside the image, so you do not install it yourself.
- **IIS:** Windows Server 2016 or later with IIS 10, 64-bit.
- **ASP.NET Core:** .NET 8 or .NET 10.

> **One worker, two names**
>
> The optimizer worker is one program under two names. The container images and
> the NuGet package ship the binary as `factory_worker`. The deb and rpm packages
> install it as `/usr/bin/pagespeed-optimizer`, with the
> `pagespeed-optimizer.service` unit, host overrides in
> `/etc/default/pagespeed-optimizer` and its cache under
> `/var/cache/pagespeed-optimizer/v3`. A page that says `factory_worker` and a log
> line that says `pagespeed-optimizer` describe the same process.

## Quickstart: Apache or nginx module

```bash
# 1. Add the signed repository; the script detects apt or dnf
curl -fsSL https://packages.modpagespeed.com/install.sh | sudo sh
# 2. Install the module (apt-get on Debian/Ubuntu, dnf on Enterprise Linux)
sudo apt-get install mod-pagespeed             # Apache: also installs pagespeed-optimizer
sudo apt-get install nginx-module-pagespeed    # nginx
# 3. Restart the web server
sudo systemctl restart apache2                 # httpd on Enterprise Linux
sudo systemctl restart nginx
```

Apache optimizes immediately: the package enables the module, its default
`pagespeed.conf`, and the configuration that points it at the worker. On nginx,
the package loads the module itself (through `/etc/nginx/modules-enabled/` on
Debian and Ubuntu, `/usr/share/nginx/modules/` on Enterprise Linux), so do not
add a `load_module` line: nginx refuses to load the module twice.
`sudo grep -Rns '^[[:space:]]*load_module.*pagespeed' /etc/nginx /usr/share/nginx/modules`
shows the line the package added. Only a module you built or copied in by hand
needs `load_module modules/ngx_pagespeed_module.so;` (on Enterprise Linux
`load_module /usr/lib64/nginx/modules/ngx_pagespeed_module.so;`) at the top of
`nginx.conf`. Then turn the module on in a `server` block:

```nginx
pagespeed on;
pagespeed FileCachePath /var/cache/ngx_pagespeed;
```

Then [verify](https://modpagespeed.com/docs/getting-started/#verify-it-works). The
[module install guide](https://modpagespeed.com/docs/installation-module/) has the distribution matrix,
the nginx compatibility table and the two directives that hand nginx's in-place
optimization to the worker.

## Quickstart: Docker reverse proxy

```bash
docker run --rm -p 80:80 \
  --add-host=host.docker.internal:host-gateway \
  -e BACKEND_HOST=host.docker.internal -e BACKEND_PORT=8081 \
  -e ACCEPT_EULA=Y \
  ghcr.io/we-amp/pagespeed-combined:latest
```

Point `BACKEND_HOST` and `BACKEND_PORT` at your origin (`host.docker.internal`
is the Docker host; the `--add-host` line defines it on Linux); `ACCEPT_EULA=Y`
acknowledges the [Terms of Service](https://modpagespeed.com/terms/). The combined image runs nginx with
the module and the worker in one container, for evaluation and small single-host
deployments. Then [verify](https://modpagespeed.com/docs/getting-started/#verify-it-works) on port 80. For production, run the
worker and nginx as separate services from the
[Docker install guide](https://modpagespeed.com/docs/installation-docker/), or on Kubernetes with the
[Helm chart](https://modpagespeed.com/docs/helm-deployment/).

## Quickstart: IIS

Download the signed MSI from the [download page](https://modpagespeed.com/download/), run it on the
Windows Server host, then `iisreset`. Running the MSI takes every IIS site on
the server down for the duration; plan a maintenance window (details on
[Install on IIS](https://modpagespeed.com/docs/install-iis/#install-the-module)). The installer
registers the module as a native HTTP module and creates the default cache
directory. Then
[verify](https://modpagespeed.com/docs/getting-started/#verify-it-works). Running IISpeed on that host? Uninstall it first;
the two register the same handler. The [IIS install guide](https://modpagespeed.com/docs/install-iis/)
has the requirements, IIS Express and the optional optimizer service. The IIS
package ships as a signed installer on the mod_pagespeed GitHub release.

## Quickstart: ASP.NET Core

Add the `WeAmp.PageSpeed.AspNetCore` package to your project, then register the
middleware in `Program.cs`:

```csharp
builder.Services.AddPageSpeed();
app.UsePageSpeed();
```

Set `PageSpeed:Enabled` to `true` in `appsettings.json`, run the app and
[verify](https://modpagespeed.com/docs/getting-started/#verify-it-works) on your app's own port. The
[ASP.NET Core install guide](https://modpagespeed.com/docs/aspnet-getting-started/) has the exact
`dotnet add package` command, the `appsettings.json` section and the console at
`/console/`.

## Verify it works

Request any HTML page twice with GET:

```bash
curl -s -o /dev/null -D - http://localhost/
curl -s -o /dev/null -D - http://localhost/
```

Use GET, not `curl -I`: the Docker reverse proxy does not cache HEAD requests,
so a HEAD never turns into a HIT there.

- **Apache module:** `X-Mod-Pagespeed: <version>` on both responses. nginx and
  IIS module: `X-Page-Speed: <version>`. The header's presence means the module
  is loaded and active for that site.
- **Docker reverse proxy and ASP.NET Core middleware:** `X-PageSpeed: MISS` on
  the first response, `X-PageSpeed: HIT` on the second. Optimization is
  asynchronous: the first request serves the original bytes and notifies the
  worker; the second serves what the worker wrote.

No header, or `MISS` on every request? [Is it working?](https://modpagespeed.com/docs/is-it-working/)
lists every marker and the first checks to run;
[Troubleshooting](https://modpagespeed.com/docs/troubleshooting/) has the fixes.

## How the parts fit together

1. The **module** runs inside the web server (Apache, nginx, IIS) or, in the
   Docker reverse proxy, inside the bundled nginx. It classifies each request,
   serves an optimized variant when the cache has one, and otherwise passes
   the original through.
2. The **optimizer worker** runs beside it as its own process. It reads
   originals from the shared cache, builds optimized variants (image
   transcoding, CSS and JavaScript minification, critical CSS) and writes them
   back.
3. The **Cyclone cache** is the shared, memory-mapped file both of them open.

The native nginx module optimizes on its own until you set
`pagespeed DaemonSocketPath` and `pagespeed DaemonVolumePath`; the Apache
packages install that wiring; the ASP.NET Core middleware starts the worker
itself as a child process. [How it works](https://modpagespeed.com/how-it-works/) covers the mechanics.

### Request flow (nginx integrations)

1. nginx classifies the client's capabilities (image format support, viewport,
   transfer encoding, Save-Data) into a 32-bit capability mask.
2. The cache is checked for an optimized variant matching that mask.
3. **On a hit**, the variant is served from the memory-mapped cache file with
   `X-PageSpeed: HIT`: no copies, no origin round-trip.
4. **On a miss**, the request is proxied to your origin, the response is
   stored and served with `X-PageSpeed: MISS`, and the worker is notified. It
   optimizes the content and writes the variants back, so later requests for
   the same mask are hits.

## Safe cache mode

By default, mod_pagespeed runs in **safe cache mode**. Optimized resources are
cached for short periods (5 minutes for CSS/JS, 30 minutes for images) with
mandatory revalidation, so misconfigurations self-correct quickly. This is the
recommended mode while you validate your setup. See
[Cache modes](https://modpagespeed.com/docs/cache-modes/) for details and options.

## Next steps

- [Is it working?](https://modpagespeed.com/docs/is-it-working/): the header table and the first checks
- [Configuration reference](https://modpagespeed.com/docs/configuration/): all directives, worker
  flags and tuning options
- [Run in production](https://modpagespeed.com/docs/deployment/): permissions, logging and cache sizing
  per deployment shape
- [Monitoring](https://modpagespeed.com/docs/monitoring/): health, metrics and what to alert on
- [Troubleshooting](https://modpagespeed.com/docs/troubleshooting/): common issues and diagnostics

## Frequently asked questions

**Which mod_pagespeed 2.1 integration should I pick?**

The native module when you run Apache or nginx on Debian, Ubuntu or Enterprise Linux; the Docker reverse proxy when you are container-native or your origin is something else; the IIS module on Windows Server; the NuGet middleware inside an ASP.NET Core app. All four run the same optimization pipeline.

**How do I verify mod_pagespeed is working?**

Request a page twice with GET (`curl -s -o /dev/null -D -`). The native module adds `X-Mod-Pagespeed` (Apache) or `X-Page-Speed` (nginx and IIS) to the responses it handles. The Docker reverse proxy and the ASP.NET Core middleware answer `X-PageSpeed: MISS` first and `X-PageSpeed: HIT` once the worker has written the optimized variant.

**Does the native nginx module need the optimizer worker?**

No. It optimizes on its own. To hand in-place optimization to the worker, install the `pagespeed-optimizer` package of the same release and set `pagespeed DaemonSocketPath` and `pagespeed DaemonVolumePath` in the server block. The Apache packages install that wiring for you.

**What are the prerequisites?**

For the native module: Debian 12 or 13, Ubuntu 22.04 or 24.04, or RHEL, AlmaLinux or Rocky 9 or 10, with Apache 2.4 or newer or the stock nginx of the distribution. For Docker: Docker 24 or newer; nginx ships inside the image. For IIS: Windows Server 2016 or later. For ASP.NET Core: .NET 8 or .NET 10.

**What is safe cache mode and why is it the default?**

Safe mode caches optimized resources for short periods (5 minutes for CSS/JS, 30 minutes for images) with mandatory revalidation, so misconfigurations self-correct quickly. It is the recommended mode while validating a new setup before switching to aggressive.
