Skip to main content
VercelEdgePerformance

Architecting Edge-First Applications: Distributed Caching, Vercel Edge Runtimes, and Event-Driven Pipelines

elango
elango

Full Stack Engineer

Updated
5 min read
Architecting Edge-First Applications: Distributed Caching, Vercel Edge Runtimes, and Event-Driven Pipelines

Edge-first architecture on a solo portfolio site does not mean running every function on Cloudflare Workers worldwide. When I deployed elangodev.com to Vercel, I mapped each workload to the runtime that matched its latency and capability needs. Static marketing pages and ISR blog posts cache at the edge. The AI assistant streams from an Edge function. Database-heavy blog generation and chat mutations stay on Node.js where they can run up to 60 seconds and talk to AWS S3.

Vercel as My Global Entry Point

Vercel sits in front of my Next.js 16 App Router build as a distributed reverse proxy and build pipeline. Every push to main triggers a production deployment with compressed assets, automatic HTTPS, and regional edge caching for static files. I disabled the X-Powered-By header in next.config.ts and added security headers globally — small hardening steps that apply regardless of runtime.

Blog posts use incremental static regeneration. In app/blog/[slug]/page.jsx I export revalidate = 3600, so HTML is generated at build or first request then refreshed hourly. That gives me CDN cache hits for readers and crawlers — including Gemini and other bots I explicitly allow via htmlLimitedBots — without stale content living forever.

Edge Runtime for Low-Latency Streaming

The portfolio AI chat route is the clearest Edge win. Streaming Gemini responses must begin quickly; Edge functions start closer to users and avoid the 10-second Hobby-tier ceiling that blocked my early serverless experiments. I documented the choice directly in code:

// app/api/chat/route.js
// Optimize for Hobby Plan: Use Edge runtime to bypass 10s serverless limit
export const runtime = "edge";

const result = await streamText({
  model: googleProvider.languageModel("gemini-flash-latest"),
  messages: normalizedMessages,
});
return result.toDataStreamResponse();

Edge is wrong for every route though. My blog AI generator sets runtime = "nodejs" and maxDuration = 60 because it chains Gemini calls, JSON validation, image generation, and S3 uploads. Trying that on Edge would hit memory and duration walls immediately.

Retry-Hardened Server Fetches to Supabase

Even Node routes execute in ephemeral regions far from my Supabase project in ap-southeast-2. Transient ECONNRESET and abort errors showed up in Vercel logs during cold starts. I wrapped the Supabase server client with fetchWithServerRetry: three attempts, exponential backoff, 20-second timeout per try.

// app/utils/supabase/server.js
const fetchWithServerRetry = async (url, options) => {
  const fetchWithRetry = async (attempt = 0) => {
    const controller = new AbortController();
    const timer = setTimeout(() => controller.abort(), 20000);
    try {
      return await fetch(url, { ...options, signal: controller.signal });
    } catch (err) {
      if (attempt < 3 && isRetryable(err)) {
        await new Promise((r) => setTimeout(r, 500 * Math.pow(2, attempt)));
        return fetchWithRetry(attempt + 1);
      }
      throw err;
    }
  };
  return fetchWithRetry();
};

I attach this fetch wrapper to cookie-based clients, simple clients for static generation, and the admin client. That single pipeline prevents random 500s from becoming user-visible failures across contact forms, chat sends, and cron blog jobs.

Distributed Caching Layers I Actually Use

I do not run Redis on elangodev.com yet. My caching stack is Vercel CDN for static assets, ISR for blog HTML, and browser caching for service worker assets on the PWA-enabled chat shell. Supabase connection pooling handles database concurrency. For media I serve optimized AVIF/WebP through Next Image with remote patterns whitelisted for my S3 bucket and Supabase storage.

When cache invalidation matters — after publishing a post — revalidate windows refresh content without manual purges. Event-driven purges would be next if I added on-demand revalidation webhooks from Supabase triggers.

Pipeline Thinking Without Over-Engineering

Event-driven pipelines appear in my push notification flow: insert message, enqueue web-push sends, delete expired subscriptions on 410 responses. Failures in notification delivery never roll back the message row. That is a lightweight asynchronous pipeline implemented with Promise.allSettled rather than a managed queue service — appropriate for current traffic, easy to migrate later.

I log retry attempts from fetchWithServerRetry with attempt number and delay so Vercel log drains show whether Supabase blips correlate with region outages or cold starts. That observability is my substitute for a full distributed tracing stack on a personal site — good enough to decide when to upgrade plans or move cron jobs.

Architecting edge-first on a real site means choosing runtimes per route, caching at the layer that matches data freshness, and hardening server-to-database hops against regional latency. My Vercel deployment is not theoretically perfect; it is tuned to how elangodev.com actually fails and recovers in production logs.

I also watch Supabase dashboard metrics after major traffic spikes — connection count, slow queries, Realtime fan-out — the same way I watch Vercel function duration percentiles. Edge-first does not eliminate the database as a bottleneck; it moves latency savings to the layers users feel first. That mindset keeps portfolio demos and portfolio pages fast globally even though my Postgres primary lives in Sydney. When latency spikes, I adjust revalidate windows before buying more infrastructure — often the cache was stale, not the region. Edge-first is a scheduling discipline, not a marketing badge. I document runtime choices beside each route so the next refactor does not move a sixty-second S3 job to Edge chasing hype. That inventory lives in the same README I use when onboarding contractors to elangodev.com infrastructure.

elango

Written by

elango

Full Stack Engineer & Software Architect specializing in React, Next.js, and high-performance web applications.

Share on:

Discover More

View blog