Edge Functions in Practice: Real Use Cases Beyond the Hype
Edge functions run your code on servers distributed globally — close to your users instead of in a single region. Vercel Edge Functions, Cloudflare Workers, Deno Deploy, and AWS Lambda@Edge all offer this. The promise: lower latency for users worldwide.
The reality: edge functions are not universally better. They excel in specific scenarios and add unnecessary complexity in others. After deploying edge functions in production for a year, here is what I learned about where they genuinely help.
How Edge Functions Work
Traditional server: your code runs in one region (us-east-1, eu-west-1). A user in Tokyo makes a request that travels to Virginia (200ms+ round trip). Processing takes 50ms. Response travels back. Total: 450ms+.
Edge function: your code runs on the server closest to the user. The user in Tokyo hits a server in Tokyo. Request travels 5ms. Processing takes 50ms. Response travels 5ms. Total: 60ms.
The latency difference is dramatic for users far from your origin region. But: edge functions have constraints that traditional servers do not.
Edge Function Constraints
Limited runtime: Edge runtimes (V8 isolates) do not support all Node.js APIs. File system access, native modules, and some npm packages do not work. You run in a stripped-down JavaScript environment.
No persistent connections: edge functions are stateless and short-lived. You cannot maintain database connections (connection pooling does not work the same way). Each invocation is independent.
Cold starts: edge functions have cold starts (though typically faster than traditional serverless — 5-50ms vs 100-500ms). For sub-millisecond latency requirements: this matters.
Data locality: your code runs near the user, but your database might be in a single region. An edge function in Tokyo querying a database in Virginia still has 200ms of database latency. The edge proximity only helps if the data is also nearby.
Use Case 1: Authentication and Middleware (Excellent Fit)
Checking authentication tokens, redirecting users, setting headers — these operations: do not need database access (JWT verification is self-contained), are extremely latency-sensitive (every page load waits for middleware), and benefit from global distribution (users everywhere need auth checks).
Our implementation: Next.js middleware runs on the edge. It verifies JWT tokens, checks session cookies, and redirects unauthenticated users — all without hitting the origin server or database. The authentication check completes in 5-15ms regardless of user location.
Use Case 2: Geolocation-Based Content (Excellent Fit)
Serving different content based on user location: currency formatting, language selection, regional pricing, content restrictions. Edge functions have access to the user's geographic information (country, region, city from the request) and can customize responses without a round-trip to origin.
Our implementation: we detect user country on the edge and set appropriate defaults (language, currency display) without an additional API call. The personalization happens at the network level.
Use Case 3: A/B Testing and Feature Flags (Good Fit)
Assigning users to experiment variants and returning the appropriate content. Edge functions can: read the user's cookie (existing variant assignment), assign a new variant (if first visit), and modify the response (inject the correct variant's content).
This avoids the "flash of wrong content" that client-side A/B testing causes. The correct variant is served from the first byte.
Use Case 4: API Responses with Cached Data (Good Fit)
If your API response can be cached (tool listings that update every few minutes, blog posts, static data): serve from edge cache. The edge function checks cache freshness and either: serves the cached response (instantaneous) or fetches fresh data from origin and updates the cache.
This is essentially a CDN with logic — you can: add authentication checks before serving cached content, transform the response based on user context, and set custom caching headers.
Use Case 5: Full Application Rendering (Sometimes Good, Sometimes Not)
Running your entire Next.js application on the edge (using edge runtime): this works for pages that do not need database access or can use edge-compatible databases.
When it works: static pages, pages using cached data, pages using edge-compatible data sources (Turso/libSQL, Upstash Redis, Planetscale with their edge driver).
When it does NOT work: pages with complex database queries (your Postgres in us-east-1 adds 200ms to every query from a Tokyo edge), pages using Node.js-only libraries, and pages with heavy server-side computation (edge functions have CPU time limits).
When Edge Functions Add Complexity Without Benefit
Scenario 1: all your users are in one region. If 95% of your users are in the US: edge functions in Tokyo and Sydney serve almost nobody. A regional deployment (us-east-1) is simpler and serves your users equally fast.
Scenario 2: your data is not at the edge. Running code on the edge but querying a database in a single region does not reduce overall latency — you have just moved where the waiting happens. The database query is still the bottleneck.
Scenario 3: simple CRUD APIs. If your API just queries a database and returns results: the edge adds a hop without reducing total latency (edge → origin database → edge → user is not faster than origin → user when database latency dominates).
The Data Locality Problem
The fundamental challenge with edge computing: code can run anywhere, but data cannot (easily). Solutions:
Read replicas at the edge: databases like Turso (SQLite-based), Planetscale (MySQL with read replicas), and CockroachDB (globally distributed) can serve reads from edge-local replicas. Writes still go to the primary, but reads are fast.
Edge caching: cache frequently-read data at the edge (Redis via Upstash, KV stores on Cloudflare/Vercel). Stale data is acceptable for many read-heavy use cases.
Data denormalization: store pre-computed results at the edge. Instead of querying and joining at read time: pre-compute the response and cache it.
Our Architecture Decision
At AIDToolStack: we use edge for middleware (authentication, redirects, geolocation) and origin (Node.js runtime in a single region) for database-heavy pages. This gives us: fast auth checks globally, low-latency personalization, and full database access for content pages (acceptable latency because our primary audience is in a few regions).
If our audience were truly global and latency-critical: we would invest in edge-compatible data (Turso or Planetscale read replicas). For our current scale and audience distribution: the complexity is not justified.
Making the Decision
Use edge functions when: the operation does not need database access (or uses edge-compatible databases), latency matters for the specific operation (authentication, personalization), your users are geographically distributed, and the operation fits within edge runtime constraints.
Use traditional serverless/containers when: you need full Node.js compatibility, database operations are the bottleneck (not network latency), your users are concentrated in one region, and the added complexity of edge is not justified by latency improvements.
The honest answer for most applications: use edge for middleware and specific latency-critical operations. Use traditional runtime for everything else. The hybrid approach gives you the benefits without the constraints.
Written by AIDToolStack Editorial
The AIDToolStack editorial team reviews developer tools, AI products, and MCP servers with hands-on testing and honest assessments. We use the tools we review every day in production.
References & Further Reading
Related Posts
Sponsor Our Newsletter
Reach thousands of developers who are actively evaluating AI tools, MCP servers, and dev infrastructure. Our weekly newsletter goes to engaged technical decision-makers.
All sponsored content is clearly labeled per our editorial policy.