CRUMB a card from devarno-cloud

Edge Redirect Flow

smo1 intermediate 6 min read

ELI5

When you click a short link, the edge worker is like a fast-food drive-thru speaker. It hears your order (the slug), checks the pre-made menu board (KV cache), and if the item is not on the board, it radios the kitchen (purr-api). Once it knows what you ordered, it immediately tells you which window to pull up to (the destination URL). The whole conversation takes less than a blink.

Technical Deep Dive

Sequence

%%{init: {'theme': 'base', 'themeVariables': {'primaryColor': '#e8f4f8', 'primaryTextColor': '#2d3748', 'primaryBorderColor': '#90cdf4', 'lineColor': '#718096', 'secondaryColor': '#f0fff4', 'tertiaryColor': '#fefcbf'}}}%%
sequenceDiagram
autonumber
actor U as User
participant CF as Cloudflare Edge
participant Z as zoomies-edge
participant KV as Cloudflare KV
participant API as purr-api
U->>CF: GET smo1.io/:slug
CF->>Z: Route to Worker
Z->>Z: Bot detection (UA check)
Z->>KV: GET link:{slug}
alt Cache HIT
KV-->>Z: Link data
else Cache MISS
Z->>API: GET /api/links/slug/:slug
API-->>Z: Link data
Z->>KV: PUT link:{slug} (TTL 300s)
end
Z->>Z: Check protection / session
alt Protected + no session
Z-->>U: Render protection prompt
else Redirect mode
Z->>Z: Append UTM params
Z-->>U: 302 Location: destination
else Proxy mode
Z->>Z: Reverse-proxy to destination
Z-->>U: Streamed response
end

KV Cache Layer

Cloudflare KV is a global, eventually-consistent key-value store. For SMO1:

  • Key: link:{slug} (e.g., link:abc123)
  • Value: JSON blob with url, userId, isActive, expiresAt, utmSource, utmMedium, utmCampaign, utmTerm, utmContent, redirectMode, protectionType
  • TTL: 300 seconds (5 minutes)
  • Consistency: KV is eventually consistent; writes may take up to 60 seconds to propagate globally. For most link shortener use cases, this is acceptable.

API Fallback

On cache miss, the worker calls:

GET https://purr-api-production.up.railway.app/api/links/slug/:slug

Response (simplified):

{
"id": "550e8400-e29b-41d4-a716-446655440000",
"original_url": "https://example.com/long/path",
"uid": "abc123",
"custom_slug": null,
"is_active": true,
"expires_at": null,
"utm_source": "twitter",
"utm_medium": "social",
"utm_campaign": "launch2025",
"redirect_mode": "redirect",
"protection_type": "none"
}

UTM Parameter Injection

If the link has stored UTM parameters and the destination URL does not already contain them, the worker appends them:

function appendUtmParameters(url: URL, link: LinkData): URL {
const params = ['source', 'medium', 'campaign', 'term', 'content'];
for (const key of params) {
const value = link[`utm_${key}`];
if (value && !url.searchParams.has(`utm_${key}`)) {
url.searchParams.set(`utm_${key}`, value);
}
}
return url;
}

Rule: Never overwrite existing UTM parameters on the destination. Precedence: destination URL > link configuration.

Redirect Response

For redirect_mode: "redirect":

HTTP/2 302 Found
Location: https://example.com/long/path?utm_source=twitter&utm_medium=social
Cache-Control: private, no-store
  • 302 (Found): Temporary redirect; browsers and SEO crawlers should continue to index the short URL, not the destination
  • Cache-Control: private, no-store: Prevents CDNs and browsers from caching the redirect, ensuring analytics and protection checks run on every visit

Latency Budget

StepTypical latency
DNS + TLS to Cloudflare20–50 ms
KV lookup1–5 ms
API fallback (rare)50–150 ms
UTM append + redirect<1 ms
Total (cache hit)25–60 ms
Total (cache miss)75–210 ms

Key Terms

  • KV namespace → Cloudflare KV binding (LINKS_CACHE) accessible from the Worker
  • Eventually consistent → KV writes may take up to 60 seconds to propagate to all edge locations
  • 302 Found → HTTP status for temporary redirect; preserves the short URL for future visits
  • UTM injection → Appending tracking parameters to the destination URL without overwriting existing values
  • Cache miss → When the requested slug is not found in KV, triggering an API call

Q&A

Q: Why 302 instead of 301? A: 301 is permanent and cacheable by browsers, which would break analytics and protection checks on repeat visits. 302 is temporary and forces re-validation on every click.

Q: What happens if a link is expired or inactive? A: purr-api returns an error or inactive flag. The worker treats this as “slug not found” and proxies to the landing page (typically showing a 404-style message).

Q: Can the edge worker serve a custom 404 page? A: Not directly. Unknown slugs are proxied to whiskers-landing, which can render a custom 404. The worker itself returns whatever the landing page returns.

Q: Why no-store instead of no-cache? A: no-store prevents the response from entering any cache (browser, CDN, proxy). no-cache allows storing but requires re-validation. For redirects, we want zero caching to ensure fresh analytics and protection state.

Examples

Think of the edge redirect like a valet parking service:

  • You pull up and say “I am here for reservation ABC123” (the slug)
  • The valet checks the reservation board (KV cache) — instant
  • If it is not on the board, he radios the main office (purr-api) — takes a few seconds
  • Once found, he tells you “Drive to Level 3, spot 42” (302 redirect)
  • He also hands you a parking pass with a promotional code (UTM params) if you did not already have one
  • If the reservation requires a password, he asks for it before giving directions (link protection)

neighbors on the map