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 endKV 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/:slugResponse (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 FoundLocation: https://example.com/long/path?utm_source=twitter&utm_medium=socialCache-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
| Step | Typical latency |
|---|---|
| DNS + TLS to Cloudflare | 20–50 ms |
| KV lookup | 1–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
- Click Tracking Pipeline debugging missing or duplicate click counts
- Multi-Layer Caching Strategy debugging stale link data