Edge Functions, Custom Domains, and the DNS Plumbing Underneath

Edge Functions, Custom Domains, and the DNS Plumbing Underneath

You pushed your Cloudflare Worker, mapped a custom domain, and watched the deployment succeed. Then a colleague pings you: “It’s still hitting the old server.” You check your code. The logic is correct. You check the dashboard. It shows the worker is active. The problem is not in your function at all. It is in the layer below the layer most developers stop thinking about once the deployment light turns green: DNS.

What You Need to Know Before You Ship

  • A successful deployment and correct DNS propagation are two completely separate events
  • Nameserver delegation determines which network intercepts your traffic before any routing rule fires
  • Cloudflare Workers require NS transfer; Vercel Edge and Deno Deploy work with CNAME records only
  • Run a DNS lookup against a neutral resolver to verify propagation before closing the deployment ticket
  • Many routing failures that look like app bugs are silent DNS misconfigurations at the edge layer

The Gap Between “Deployed” and “Live”

Edge platforms give you a confident green checkmark the moment your function is packaged and distributed across their network. That checkmark means the function exists at every point of presence. It does not mean traffic from your custom domain is reaching it yet. Those are two separate systems, and the second one is entirely DNS.

When a browser resolves api.yourdomain.com, it does not ask your edge platform anything. It asks the nameserver authority for yourdomain.com. That authority replies with whatever records you have published. If those records point to your old origin, that is where the request goes, regardless of what your Cloudflare or Vercel dashboard says.

This gap catches experienced developers off guard because most deployment systems they have worked with treat “deploy” as the final step. CDN distribution, SSL issuance, routing rules, and traffic control collapse into that one action. Edge function platforms work differently. The function deployment and the traffic routing are independently configured, and DNS is the bridge between them.

How Each Platform Handles the Custom Domain Bridge

Cloudflare Workers, Vercel Edge Functions, and Deno Deploy each approach custom domains differently. Understanding those differences prevents you from applying the wrong mental model when something fails.

Cloudflare Workers can be reached via two paths: a *.workers.dev subdomain that always works after deploy, and a custom domain you configure in the dashboard. For the custom domain to route traffic to your worker, Cloudflare must be the authoritative nameserver for that domain. If your domain’s NS records point somewhere else, Cloudflare cannot intercept the request regardless of how the worker route is configured.

Vercel takes a different approach. It does not require you to transfer nameserver authority. Instead, it asks you to add a CNAME record pointing your subdomain to cname.vercel-dns.com, or an A record for apex domains. Vercel’s edge network resolves incoming requests for that subdomain and routes them to your deployment. Vercel uses its own certificate infrastructure to handle TLS once that CNAME is in place.

Deno Deploy behaves similarly to Vercel in this respect. You point a CNAME at a Deno-controlled endpoint, and their network handles the rest. You do not need to migrate nameservers. But because CNAME records at the apex level are technically invalid per the DNS specification, both platforms require workarounds for root domains, either ALIAS records or A records backed by their IP ranges.

Edge Platform Custom Domain Requirements at a Glance

Platform Nameserver Transfer Required Subdomain Record Type Apex Domain Solution
Cloudflare Workers Yes (for custom routes) CNAME or A (proxied) Proxied A record
Vercel Edge No CNAME A record (Vercel IPs)
Deno Deploy No CNAME ALIAS or A record

Nameserver Delegation and Why It Sits Above Everything Else

Nameserver delegation is the most consequential piece of DNS configuration you will ever set, and most developers configure it once at domain registration and never think about it again. The NS records for your domain tell the internet’s root servers which nameserver is authoritative for your zone. Every DNS query for any record under your domain goes through that authority first.

When you add your domain to Cloudflare and it asks you to change your nameservers, it is asking for this authority. Once your NS records point to Cloudflare, every DNS query for your domain routes through Cloudflare’s resolver. That is how Cloudflare can proxy your traffic, apply firewall rules, and route requests to Workers. Without NS delegation, Cloudflare has no intercept point.

NS record changes propagate slowly. Registrars cache NS records with TTLs that can be anywhere from an hour to 48 hours. During that window, some resolvers will still query your old nameserver, and some will query the new one. Requests can behave differently depending on which resolver a client uses. This is not a bug in your code. It is DNS doing exactly what it was designed to do.

