How it works

One redirect, and everything that has to be decided before it.

The mechanics, for anyone evaluating this rather than buying it. Status codes, evaluation order, what an unfurler gets instead of a redirect, and what is kept.

The hot path

What happens when somebody clicks.

  1. 01

    The request lands

    A GET for fixedlink.dev/:slug, or your own domain, at whichever edge location is nearest the visitor. No session is involved and none is read — short links never require one.

  2. 02

    The slug is resolved

    One lookup for a live link. On our domain a slug is global; on your domain it is scoped to that hostname, so two customers can both own /spring.

  3. 03

    Rules are evaluated

    Top to bottom, first match wins. Every condition on a rule must hold. Matching nothing is normal and gets the link’s own destination.

  4. 04

    The redirect goes out

    HTTP 302, not 301. A 301 is cached by browsers and intermediaries more or less permanently, which would make the destination un-editable — the one thing this product exists to keep editable.

  5. 05

    The click is recorded after the response

    Registered with the request context so the runtime keeps it alive past the redirect, and never awaited in front of it. Recording a click cannot be allowed to fail one.

A slug that does not resolve is a 307 to the home page carrying a notfound flag, rather than a bare 404 — someone holding a mistyped link off a poster gets told what happened instead of a browser error page.

Routing rules

How one click gets resolved.

Rules are checked in the order you put them in, and the first whose conditions all hold decides where the visitor goes. Nothing matching is a normal outcome, not a failure — so adding a rule can never make an existing link stop working.

One short link sending iOS visitors to the App Store, Android visitors to Google Play, and everyone else to the download page.go.acme.com/appon iOSthe App StoreRULE 1on AndroidGoogle PlayRULE 2everyone elsethe download pageFALLBACK

What a rule can test

Conditions on one rule are ANDed. To express “or”, add a second rule — which keeps each one readable in the dashboard, and keeps the order meaningful.

Everything here is decided from the request itself at the edge nearest the visitor. There is no round trip to a rules service and no client-side redirect.

Country
From the CDN’s own geo header. We never look up an IP ourselves.
Device
Mobile, tablet or desktop, parsed from the user agent.
OS and browser
iOS, Android, macOS, Windows; Chrome, Safari, Firefox, Edge.
Language
From Accept-Language, most-preferred first.
Referrer
The referring host, so t.co and x.com are separable.
Date window
Absolute from/to instants. The one that makes printed codes survive.
Time of day
A window in a named IANA zone, which may wrap past midnight.
Weekday
Days of the week, evaluated in that same zone.

Crawlers and unfurlers

A preview page, not a redirect.

An unfurler reads metadata without following redirects. Sent a 302 it would either show no card at all, or build one from the destination’s tags — never the ones you set on the link.

So a request from a known crawler gets an HTML page carrying the link’s own Open Graph tags, with a meta refresh so a human who lands on it still arrives at the destination. If the link has no preview worth showing, it falls through and is treated like any other visitor.

Rules are evaluated against the crawler, because it is the only visitor that request has. Date windows therefore behave exactly as intended — a poster whose sale has ended unfurls with the post-sale copy — while a device rule will essentially never match one, and so leaves the card alone.

Cached for five minutes

Unfurlers cache aggressively on their own account. A short TTL on our side means an edited preview appears in minutes rather than days.

Per rule, as well as per link

A routing rule can carry its own title, description and image. Fields it leaves null fall back to the link’s, so a rule only states what differs.

Custom domains

What connecting one looks like.

Two DNS records at your provider, an automatically issued certificate, and links serving from your own domain over HTTPS.YOU ADD, ONCECNAME links → edgeTXT _cf-custom…WE DO, AUTOMATICALLYVerify the recordsIssue the certificateLIVElinks.acme.comHTTPS, at the nearest edge

Two records

A CNAME pointing the hostname at the edge, and a TXT proving you control it. Both are shown to you with their values filled in.

Certificates

Issued once the records verify, and renewed without you. The dashboard shows the hostname and certificate states separately, because they fail separately.

Separate from the app

Short links are served from a different registrable domain than the dashboard, so nothing a link points at ever shares an origin or a cookie scope with a signed-in session.

What is stored

A click, and what it becomes.

One row per redirect: the link, a timestamp, the country from the CDN header, the referring host, and the device, browser and operating system parsed from the user agent at write time. Parsing on the way in is what keeps every breakdown a plain GROUP BY on the way out.

The visitor is a salted hash of the address, not the address. Counting unique visitors needs a stable key, not an identity, and this gives one without keeping something that identifies a person indefinitely.

Rows older than your plan’s retention are pruned on a schedule, in bounded batches.

Retention on Free
30 days
Retention on Pro
a year
Retention on Enterprise
as long as your policy says

Next

Build on it.

Everything here is reachable over the REST API — links, domains, routing rules and analytics, from the same endpoints the dashboard uses.

Looking for who uses it and what for? That is solutions.