TCP vs UDP: What's the Difference, and Why DNS Runs on Both
· Zoe Montague · 16 min read
TCP vs UDP: The Quick Answer
TCP and UDP are the two protocols that carry almost all internet traffic. TCP checks that every piece of data arrives, in the right order, before moving on — that makes it slower, but reliable, which is why it's used for web pages, email, and file transfers. UDP just sends the data without checking — that makes it faster, but occasionally lossy, which is why it's used for DNS lookups, video calls, and online gaming.
For DNS specifically: ordinary domain lookups use UDP because it's fast, but DNS also depends on TCP for zone transfers, oversized responses, and DNSSEC-signed records. A firewall or network that only allows one of the two will eventually break something, usually in a way that's hard to trace back to the cause.
The rest of this article covers how each protocol works, why DNS needs both, and how to diagnose it when only one gets through.
The Firewall Change Nobody Thought Twice About
A client's network team ran a security audit and tightened the firewall, closing off anything that didn't look load-bearing. Port 53 UDP stayed open, obviously, because everyone knows DNS runs on UDP. TCP 53 got closed along with a dozen other ports nobody could quite justify keeping. Regular DNS lookups kept working fine, the website resolved, email delivered, nothing looked broken from the outside. Nine days later someone noticed a new MX record hadn't shown up on the client's secondary nameserver yet, well past when it should have replicated.
Nothing about that firewall change looked wrong from the audit's perspective. Every ordinary DNS query went out over UDP and came back fine, because that really is how the overwhelming majority of DNS traffic works. What got missed is that DNS doesn't run only on UDP, and the zone transfer keeping that secondary nameserver in sync needed TCP the entire time. Once TCP 53 closed, the secondary just quietly stopped getting updates, and nothing in the ordinary lookup path would ever surface that on its own.
That gap, between what DNS "runs on" in the popular shorthand and what it actually needs on the wire, is worth closing properly, because it comes up constantly in MSP work and not only for DNS. Here's how TCP and UDP actually differ, and where each one shows up in a DNS ecosystem that leans on both.
How TCP Works
TCP, Transmission Control Protocol (RFC 9293), is connection-oriented. Before either side sends any real data, they run a three-way handshake — SYN, SYN-ACK, ACK — to open a session and agree on some initial bookkeeping. Every byte after that gets a sequence number, every segment gets acknowledged, and if an acknowledgment doesn't come back in time, TCP assumes the packet got lost and resends it. Packets that arrive out of order get held and reassembled in the right sequence before the application ever sees them. There's also flow control and congestion control built in, so a fast sender doesn't overwhelm a slow receiver or flood a congested network path.
All of that costs something. A handshake means at least one extra round trip before any application data moves at all, and the ongoing sequence/acknowledgment tracking adds overhead to every packet. But it buys a guarantee that matters a lot more than the extra latency in plenty of cases: whatever gets sent arrives, complete, in the order it was sent, or the connection surfaces an error instead of silently dropping something. That's why TCP is the default for anything where a missing or corrupted piece of data is a real problem — web pages, email, file transfers, database connections, and, as it turns out, DNS zone transfers.
How UDP Works
UDP, User Datagram Protocol (RFC 768), skips essentially all of that. There's no handshake, no session state kept on either side, no sequence numbers, no acknowledgments. A datagram goes out, and if it arrives, it arrives; if it doesn't, neither side automatically knows. Whatever's running on top of UDP has to decide for itself whether a lost packet matters enough to ask again.
That sounds like a downgrade until you notice what it buys back: speed. One packet out, one packet back, with no handshake overhead and no per-packet bookkeeping, is about as fast as a request-response exchange can get. That's exactly the shape of a huge amount of network traffic that either doesn't need TCP's guarantees or actively doesn't want them. A DNS resolver handling millions of lookups a day would burn an enormous amount of time and connection state on handshakes for queries that mostly just need "ask, get an answer, move on." A video call that loses one frame is better off skipping it and moving to the next one than pausing to retransmit a frame nobody needs anymore by the time it arrives. UDP is the right tool specifically because reliability, in those cases, isn't worth what it costs.
TCP vs UDP: The Differences That Actually Matter
| TCP | UDP | |
|---|---|---|
| Connection | Connection-oriented — handshake before data moves | Connectionless — no handshake, no session state |
| Reliability | Guaranteed delivery, lost packets are retransmitted | No delivery guarantee, lost packets just vanish |
| Ordering | Data arrives in the order it was sent | No ordering guarantee |
| Speed | Slower — handshake and acknowledgments add round trips | Faster — no handshake, minimal overhead |
| Header size | 20+ bytes, carries sequence/ack state | 8 bytes |
| Congestion control | Built in | None — the application handles it, if at all |
| Typical DNS role | Zone transfers, truncated responses, DNSSEC fallback | Standard queries and responses |
What Each One Actually Gets Used For
TCP carries most of the traffic where a dropped or corrupted byte would actually break something: HTTP and HTTPS traffic historically, SMTP/IMAP/POP3 for email, FTP and SFTP, SSH sessions, database connections, and DNS zone transfers. In all of those cases, losing part of the data silently and not knowing it happened is worse than the extra latency of a handshake and retransmission logic.
UDP shows up everywhere the opposite trade-off applies: DNS queries, VoIP and SIP/RTP traffic, video conferencing, live streaming, online gaming, DHCP, and NTP time sync. Either the data is time-sensitive enough that a late retransmit is useless — a stale video frame, an old game-state update nobody needs anymore — or the exchange is small and cheap enough that just asking again is less overhead than a handshake in the first place, which is exactly DNS's situation.
Worth a quick aside since it complicates the clean divide above: HTTP/3 (RFC 9114) actually moved back to UDP, via a protocol called QUIC (RFC 9000), after decades of HTTP running over TCP. QUIC builds its own reliability, ordering, and congestion control on top of UDP at the application layer instead of relying on the OS's TCP stack, mainly to avoid a problem called head-of-line blocking, where one lost TCP packet stalls an entire connection even if the data behind it already arrived. It's not a sign that UDP quietly became "reliable" in general. It's a sign that if you're willing to build TCP's guarantees yourself, at the application layer, you can get some of TCP's reliability without all of its overhead. That's a much higher bar than DNS clears for an ordinary query, which is exactly why DNS still leans on plain UDP for the common case instead of building something like QUIC for itself.
Why DNS Runs on Both
Standard DNS queries default to UDP because the shape of the exchange is about as simple as network traffic gets: one small query out, one small response back, no ongoing session needed either way. A resolver handling a heavy query load would pay a real cost in latency and connection state if every lookup opened a TCP handshake first, so UDP is the sensible default and has been since DNS was designed.
That default has a ceiling built into it. Classic DNS responses over UDP were capped at 512 bytes under the original DNS specification (RFC 1035), a limit from an era before anyone anticipated how much data a single DNS response might eventually need to carry. The EDNS0 extension (RFC 6891) raised that ceiling, and modern resolvers typically negotiate a larger UDP buffer size, but there's still a practical limit past which a response won't fit in a single UDP datagram. When a response is too big, the authoritative server sets the truncation bit, TC, in the DNS header instead of sending a broken partial answer. A well-behaved resolver sees that bit, discards the truncated UDP response, and re-asks the exact same query over TCP instead, where there's no size ceiling to worry about.
Zone transfers are the other place TCP is required rather than optional. AXFR (RFC 5936), a full zone transfer, and IXFR (RFC 1995), an incremental one, move the entire set of records (or just the changes) from a primary or hidden master nameserver to a secondary. That's exactly the kind of transfer where losing or reordering a packet mid-stream would silently corrupt a secondary's copy of the zone, which is precisely the failure mode UDP can't rule out and TCP is built to prevent. Zone transfers have always run over TCP for that reason, not as a modern addition.
DNSSEC (introduced across RFC 4033, RFC 4034, and RFC 4035) pushes even ordinary lookups closer to that TCP fallback path more often than most people expect. Signed responses carry RRSIG and DNSKEY records on top of the normal answer, and those records are large enough that plenty of DNSSEC-validated responses cross the truncation threshold that a non-signed response for the same domain never would. A domain that turns on DNSSEC will, in practice, see a meaningfully higher share of its DNS traffic fall back to TCP than it did before, simply because the responses got bigger.
None of this is a modern workaround bolted onto an otherwise UDP-only protocol. RFC 7766, published in 2016, made TCP support mandatory for DNS resolvers and authoritative servers specifically because reliance on TCP fallback had become common enough that "DNS mostly runs on UDP" stopped being a safe assumption to build infrastructure around.
When "Port 53 Is Open" Doesn't Mean What You Think
The firewall story from the top of this post has a recognizable shape once you know what to look for, and it's worth knowing the pattern because it shows up in a few different disguises. A secondary nameserver quietly falling behind on zone changes, while ordinary lookups for the same domain resolve just fine, is one version. A DNSSEC-signed domain that resolves fine from some networks but intermittently SERVFAILs from others is another — the failing resolvers are likely the ones sitting behind a firewall that only opened UDP 53. A domain with a long SPF record listing several includes, or a large DKIM key, timing out from some networks but not others is a third variation on the same root cause: a truncated response trying to fall back to TCP, and TCP getting silently dropped somewhere along the path.
A few commands make the diagnosis fast instead of guesswork:
# Force the query over TCP and compare it against the default UDP result
dig +tcp example.com
# Check the flags line in a normal query for the tc (truncated) bit —
# its presence means a well-behaved resolver would retry over TCP next
dig example.com
;; flags: qr rd ra tc;
# Test whether TCP port 53 is actually reachable, independent of UDP
nc -vz ns1.example.com 53
If dig +tcp times out or gets refused while the default query returns fine, that's the signature: UDP 53 is open, TCP 53 isn't, and anything relying on TCP fallback, truncated responses, DNSSEC-heavy lookups, zone transfers, is failing quietly instead of loudly. The fix is almost always the same one: update the firewall rule to allow both protocols on port 53, not just the one that handles the traffic anyone actually notices day to day. For zone transfers specifically, confirm the rule explicitly allows TCP between the primary or hidden master's IP and each secondary's IP, since that's traffic a general "allow DNS" rule can miss if whoever wrote it was thinking about resolvers, not nameserver replication.
Best Practices for MSPs
1. Never write a firewall rule for "DNS" that only covers UDP
Every rule permitting port 53 traffic should cover TCP and UDP together, by default, not as an exception added after something breaks. Treat "DNS = UDP" as the popular shorthand it is, not a spec to build firewall policy around.
2. Reach for dig +tcp before assuming something else is wrong
When a domain resolves inconsistently across networks, or a secondary nameserver looks stale, testing over TCP directly rules a whole category of cause in or out in seconds, well before touching anything DNS-provider-side.
3. Expect DNSSEC to increase how often a domain falls back to TCP
Signed responses are bigger. A client turning on DNSSEC is a good moment to double-check that TCP 53 is actually open everywhere it needs to be, not just assume the existing firewall rules already cover it.
4. Use Unified DNS to catch a stalled secondary before a client does
Unified DNS surfaces zone health and DNSSEC status across every connected provider, so a secondary that's silently drifted out of sync, or a chain of trust that's broken, shows up as an alert instead of something a client notices first when their new MX record still hasn't propagated a week later.
Frequently Asked Questions
Is DNS UDP or TCP?
Both, and it's not really optional for either. Standard DNS queries default to UDP for speed, since most lookups are small enough to fit in a single packet with no handshake needed. DNS also relies on TCP for zone transfers, for any response too large to fit in a UDP datagram, and increasingly for DNSSEC-signed responses that cross that same size threshold more often than unsigned ones do.
Why does DNS default to UDP if TCP is more reliable?
Because the overwhelming majority of DNS queries are small, simple, one-shot exchanges where TCP's handshake overhead would cost more than it's worth. A resolver answering a heavy volume of lookups benefits enormously from skipping a handshake on each one. TCP's reliability matters more for larger or more sensitive transfers, which is exactly where DNS falls back to it.
When does DNS use TCP instead of UDP?
Three main cases: zone transfers between a primary or hidden master and a secondary nameserver, which always use TCP; any response too large to fit in a UDP datagram, which the server flags by setting the truncation (TC) bit so the resolver knows to retry over TCP; and DNSSEC-signed responses, which are more likely to hit that size threshold because of the extra RRSIG and DNSKEY data they carry.
What is DNS truncation, and what's the TC flag?
Truncation happens when a DNS response is too large to fit in a single UDP datagram. Instead of sending a corrupted partial answer, the authoritative server sets the TC (truncated) bit in the response header, as defined in the core DNS specification (RFC 1035), and sends back a truncated message. A well-behaved resolver checks for that bit, discards the incomplete UDP response, and re-sends the identical query over TCP, where there's no equivalent size ceiling.
Do I need to open TCP port 53 on my firewall, or is UDP enough?
Both need to be open, on any firewall a nameserver or resolver sits behind. UDP alone handles ordinary lookups, but zone transfers, oversized responses, and DNSSEC fallback all specifically require TCP. A firewall that only permits UDP 53 will look completely fine under normal use and then fail in exactly the ways described above, quietly and without an obvious cause.
What's the difference between AXFR and IXFR zone transfers?
AXFR is a full zone transfer — the secondary receives the entire zone, every record, from the primary. IXFR is incremental — the secondary receives only the changes since its last known zone version, which is faster and lighter for zones that update frequently. Both run over TCP, for the same reason: a dropped or reordered packet mid-transfer would corrupt the secondary's copy of the zone, and TCP is what rules that out.
Does DNS over HTTPS or DNS over TLS change any of this?
Not the TCP-versus-UDP fundamentals for the resolver-to-authoritative-server side of things, no. DoH (RFC 8484) and DoT (RFC 7858) both change how a client talks to its resolver, encrypting that query specifically, and both run over TCP-based protocols, HTTPS and TLS respectively, for that leg of the conversation. What happens after the resolver receives that query, resolving it out to the authoritative side, still follows the same UDP-by-default, TCP-when-necessary pattern described here.
Get Started with Unified DNS
Firewall rules that quietly only cover one protocol are the kind of DNS problem that doesn't show up until something depending on the other one breaks. Unified DNS surfaces zone health, record drift, and DNSSEC state across every connected provider in one place, so an out-of-band change or a broken chain of trust shows up as an alert instead of a client noticing first.
Unified DNS is live — try it free for a month with code FREETRIAL2026 at billing setup. No commitment. Or request a demo for a walkthrough.
One more thing: I read through a dozen RFCs putting this one together, so my brain is officially done for the day. Going to go let it rest before it falls back to TCP on me too.
Zoe Montague is the founder of Silverfern Technology Consultants and the creator of Unified DNS, a DNS management platform built for MSPs.