Time-limited short links — expiring URLs done right

Expiring short links — when to use them, what HTTP code to return, and how to design the dead-link page so the offer still converts cleanly.

May 14, 2026 18 min read Linked.Codes
Time-limited short links — expiring URLs done right

Expiring short links exist for a reason most teams understate: a link is a promise about a destination, and some destinations stop being true. A flash-sale URL pointing at a sold-out product, a trial-signup token that should die after seven days, a payment QR on a poster that became invalid the moment the campaign ended — these are not links you want to keep redirecting to whatever the destination has become. Time-limited short links shut the door cleanly when the offer expires, with the right HTTP code, with a page that still respects the human who scanned it.

This post covers when to expire a link versus when to delete it, the four expiry policies that cover almost every real use case, the HTTP-code question that most platforms get wrong, and how to design the expired-link page so a stale poster still converts. There's also a working policy picker further down — pick the use case and the widget recommends an expiry rule, a landing target, and a status code. Time is one axis a redirect can switch on; geography is another, and the country-by-country destination-swap pattern for geo-targeted short links uses the same policy-picker shape with a different inspector at the front.

Three categories cover most expiring-link work, and they're worth keeping separate because the right policy for each is different.

Campaigns and offers that go stale. A 48-hour flash sale, a Black Friday window, a webinar registration that closes at the door, a promo code that runs through Friday. The destination URL is fine after expiry — the product still exists, the page still loads — but the offer is gone. Sending traffic to a "live" page that no longer matches the email or poster the user came from is worse than honest dead-end. They feel tricked.

Sensitive shares that should not outlive their purpose. A trial-signup token, a download URL for a paid asset, a one-time invitation link, a Dropbox-style share that should die after seven days. These are security boundaries dressed up as links. Letting them keep redirecting forever defeats the purpose of issuing them as time-limited in the first place. Expiry isn't a UX nicety; it's the spec.

Hygiene. A team that ships campaigns weekly accumulates short links faster than anyone can audit them. Auto-archive after 90 days of inactivity, auto-expire after a year of unuse — these aren't security policies, they're dashboard-cleanup policies. The link probably wasn't doing anything anyway; the expiry just makes that explicit and quiet.

The mistake worth avoiding: treating all three categories with the same policy. A flash-sale link expiring at 23:59 on the campaign date is not the same problem as a one-time download token, which is not the same problem as quarterly cleanup. They want different defaults. Test an expiry yourself: mint a link in the short-link builder, set the window to five minutes, then watch the destination flip to the expired state once the clock runs out.

Before and after expiry — what an expiring short link does at each state Before and after expiry — what each state should return BEFORE EXPIRY GET /k/sale → 302 Found Location: example.com/sale User reaches the live offer page. Click logged. Status: ACTIVE AFTER EXPIRY (RIGHT) GET /k/sale → 410 Gone + small body w/ live offer Search engines drop it. User sees a real next step. Status: HONEST DEAD-END AFTER EXPIRY (WRONG) GET /k/sale → 302 Found Location: example.com/ Soft-404. Hurts homepage SEO. User confused. Status: BAD DEFAULT
Most platforms ship the right column on the right, which is the wrong answer. The middle column — 410 Gone with a small body pointing at the live equivalent — is what RFC 9110 and Google Search Central both want.

The four expiry policies

There are four ways to tell a short link when to die, and each fits a different shape of problem.

Absolute date. The link works until 2026-05-31 23:59 UTC, then it doesn't. Best for time-bounded campaigns where the deadline is the same for every reader. A Black Friday URL doesn't care when the user got the email; it cares whether the campaign window is open. Pair this with a pre-expiry warning — a banner the day before, a "campaign ending" reminder — so internal teams aren't surprised.

