# HTTP 308 Permanent Redirect — Status Code Meaning & Examples

> The resource moved permanently, and clients must repeat the same method and body at the new URL.

308 is the permanent counterpart to 307: the resource has a new home, search engines should index the new URL, and clients must not change the request method. Next.js uses it for `permanent: true` redirects, and it's the right choice when moving API endpoints that accept POST or PUT.

- Class: 3xx Redirection
- Retry: Not applicable
- Cacheable by default: yes
- Defined in: [RFC 9110 §15.4.9 — 308 Permanent Redirect](https://www.rfc-editor.org/rfc/rfc9110.html#section-15.4.9)

## Example response

```http
HTTP/1.1 308 Permanent Redirect
Location: https://www.example.com/docs
```

## When you'll see it

- Permanent redirects in Next.js (`permanent: true`) and on Vercel.
- Moved API endpoints.
- Trailing-slash normalisation in many frameworks.

## How to use it well

1. Treat it like a 301 for SEO — Google consolidates signals to the target URL.
2. Very old clients (Internet Explorer on Windows 7 and earlier) don't understand 308; use 301 if you must support them.

## Send a 308 from your server

### Express

```
res.redirect(308, "https://www.example.com/docs");
```

### Next.js route handler

```
return NextResponse.redirect(new URL("https://www.example.com/docs", request.url), 308);
```

### Flask

```
return redirect("https://www.example.com/docs", code=308)
```

### Go net/http

```
http.Redirect(w, r, "https://www.example.com/docs", http.StatusPermanentRedirect)
```

### nginx

```
return 308 https://www.example.com/docs;
```

## FAQ

### 301 or 308 for SEO?

Google treats them the same. Choose 308 when the method must be preserved (APIs), and 301 when it doesn't matter.

## Related status codes

- [301 Moved Permanently](https://www.devkult.com/http/301.md)
- [307 Temporary Redirect](https://www.devkult.com/http/307.md)
- [410 Gone](https://www.devkult.com/http/410.md)

Open the interactive page: https://www.devkult.com/http/308