The Records That Determine Which Edge Node Answers

Once nameserver delegation is sorted, the specific records you publish determine which edge network intercepts a given hostname. Two record types matter most: CNAME and A.

A CNAME record is an alias. It tells resolvers “the answer for this hostname is whatever the target hostname resolves to.” When you set api.yourdomain.com CNAME cname.vercel-dns.com, every resolver that queries your nameserver gets that CNAME response, then resolves cname.vercel-dns.com to get the actual IP. Vercel controls that resolution, and they return the IP of an edge node geographically close to the client. The client connects to that node. The node routes the request to your edge function.

On Cloudflare, proxied records work differently. Cloudflare’s nameserver returns its own IP addresses for proxied hostnames instead of your origin’s IP. Traffic flows into Cloudflare’s network before Cloudflare decides where to forward it. If a Worker route matches, the request goes to your function. If nothing matches, it passes through to your origin. This gives you fine-grained routing control, but it also means that misconfiguring a Worker route pattern sends requests straight to origin without any obvious error signal.

TTL values on your CNAME and A records also shape how fast changes take effect. A TTL of 3600 means changes you publish now take up to an hour to reach cached resolvers. Dropping TTL to 60 seconds before a cutover, then restoring it afterward, is a low-overhead habit that saves real debugging time.

The Verification Workflow That Confirms Your Deployment Is Actually Routing

Before you close the deployment ticket, run this check. It takes two minutes and catches the class of errors that create the most confusion later.

  • Confirm NS records have updated by querying your domain against a public resolver outside your local network
  • Confirm the CNAME or A record is published and returning the expected target value
  • Confirm the resolved IP belongs to your edge platform’s network range, not your origin
  • Confirm TLS is terminating on the edge platform by checking the certificate issuer in a browser or with openssl s_client

Run a DNS lookup against a neutral resolver to see exactly what the rest of the internet is seeing right now. Your local DNS cache and your ISP’s resolver may be serving stale answers from hours ago. A fresh query from an independent resolver cuts through that noise.

Pay close attention to the nameserver field in that result. If your domain’s NS records still point to your registrar’s default nameservers instead of Cloudflare’s, your worker routes will never fire regardless of how they are configured in the dashboard. That field is the first thing to verify, not an afterthought.

Routing Failures That Look Exactly Like Application Bugs

DNS misconfiguration at the edge creates a specific category of failure that is particularly disorienting: the kind where the symptom appears in your application layer but the cause is invisible to application tooling.

A request that bypasses your Worker and hits the origin directly produces a response, but that response will be missing headers your Worker injects, geolocation data your function uses, or auth handling your edge middleware provides. From the client’s perspective, the request “worked.” From the developer’s perspective, the feature is broken. No error logs appear because no errors occurred. The wrong system handled the request cleanly.

Another pattern shows up regularly: a Worker route is configured for *.yourdomain.com/* but the CNAME record points to a Vercel deployment instead of being proxied through Cloudflare. Traffic bypasses the Worker entirely. The Vercel deployment responds. Developers spend hours reading Worker code that was never invoked.

Partial propagation adds another layer of confusion. If nameserver delegation is mid-transition, roughly half your team might be hitting the new edge configuration while the other half resolves through the old nameserver. Behavior is inconsistent across machines in the same office network. This looks like a race condition or an environment-specific bug. It is neither.

When the DNS Settles and the Edge Finally Snaps Into Place

Edge functions are genuinely powerful. Geolocation at the request level, sub-millisecond middleware, and personalization without round-trips to the origin: these capabilities change what frontend architecture can do. But they depend entirely on DNS plumbing that works correctly and completely.

The developers who get the most out of edge deployments treat DNS verification as a non-optional step in the deployment checklist, not something they check after something feels wrong. They know that a green deployment dashboard and correct DNS propagation are two separate events, and they confirm both before declaring the work done.

Check the nameservers first. Check the records second. Verify propagation from a neutral resolver third. Everything above the DNS layer, your function code, your routing logic, your header manipulation, all of it assumes traffic is actually reaching the edge. Verify that assumption explicitly, every time, and you will spend significantly less time debugging systems that were never the problem.

Leave a Reply

Your email address will not be published. Required fields are marked *