An HTTP redirect tells a client to make another request at a location named in the Location response header. The main choices are whether the move is permanent and whether the redirected request must preserve its method and body.

Redirect decision table

SituationUseMethod handling
Permanent move for a normal page or GET resource301A user agent may change POST to GET.
Temporary move for a normal page or GET resource302A user agent may change POST to GET.
Result of a POST is available at a separate GET URL303The follow-up request is GET or HEAD.
Temporary move that must preserve the method and body307Method and body are preserved.
Permanent move that must preserve the method and body308Method and body are preserved.

For GET and HEAD, 301 and 302 are usually sufficient. For an API request such as POST, PUT, or PATCH, use 307 or 308 when replaying the same method and body at the destination is intentional and safe.

301 Moved Permanently

Use 301 when a resource has a new permanent URL. Browsers, caches, and search engines can remember the destination. A client is allowed to turn a redirected POST into GET, so do not use 301 when the body must reach the new URL unchanged.

HTTP/1.1 301 Moved Permanently
Location: https://example.com/new-path
Cache-Control: public, max-age=86400

For site migrations, point each old URL to its closest equivalent. Do not send every removed URL to the home page.

302 Found

Use 302 when the redirect is temporary and the original URL should remain the main address. Common uses include short maintenance windows and temporary routing changes.

Like 301, a user agent may change POST to GET. Use 307 if method preservation matters.

303 See Other

Use 303 after an operation when the client should retrieve the result with GET. It is useful in the post/redirect/get pattern: a form submission creates or changes something, then the browser is sent to a result page that can be refreshed safely.

HTTP/1.1 303 See Other
Location: /orders/1234

307 Temporary Redirect

Use 307 for a temporary redirect that must preserve the request method and body. A POST remains a POST. This is useful for temporary API routing, but only when the destination is prepared to process the same request.

308 Permanent Redirect

Use 308 for a permanent redirect that must preserve the request method and body. It is the method-preserving counterpart to 301.

Be cautious with non-idempotent requests. A redirect, retry, or network failure can cause a client to submit the request again. Use idempotency keys or another deduplication mechanism when duplicate processing would be harmful.

Redirect caching at a CDN

Permanent does not mean “cache forever.” Set an explicit cache policy that matches how quickly you may need to reverse the redirect.

  • Test a redirect with a short TTL before increasing it.
  • Include only the request attributes that genuinely change the destination in the cache key.
  • Purge the cached response when the destination changes.
  • Check both the CDN response and the origin response; a redirect may be generated at either layer.
  • Avoid caching user-specific redirect destinations in a shared cache.

301 and 308 are defined as heuristically cacheable. Other redirect responses can also be stored when explicit caching rules allow it. Verify the behaviour of the CDN in use rather than assuming every intermediary handles redirects identically.

Google documents permanent server-side redirects such as 301 and 308 as strong signals that the destination should become canonical. Temporary redirects such as 302 and 307 signal that the source should normally remain in search results. That distinction is more precise than claims that one code “passes link equity” and another does not.

For a URL migration:

  1. Redirect directly to the final canonical URL.
  2. Update internal links, canonical tags, hreflang, and sitemap entries.
  3. Keep redirects in place long enough for users, crawlers, and old links to move.
  4. Do not create redirect loops or long chains.
  5. Return 404 or 410 when no relevant replacement exists.

Test a redirect

Inspect the response without automatically following it:

curl -sS -D - -o /dev/null https://example.com/old-path

Follow the complete chain:

curl -sS -L -D - -o /dev/null https://example.com/old-path

Confirm the status, Location, cache headers, number of hops, final status, and whether a non-GET method changes.