# Expires Header — Syntax, Values & Examples

> The HTTP/1.0 way to say when a response goes stale. Cache-Control: max-age overrides it.

Expires holds a date; until then, caches may reuse the response without asking. It predates `Cache-Control` and has two weaknesses: it depends on the client's clock being right, and it has to be recalculated for every response. When `Cache-Control: max-age` or `s-maxage` is present, caches ignore Expires.

- Type: Response header
- Category: Caching
- Defined in: [RFC 9111 §5.3 — Expires](https://www.rfc-editor.org/rfc/rfc9111.html#section-5.3)

## Syntax

```http
Expires: <http-date>
```

## Examples

```http
Expires: Thu, 15 Oct 2026 12:00:00 GMT
```

stale after this moment

```http
Expires: 0
```

an invalid date, which caches treat as already expired

## Good to know

- Prefer `Cache-Control: max-age`; Expires only matters for very old HTTP/1.0 caches.
- Any invalid value, including `0`, means already expired.
- nginx's `expires` directive sets both Expires and `Cache-Control: max-age`.

## How to set Expires

### nginx

```
location /static/ {
  expires 30d;  # sets Expires and Cache-Control: max-age=2592000
}
```

### Apache (mod_expires)

```
ExpiresActive On
ExpiresByType image/png "access plus 1 month"
ExpiresByType text/css "access plus 1 week"
```

### Express

```
// Cache-Control does the real work; Expires is for HTTP/1.0 caches
res.set("Cache-Control", "public, max-age=3600");
res.set("Expires", new Date(Date.now() + 3600 * 1000).toUTCString());
```

## Check it

Fetch only the response headers and filter for Expires. In the browser, it's under Response Headers in DevTools → Network.

```sh
curl -sI https://example.com/ | grep -i '^expires:'
```

## FAQ

### Do I need Expires if I send Cache-Control?

No. Every cache in use today understands Cache-Control, and max-age takes precedence over Expires when both are present.

## Related headers

- [Cache-Control](https://www.devkult.com/headers/cache-control.md): Directives that tell browsers and CDNs whether, where and for how long a response may be cached.
- [Age](https://www.devkult.com/headers/age.md): How many seconds a response has been sitting in a shared cache such as a CDN.
- [Last-Modified](https://www.devkult.com/headers/last-modified.md): The date and time the server believes the resource last changed.

## Further reading

- [HTTP caching explained](https://www.devkult.com/blog/http-caching-explained.md)

Open the interactive page: https://www.devkult.com/headers/expires