← Blog Developers · 4 min read

When to choose 301 and when 308 is the right answer

The difference is not permanence. It is what happens to the request method and the body.

By ShortFreeURL Team · 24 August 2026

Both mean permanent, which is the least interesting part

A 301 and a 308 both tell the client that the resource has moved permanently and that it should update any stored reference. Caches may retain them for a long time, browsers store them aggressively, and search engines treat both as a signal to transfer to the new location. If permanence were the only axis, there would be no reason for two codes to exist.

The reason 308 exists is a defect in how 301 was implemented in practice. The specification for 301 originally did not permit clients to change the request method, but nearly every browser did so anyway, converting a POST into a GET when following the redirect. The behaviour became so universal that it was eventually documented as reality. 308 was defined to provide what the original text intended: a permanent redirect that must preserve the method and the body.

The practical rule

If the request could ever be anything other than a GET, and you want that method preserved, use 308. If the request is always a GET, or if you actively want a POST turned into a GET at the new location, 301 is correct and is the safer choice for compatibility.

For short links this resolves quickly. A short link that a person clicks is fetched with GET. Nobody POSTs to a marketing link. The method question does not arise, so 301 is appropriate on the merits and has the advantage of being understood by every client ever written, including old scanners, embedded browsers and command line tools.

Where 308 genuinely earns its place

API endpoints. If you are moving an API from one path or host to another and clients send POST, PUT, PATCH or DELETE requests, a 301 will silently convert those into GETs in many clients. The client sees a 200 or a 405, the write never happens, and the failure mode is a data loss bug that is extremely difficult to trace from the client side. 308 preserves the method and the body, so the write lands at the new location.

The same applies to form submissions that post to a URL you are retiring, and to webhook receivers whose URL has changed. In all of these cases the body is the point, and a redirect that discards it is worse than an error.

What temporary looks like on the same axis

The temporary pair mirrors this exactly. A 302 is the historically ambiguous one that clients treat as method-changing, and 307 is the strict version that preserves the method. So the grid is: permanent and loose is 301, permanent and strict is 308, temporary and loose is 302, temporary and strict is 307.

Reach for a temporary code when the mapping is genuinely expected to change: a link that rotates between destinations, an A/B split, a maintenance page, a seasonal target. Reach for a permanent code when the new location is the answer forever.

Caching is the part that bites

A permanent redirect can be cached by the browser essentially indefinitely, and browsers do this. If you publish a 301 pointing at the wrong destination and then correct it, everyone who already clicked may continue to be sent to the old target from their local cache, sometimes for weeks, and clearing site data is not something you can ask an audience to do.

This is the strongest argument for using a temporary code on any short link whose destination is not final. A short link is a piece of infrastructure whose whole value is that it can be repointed. Permanently caching it in a hundred thousand browsers negates that value for exactly the links you are most likely to need to change.

The default for a marketing short link should be a temporary redirect, so the destination stays changeable and click counting stays reliable. Cached redirects do not reach your server and therefore do not increment your click counts, which is a second, quieter reason to avoid permanent codes on anything you are measuring.

Reserve permanent codes for structural moves: an old short domain retired in favour of a new one, a bulk migration where every old slug maps to a new slug and will never change again. Those are the cases where you want the caching, because the point is to stop receiving the traffic at all.

Test the code, do not assume it

Platforms differ, defaults change between versions, and a proxy or CDN in front of your redirect may rewrite the status. Check what your links actually return with a request that prints the status line, and check it after any change to your edge configuration.

It is worth putting this into an automated check for the handful of links that matter most. A test that asserts the status code and the exact Location header for your top campaign links will catch a configuration change that nobody meant to make, and it will catch it before a customer does.

Related posts

Start Free — no credit card

The free plan includes 1,000 links, 6 custom domains and 50,000 tracked clicks a month, free forever. Choose a free subdomain from six shared domains. Paid plans start at $4 a month when you outgrow it, and you keep everything you have built.