N days from creation. The link expires seven days after it was issued, regardless of whether anyone clicked it. Best for sensitive per-user shares: trial signup tokens, file-share links, magic-link emails. Each user gets their own clock. Forty days from now, no holdovers. The clock starts when the link is generated, not when the user receives it — which is fine if your delivery is roughly real-time. When the share is also a private one (a client download, an NDA'd deck), stacking the N-days clock with a password gate is the natural combination — when a url shortener with password protection earns its keep covers which use cases want both layers and which want only one.

N clicks from creation. The link works for the first 100 clicks and then stops. Best for limited-supply offers — first 50 signups get 20% off, first 200 attendees get the swag bag. There's a race-condition warning here that nobody talks about and we'll get to in a section.

Manual off-switch with no clock. The link works until you flip a switch. Best when you don't know the right expiry yet but want to be able to kill the link cleanly without breaking the redirect host. Useful as a safety net behind any of the others — campaigns end early, exploits get found, partnerships go sideways. Always wire one of these in.

Decision tree for choosing the right expiry policy Which expiry policy fits the link in front of you Same deadline for every reader? YES NO Absolute date campaigns, sales, events Per-user clock? trials, file shares YES NO N days from creation 7-day file share, magic links Limited supply? N clicks from creation Manual
Four policies, three branching questions. Always wire a manual off-switch behind whichever automatic policy you pick — campaigns end early.

The HTTP code question — and why most platforms get it wrong

This is the section that matters most and the one most platforms quietly skip. When a short link expires, what does the server return?

RFC 9110 — HTTP Semantics is the current authoritative spec. It defines 410 Gone as: "the target resource is no longer available at the origin server and that this condition is likely to be permanent." That is exactly the situation an expired short link is in. The redirect rule existed; it doesn't anymore; that's deliberate, not an unknown.

404 Not Found is for "we have no idea — could be wrong URL, could be deleted, could never have existed." Less specific. Search engines treat 404 as "try again later, maybe it'll come back." They treat 410 as "remove this from the index, it's not coming back." For an expired link, 410 is the right answer.

Most short-link platforms ship 302 redirect to the homepage when a link expires. This is the worst of all worlds. The user lands somewhere unrelated to the click intent. Search engines see the redirect chain, follow it to the homepage, and start treating the homepage as the canonical destination of every expired URL — which, per Google Search Central, creates "soft 404" signals against the homepage and dilutes its ranking. You wanted to retire one URL; you ended up degrading the most important page on the site.

Take the stance: expired short links return 410 Gone. With a body. The body is small, branded, and usually contains a single sentence ("This offer ended on 2026-05-31") plus a link to the equivalent live offer. The status code is the machine signal; the body is the human signal. Both matter.

There are two edge cases. If the expiry is per-user and the user is just on the wrong device — they expect the link to work because they got it five minutes ago — return 403 Forbidden instead, with a body explaining how to get a fresh one. The semantic is "this exists but you can't have it" rather than "this is gone." And if the expiry is purely a hygiene auto-archive of a link nobody ever shared publicly, you can return 404 because the link basically didn't exist for the public anyway. Default to 410 for everything else.

410
The status code most expired short links should return, per RFC 9110 §15.5.11. Google Search Central treats 410 as a faster, harder de-index signal than 404. Returning 302 to the homepage is the most common default and the most damaging — it bleeds soft-404 signal onto your top-ranked page.

The expired-but-the-poster-is-still-out-there problem

QR codes printed on physical material outlive the campaigns they were generated for. A coffee-shop poster from October's promotion stays in the window through January. A conference-handout QR keeps getting scanned six months after the event. A magazine ad survives in dentists' waiting rooms for years.

If those QRs point at expiring short links, the failure mode is predictable: someone scans, the link 302s to your homepage, the user has no idea what just happened. The promotion they thought they were claiming doesn't exist; they don't know what to do next; they bounce.

The fix is not to make the link live forever — that's worse, because then "free coffee for the first 50" turns into "free coffee for everyone for two years." The fix is the expired-link page itself.

A good expired-link page has three properties. It returns 410 Gone so search engines know the URL is dead. It tells the user, in one line, what they were looking for and that it's over. And it offers the closest live equivalent: the current sale, the current event, the current trial — whatever the user-of-now would actually want. "The October coffee promo ended, but our November loyalty card is here →" converts surprisingly well, because the user already proved they're interested in the brand by scanning the QR.

This pattern is most important for QR codes specifically — the gap between when the print was made and when the user scans can be months. For short-links shared in email, the gap is days, and the consequences are smaller. But the policy is the same either way: never let an expired campaign URL silently redirect to your homepage.

"First 100 signups get 20% off" is a real campaign pattern. Click-limited short links are how you implement it at the link layer rather than at the application layer. The redirect server counts clicks, and click 101 returns 410 Gone (or 403 Forbidden if you want "we know who you are, you missed it" semantics).

There is a race condition here that most platforms do not document. At low concurrency, the counter increments cleanly: click 99 sees count=99, increments to 100, redirects. Click 100 sees count=100, increments to 101, redirects. Click 101 sees count=101, returns 410. Fine.

At high concurrency — a tweet hitting a million followers, a celebrity sharing the link, a bot scraping it — multiple requests arrive at the same millisecond. The naive implementation reads the counter, decides to dispatch the redirect, then increments. Five requests can all read count=99, all decide they're number 100, all redirect, then all increment to 101 (or worse, all increment to 100 because they all read 99). You wanted 100 winners; you got 104.

The fix at the edge is an atomic counter — Redis INCR, Cloudflare Workers Durable Objects, or a database with SELECT FOR UPDATE. The check-and-redirect happens against the post-increment value. If your platform handles click-limited links and doesn't tell you how it handles concurrency, assume it doesn't, and either pad the limit or use absolute-date expiry instead. For most campaigns this is a non-issue; for anything attached to a paid promotion or a regulated giveaway, ask before you ship.

SEO impact — what 410 vs 302 actually does to your site

An expired short link with backlinks pointing at it is a measurable SEO surface. Bloggers cite the URL, partners include it in their newsletters, the link survives in indexed search results until something changes.

If the expired URL returns 410 Gone, Google's documented behaviour is to drop the URL from the index relatively quickly — within weeks rather than months. The backlinks become dead-link signals against the source pages but don't transfer any signal back to your domain. Clean.

If the expired URL 302s to your homepage, the indexer follows the redirect, sees that the canonical destination of yourdomain.com/k/october-promo is now yourdomain.com, and starts to associate the homepage with the old URL's anchor text. If a hundred backlinks pointed at the expired link with anchor text like "October coffee promotion," your homepage starts looking like a page about an October coffee promotion. That's not what you wanted your homepage to rank for.

The fix is the same one already covered: return 410 with a body. The body keeps the user happy, the status code keeps the search engine happy, the backlinks de-index cleanly, and your homepage stays focused on the things you actually want it to rank for. This is the same domain-trust mechanic that makes a branded short-link domain worth setting up — your domain reputation lives or dies on the signals it sends.

Run expiring campaigns on your own domain — 410 by default, branded dead-link page included.

Try the lifetime tier

Marketing teams that ship campaigns regularly land on a lifecycle pattern that looks something like this. The campaign launches in six weeks. The short link gets created today, with absolute-date expiry set for twelve weeks from now — six weeks of campaign plus six weeks of grace for slow followers, screenshot-shares, and the long tail of social pickup. After twelve weeks, the link expires. The expired-link page points at the next live offer.

The numbers are arbitrary. The pattern isn't. Always set the expiry beyond the campaign's published end date, because the email someone forwarded last week gets opened today. Always build in a grace period; the question is just how much.

The other piece of this is the pre-expiry warning. Sixty days out, send a cron-job alert to whoever owns the link. Seven days out, send another. The day of, send a final. This avoids the "wait, that link expired?" Slack message at 9am the morning after the deadline. Most platforms can be configured to email or webhook these warnings — wire it in once and forget about it.

For email-distributed campaigns, the same pattern stacks with the UTM hygiene rules for short links: expiry policy belongs to the link itself, UTMs belong to the destination, and they need to be reasoned about separately. Expiring the link without rotating the UTMs leaves the next campaign inheriting the analytics dimension of the dead one.

Platform-launch campaigns are the cleanest fit for absolute-date expiry. A book launch that promotes a new Threads handle, a course drop pointing at a fresh creator profile, a conference pushing attendees to a launch-week post — every one of these has a six-to-twelve-week window, after which the printed QR should quietly retire its launch destination and either return a clean 410 or flip to whatever comes next. Building a Threads-launch QR with an expiring short link in the middle walks through this exact pattern from the print side, and the policy that fits it is the absolute-date-plus-grace one above.

Auto-archive vs auto-expire — they are not the same

These two get conflated and they're different operations.

Auto-archive hides the link from the dashboard. The redirect still works; the link just doesn't appear in the active-links list. Useful for cleaning up old campaigns from your management view without breaking anything anyone might still click. Reversible.

Auto-expire stops the redirect. The link is dead from the public's point of view. The dashboard still shows it (often in an "expired" tab), but visitors get the 410. Reversible only by extending the expiry date — the link was off, and now it's on again.

Pick the right one for the job. A two-year-old campaign that nobody clicks anymore wants archive — quiet the dashboard, leave the redirect alive on the off chance. A sensitive trial token wants expire — kill it on schedule, no exceptions. Confusing the two is how teams either accidentally delete production redirects (clicking "archive" on something they meant to delete) or accidentally leak access (assuming "archive" killed the link when it didn't).

Returning 410 Gone doesn't mean returning a blank page. The HTTP spec allows — and good UX demands — a body. Here is what should be in it.

One sentence at the top, plain English, telling the user what happened. "This sale ended on 31 May 2026." Not "Page not found" — that's a lie. Not "Sorry!" — that's a tone the user can't use. The literal what.

One link below it pointing at the closest live equivalent. The current sale, the current trial, the current product page. The phrasing matters: "See the current spring deals →" works better than "Go to homepage" because it implies the user's intent is being respected, not abandoned.

The page should match your domain's branding — header, font, primary colour. An expired-link page that looks like a 404 with monospace error text reads as broken. One that looks like the rest of your site reads as deliberate. The user came in via a branded URL; they should feel like they've landed in the same place.

Optional but useful: a small note about why the link expired, when, and what to do if they think it shouldn't have. Three lines maximum. Most users don't read these but the ones who do are usually about to email support, and the answer in the page reduces a ticket.

Pick a policy

Expiry policy picker
Use case
Expiry policy
Landing on expiry
HTTP code
Why this fit

The widget is opinionated on purpose. The defaults reflect what teams actually need — 410 for public retirement, 403 for sensitive per-user shares, an honest landing page in every case. If your current platform doesn't let you set a different status code per link or override the default redirect target, that's the gap to close.

What real-world use cases look like in the wild

Real-world expiring short link patterns Six expiring-link patterns and what each one wants Flash sale (48h) Absolute date + 14d grace 410 → live offers page Public, indexable, same deadline for all readers. Trial magic-link 7d from creation 403 → request-new form Per-user clock. Safer to offer fresh than extend. First-100 promo N clicks (atomic counter) 410 → still-available list Race-safe at the edge. Pad the limit by ~5%. Event RSVP Absolute date = event end 410 → event recap page +24h timezone grace. Recap converts to next. Confidential PDF share 30d + manual revoke 403 → ask sender Sensitive payload, manual kill switch always wired. QR poster campaign Absolute date, long grace 410 → next campaign Posters outlive campaigns. Always offer next step.
Six common patterns. The poster-campaign row is the one most teams skip — physical media keeps generating clicks for years after the campaign ends.

A pattern worth lifting from the grid: every public-indexable expiry uses 410. Every per-user sensitive expiry uses 403. Every expired page points at a live next step. None of them redirect to the homepage. That trio of rules covers most of the work.

What if you're using QR codes?

If your short link sits behind a QR code, the expiry conversation has an extra wrinkle. The QR is permanent — once printed, it cannot be changed. The short link can change. So the expiry happens at the link layer, not the QR layer.

This is why dynamic QR codes are a hard requirement for any campaign with a real expiry policy. A static QR encodes the destination URL directly; if the URL goes away, the QR is dead-on-arrival from that day forward, and you can't update what it points at. A dynamic QR encodes a short link, which then redirects; you control the redirect, you control the expiry, and you control the post-expiry landing page.

The combination — dynamic QR + branded short link + 410-with-body expiry + live-next-step landing page — is what makes a poster campaign work for the long tail. Six months after the campaign ended, the QR still scans, the user still gets a coherent landing experience, and the dead campaign doesn't poison the rest of the site.

What HTTP code should an expired short link return?

410 Gone for public-indexable retirement (campaigns, sales, events) — that's what RFC 9110 §15.5.11 specifies for known-permanently-removed resources. 403 Forbidden for per-user sensitive expiries (trial tokens, file shares) — the resource exists, the holder just is not allowed to use it. Avoid 302 to the homepage; it creates soft-404 signal on the page you most want to rank.

Should I just delete the link instead of expiring it?

No — deletion gives you 404, which search engines treat as "might come back, keep it indexed for now." Expiring with 410 is faster and cleaner: the URL is gone for good and the index drops it. Delete only after the link has been 410-ing for several months and there are no inbound backlinks of value left.

Can a click-limited link replace an expiry date?

Sometimes. For finite-supply offers (first 100 signups), click-limit is the natural fit. For time-bounded offers (Black Friday weekend), absolute-date is what users expect. Many real campaigns combine both — fixed end date, but cuts off at N redemptions if it hits sooner. Pad the click limit by 3-5% to absorb concurrency-related overcounts.

How do I tell users a link has expired?

Branded page on the same domain, returning 410, with one sentence ("This offer ended on 31 May 2026"), one link to the live equivalent ("see the current spring deals"), and matching site styling. Three lines tops. Avoid the words "Sorry," "Page not found," or "Error" — the link did exactly what it was supposed to do.

What happens to QR codes pointing at expired links?

The QR keeps scanning forever — it cannot be updated post-print. The short link is what expires. Use a dynamic QR (which encodes a redirectable short link rather than a hardcoded URL) and design the post-expiry page assuming a poster from six months ago is still scanning into it today. Never let an expired payment QR or coupon QR redirect to your homepage.

Does an expired link still hurt my SEO?

If it returns 410 with a body, no — Google de-indexes the URL and inbound backlinks become dead links against the linker, not signal flowing into your domain. If it returns 302 to the homepage, yes — Google treats the homepage as the redirect target, anchor text from the dead URL starts associating with your homepage, and you dilute what you actually rank for.

Should auto-archive and auto-expire be the same thing?

No. Auto-archive hides the link from your dashboard but keeps the redirect alive — useful for cleanup. Auto-expire stops the redirect — useful for security and for retiring offers. Confusing them is how teams either delete redirects they meant to hide, or leak access by assuming "archive" killed the link when it didn't.

Sourcesshow citations

Try it on your own domain

Branded short links and dynamic QR codes, on your subdomain or your own domain. One-time purchase, no per-click fees.