Auto-Expiring Content — Designing Away "Forgot to Take It Down"

Giving campaign pages and event galleries an expiration date so they go private on their own when the time comes

expiring contentauto expirationtemporary pagescampaign landing pagesite operations
8 min read

Introduction

The campaign ended last week, but the announcement page is still up. If you run an e-commerce site, you have probably run into this at least once. When an expired discount or a sold-out perk is still on display, users reasonably assume the offer is still running.

This article walks through the big picture of a system that gives temporary pages and event galleries an expiration date, then takes them down automatically when that date arrives — no human involved. What parts it is made of, the thinking behind the design, and how day-to-day operations change. The finer details live in the related articles, so start here for the overall shape.

Why Leaving Old Pages Up Misleads Users

An expired campaign left online creates price mismatches

Publishing a campaign landing page or a sale announcement is the easy part. The work is in taking it down afterward. When things get busy, cleanup slides to the bottom of the list, and expired prices and perks keep showing.

Price mismatches are the costly ones. "The amount on your site was different" takes support time to resolve and chips away at that user's trust in you. Forgetting to take a page down isn't just a missed task — it belongs on the list of operational risks that touch revenue and credibility directly.

Checklists stop working the moment the person in charge changes

"We'll just delete it when it's over" sounds fine until several campaigns run in parallel. Then tracking which page comes down on which date becomes work in itself. The person in charge was off that day, the handover missed it, nobody remembered publishing it at all. Being careful doesn't reliably prevent any of that.

Internal checklists and reminders can patch the gap, but they depend on specific people and break down when staff change. Building something that doesn't lean on human attentiveness ends up being both the most reliable option and the least effortful one.

Decide when it disappears at the same moment you publish it

The approach that worked is simple: decide the lifespan of a page at the moment you create it. When publishing, you enter an expiration such as "valid through the end of March." From there the system watches the clock and retires the page when the time comes.

Instead of leaving cleanup as a task for future you, it becomes one extra field at creation time. Just reversing that order removes almost every case of stale content lingering. The point is to build it in as an input, not to enforce it as an operating rule.

Two ways of thinking about operations
BEFORE
Cleaning up later

Publishing is easy, but the takedown depends on whoever remembers it. Forget once and stale information stays up

AFTER
Deciding lifespan at creation

Set an expiration when you publish. The system retires it automatically, and the cleanup task disappears

In short, cleanup moves from being a task you do later to being a value you set while creating the page.

The System Is Made of Three Parts

A place to store, a watcher, and a check at display time

There are three pieces here. First, storage that holds the content and its expiration date. Second, a scheduled job (cron — a mechanism that runs a process automatically at a time you choose) that checks expirations and retires content. Third, the check on the public page that decides whether to show it.

Each has its own job, which makes it easy to add features later or swap out one piece without touching the others. Keep this three-part set in mind and the individual articles become much easier to follow.

The auto-expiration system at a glance
Admin screen

Protected by one-time codes Set body, images, expiration

KV storage

Holds the content itself and the expiration date

Checked once a day
Scheduled job (cron)

Finds expired items and unpublishes them

Public page

After expiry: a notice or a 404

Put in one line: you create a page with an expiration in the admin screen, a daily job watches that expiration, and the public page checks it again every time someone opens it.

No database — just KV

A feature of this size didn't need a full database. Temporary pages and event galleries aren't numerous, and there are no complicated relationships between records. So the whole thing runs on Vercel KV (a key-value store — you give it one name and it hands back what you stored under it).

That drops table design, migration work when the data shape changes, and connection management entirely, which makes both launch and operation lighter. Build small, grow it if the need appears. For supporting features, that call pays off.

The admin screen is guarded by one-time codes

The admin screen that creates temporary pages obviously can't be open to anyone. At the same time, bolting full permission management onto a small internal tool would be overkill. So it's guarded with one-time password authentication (OTP — a disposable code delivered by email).

You enter the code that arrives and you're in, which keeps the risk of reused or leaked passwords low while staying quick to use. Matching the strength of the guard to the nature of the tool is the practical choice.

Deleting and Unpublishing Are Different Jobs

Removing the data versus flagging it as expired

There are two ways to make something disappear on schedule. One uses the KV store's TTL (Time To Live — you set a lifespan when saving, and the data is removed automatically once that time passes). The other has the scheduled job watch the expiration and flip a flag that takes the page out of public view.

Both stop the page from being visible, but what happens afterward differs. Is the data gone, or is it still there and simply hidden? Knowing that difference lets you pick the one your requirement actually calls for.

The table comes down to one question: do you want to show anything after expiry? That decides the method.

What to show when someone opens an expired page

What you return to a user who lands on an expired page matters more than you'd expect. A 404 (the response meaning the page doesn't exist) is one option, but for a URL that spread on social media and gets clicked later, "this page is no longer available" is the kinder answer.

With the flag approach, the data is still there, so switching to a notice is easy. Rather than treating expiry as instant deletion, deciding how the page ends gives you more room to work with.

If deadlines are day-level, once a day is enough

The expiration check runs once a day. You might wonder whether that's often enough, but campaign and event deadlines are nearly always day-level — "valid through this date" — and nobody needs minute-level precision.

Raising the frequency raises the number of runs and the monitoring that comes with them. Choosing a cadence that isn't excessive for the requirement is part of keeping the system light. For the rare content that truly needs to stop the second it expires, add TTL alongside it.

Summary

Auto-expiring content isn't a flashy feature. What it does is guarantee that old information doesn't stay up — through the system rather than through anyone's attentiveness. The more campaigns you run at once, the more you feel the relief of never having to take anything down.

Two things to remember. Decide the lifespan when you publish, and choose between deleting and hiding based on the use. Features like this — an admin screen plus a scheduled job — are also the kind of thing you can build alongside an AI agent, as long as you can describe clearly what you want it to do.

If you want the details, the articles below go deeper.