A database client sending a payment request and a voice-call application sending the latest audio sample have very different needs.
The payment request must arrive correctly and in order. If the network temporarily loses data, waiting for recovery is usually better than silently processing an incomplete request. An old audio sample is different: by the time it is recovered, playing it may only make the conversation less natural. Continuing with newer audio can be more useful than waiting.
TCP and UDP exist to support these different delivery requirements. Both carry application data over IP and both use port numbers to reach the right application. Their service contracts, however, are fundamentally different:
Neither protocol is universally faster or better. The right choice depends on what the application must preserve when the network delays, loses, duplicates, or reorders packets.
IP moves packets between hosts. Applications need communication between processes running on those hosts. TCP and UDP provide that process-to-process delivery.
Each protocol adds a header containing a source port and destination port. The destination port helps the receiving operating system deliver data to the appropriate socket. The combination of IP addresses, transport protocol, and port numbers distinguishes one communication flow from another.
Suppose a client at 192.0.2.10 uses local port 51000 to contact a server at 198.51.100.20 on port 443. The transport endpoints are:
The client port lets several client processes communicate with the same server port without their traffic being confused. TCP and UDP have separate port spaces, so TCP port 443 and UDP port 443 are distinct endpoints.
Both protocols also include a checksum field that can detect corruption in the transport header and payload. TCP always uses its checksum. UDP checksums are required with IPv6; IPv4 permits a sender to disable the UDP checksum, although normal applications should keep the protection enabled. What happens beyond basic corruption detection is where the protocols' behavior diverges.
TCP is connection-oriented. Before application bytes are exchanged, the endpoints establish shared transport state. Once established, a TCP connection supports simultaneous communication in both directions.
To an application, TCP provides a byte stream with four important properties.
TCP tracks which bytes have been received. When recoverable packet loss occurs, TCP retransmits missing data. The application normally sees the recovered bytes rather than the loss itself.
Reliable does not mean that delivery is inevitable. A machine can crash, a cable can remain disconnected, or the path can disappear indefinitely. TCP can eventually report that a connection failed; it cannot guarantee communication through a permanent failure.
The useful contract is this: TCP either delivers bytes to the receiving application in order, without silently omitting part of the stream, or exposes a connection failure. An application must still handle that failure.
IP packets can arrive in a different order from the one in which they were sent. TCP puts received bytes back into their original stream order before exposing them to the application.
If a later portion arrives while an earlier portion is missing, the later bytes normally wait in the receiving TCP implementation. This protects stream order, but it also means one loss can delay otherwise available data.
A network can produce duplicate packets, and recovery behavior can result in the same bytes reaching the receiver more than once at the packet level. TCP uses its stream position information to avoid delivering duplicate bytes twice to the application.
This does not make an application operation exactly-once. If a client sends a payment request and loses the response, reconnecting and sending the request again creates a new application-level attempt. TCP cannot determine whether two valid requests represent the same business operation. Applications still need appropriate request identifiers and idempotency rules.
TCP does not preserve the boundaries between application writes. If a sender performs:
the receiver gets the ordered bytes:
It might read them as CATDOG, as CAT followed by DOG, or even as C, ATD, and OG. All are valid. TCP promises byte order, not matching calls to write() and read().
An application protocol running over TCP must define its own message boundaries. Common approaches include a fixed-size message, a delimiter, a length prefix, or a self-describing format with explicit framing.
Without application framing, the receiver cannot know whether CATDOG represents one message, two messages, or part of a larger message.
UDP is connectionless at the protocol level. An application can send a datagram without first establishing transport state with the destination. Each UDP datagram is an independent message containing an 8-byte UDP header and an application payload.
UDP offers a deliberately small service:
If a sender transmits two datagrams containing CAT and DOG, the receiver never obtains a merged CATDOG datagram from UDP. It may receive both messages separately, receive only one, receive them in the opposite order, or—less commonly—receive a duplicate.
A UDP socket can be "connected" through an operating-system API. In that case, the kernel records a default peer and can filter incoming datagrams by that peer. This is a useful local socket behavior, but it does not add a UDP handshake, reliable delivery, or an end-to-end connection.
UDP's minimal contract is not the same as having no error handling. It means that the application—or a protocol implemented above UDP—chooses which recovery, ordering, timing, and congestion behaviors it needs.
The central differences are service semantics, not simply header size.
| Property | TCP | UDP |
|---|---|---|
| Communication model | Connection-oriented | Connectionless datagrams |
| Data presented to the application | Continuous byte stream | Individual messages |
| Delivery guarantee | Retransmits recoverable loss; reports connection failure | No delivery guarantee |
| Ordering | Delivers bytes in order | Datagrams can arrive out of order |
| Duplicate handling | Suppresses duplicate stream bytes | Duplicates can reach the application |
| Transport setup | Establishes connection state before sending application data | Can send immediately without transport setup |
| Base header size | At least 20 bytes | 8 bytes |
| Flow and congestion behavior | Built into TCP | Must be supplied by the application or an upper protocol when needed |
| Broadcast or multicast use | Not supported by the TCP connection model | Can be used with IP broadcast or multicast where the network permits it |
| Typical abstraction | File-like stream | Message mailbox |
These are default transport properties. An application protocol can build additional behavior above either protocol. For example, an application can add messages to TCP by framing its byte stream, or add acknowledgments and retransmissions above UDP.
Loading simulation...
Packet loss makes the trade-off between TCP and UDP visible.
Assume an application produces three pieces of data: A, B, and C. The network loses the packet carrying B.
With TCP, the receiving application gets the bytes in order. TCP holds later stream data until the missing bytes have been recovered:
With UDP, A, B, and C would normally be separate datagrams. If the B datagram is lost, UDP can still deliver C when it arrives. The application decides whether to ignore the gap, interpolate missing data, request recovery, or discard later data.
For a file, the TCP behavior is usually desirable because bytes after a gap are not useful in the wrong position. For a live sensor display, audio call, or rapidly changing game state, the newest update may remain useful even when an older update is missing.
Recovery is therefore not free. It exchanges additional time and traffic for completeness. Skipping recovery is not free either: the application must tolerate or handle missing data.
UDP is often described as "faster than TCP." That statement is too broad to guide a real design.
UDP has several sources of lower baseline overhead:
Those properties can reduce latency for the right workload. They do not make the network transmit UDP packets at a higher physical speed. Propagation delay, queueing, serialization, server work, and the application's own protocol can dominate the difference.
TCP also has performance advantages. Its mature implementations adapt their sending rate, avoid overwhelming a receiver, react to congestion, and recover from common packet loss. A long-lived TCP connection can amortize its setup cost across many requests and use the available path efficiently.
A custom reliable protocol over UDP may send fewer header bytes yet perform worse than TCP if its recovery and congestion behavior are simplistic. Once an application adds acknowledgments, retransmissions, ordering, security, and connection state, it has taken responsibility for a substantial transport system.
The more accurate question is:
Does this application benefit more from TCP's ordered reliability, or from UDP's independent and time-sensitive message delivery?
A fast sender can overwhelm a slow receiver. TCP includes flow control, which lets a receiver limit how much unconsumed data the sender may have in flight. Operating-system buffers absorb temporary differences, but a persistently slow receiver eventually creates backpressure that the sending application can observe through blocked, partial, delayed, or failed writes.
UDP has no equivalent end-to-end flow-control mechanism. A successful UDP send usually means the local kernel accepted the datagram, not that the remote application received or processed it. If an application sends faster than a socket, host, or network can handle, datagrams can be discarded.
This distinction matters for backend systems:
Neither transport acknowledgment is a business-level acknowledgment. If a service needs to know that an order was stored, it needs an application response that means "the order was stored," regardless of the transport protocol.
UDP applications that produce sustained traffic should implement suitable rate control or use an established protocol that does. Avoiding TCP does not remove the shared network's capacity limits.
TCP gives the application a stream, so the sender can write a large amount of data without constructing one network-sized message. TCP divides the stream into pieces suitable for transmission, and the receiver reconstructs the ordered byte stream.
Every UDP send, in contrast, creates one datagram. A large datagram may need IP fragmentation or may be rejected, and losing one fragment can prevent delivery of the entire datagram. Large UDP datagrams are therefore fragile across paths with unknown size limits.
Applications should keep UDP datagrams within a safe payload size for their environment or use a protocol with proper packetization and path-size handling. They must also provide a receive buffer large enough for the complete datagram. If the buffer is too small, the excess portion can be discarded rather than returned by a later read.
This message-oriented behavior is valuable when records are naturally small and independent. It requires more deliberate size management than writing a byte stream.
TCP is a strong default when every byte matters and the application naturally expects a durable, ordered conversation.
Common examples include:
Database connections: Queries, result sets, and protocol control messages must not silently skip bytes or change order.
File transfer: A file with missing or reordered bytes is not the same file. Reliable stream delivery matches the requirement directly.
Remote shells: Commands and output need ordered delivery, even if a temporary network problem causes a pause.
Email transfer: Completeness matters more than preserving the timeliness of an individual packet.
Traditional web traffic: HTTP/1.1 and HTTP/2 commonly run over TCP. Applications add HTTP message framing above TCP's byte stream.
TCP reduces application complexity for these workloads. Developers still need timeouts, application framing, reconnection logic, and protection against repeated business operations, but they do not need to rebuild ordinary loss recovery and stream ordering.
UDP is a good foundation when individual messages are useful independently, stale data loses value quickly, or the application needs control over recovery.
Interactive audio and video: Waiting for an old media packet can be worse than concealing the loss and playing current media. The application can use sequence and timing information to detect gaps without forcing all later media to wait.
Rapid game-state updates: A newer position update can supersede an older one. Reliable delivery may still be used for actions that must not disappear, while frequent state snapshots use loss-tolerant messages.
Small request-response protocols: DNS commonly uses UDP for ordinary queries because one request and one response fit the datagram model. DNS can use TCP when its protocol rules or response behavior require it.
Telemetry with replaceable samples: A periodic metric may be useful even if the preceding sample was lost. This is appropriate only when the system explicitly accepts gaps.
Discovery and group delivery: Protocols can use UDP with broadcast or multicast to reach multiple listeners without creating a separate TCP connection to each one.
Choosing UDP should be an explicit decision about failure behavior. Logs, audit records, payments, and configuration changes are usually not disposable merely because sending them as datagrams looks simple.
Applications do not always have a single reliability requirement.
A multiplayer game may need:
A video meeting may need:
This does not necessarily mean opening both a raw TCP socket and a raw UDP socket. Established application protocols may already provide several delivery modes. The important design step is to classify the data before choosing a transport behavior.
Ask of each operation:
These questions are more useful than labeling an entire product "real time" or "reliable."
Using UDP does not require the application to expose unreliable delivery to its user.
QUIC, for example, runs over UDP but adds connection management, security, congestion control, loss recovery, and reliable streams. HTTP/3 runs over QUIC. In that stack, UDP provides the operating-system datagram interface, while QUIC provides a richer transport contract above it.
It would be misleading to compare HTTP/3 with TCP by saying that HTTP/3 "does not retransmit because it uses UDP." QUIC implements its own recovery. The application's behavior is determined by the complete protocol stack, not just the IP protocol number.
This is also why building directly on UDP deserves caution. A well-designed protocol above UDP can provide exactly the semantics an application needs. A poorly designed one can create unfair network usage, weak loss recovery, security vulnerabilities, and failures that TCP implementations have spent decades learning to handle.
Consider four backend operations.
The request and response must arrive intact, so a reliable transport is appropriate. TCP is a natural base. The service still needs a transaction identifier because retrying after an uncertain response can submit the logical operation more than once.
Every byte matters, the data is large, and completion matters more than shaving a small amount of delay from individual packets. TCP's reliable byte stream fits directly.
If the gauge refreshes every second, an old sample may be safely replaced by the latest sample. UDP can be reasonable when occasional gaps are explicitly acceptable. If the metrics feed billing or compliance records, that assumption changes and reliable delivery or application-level recovery becomes necessary.
Audio must arrive near its playback time. The application may prefer to conceal a missing sample and continue. UDP-based media transport can make that choice, while adding sequence numbers, timing, rate adaptation, and selective recovery at the application-protocol level.
The data's meaning determines the choice. "Backend service" does not automatically imply TCP, and "real-time application" does not automatically imply that every message should use UDP.
Protocol semantics are the first consideration, but real networks also contain firewalls, load balancers, network address translators, and observability tools.
These devices commonly track TCP's explicit connection lifecycle. UDP has no protocol-level connection lifecycle, so devices often infer temporary flow state from observed datagrams and expire it after an idle period. As a result, a UDP application can work on a local network yet encounter shorter idle timeouts or restrictive policy on another path.
TCP is widely supported through enterprise networks and proxies. UDP support is also common, but a deployment should verify that every required network component accepts the chosen protocol and port. Falling back to TCP or another supported transport can be necessary in constrained environments.
Troubleshooting also differs:
For UDP, application-level request IDs, sequence numbers, timestamps, loss metrics, and explicit timeouts are especially important. Without them, "no response" does not reveal whether the request was lost, the response was lost, the server was slow, or a network policy discarded the traffic.
TCP is reliable, not infallible. It recovers from ordinary loss and reports connection failure, but it cannot deliver through a permanent outage or prove that the remote application completed an operation.
TCP does not preserve messages. It delivers an ordered stream of bytes. The application must define where each message begins and ends.
UDP preserves datagram boundaries, not delivery. A delivered datagram remains a distinct message, but it may be lost, reordered, or duplicated before delivery.
UDP is not always faster. It has less built-in work, but total performance depends on the path, workload, implementation, and any features added above UDP.
TCP's larger header is rarely the whole decision. Correct failure semantics and application complexity usually matter more than saving twelve or more transport-header bytes.
A successful send is not proof of remote processing. This is true for both protocols. Business-level completion requires an application-level response or durable protocol rule.
Using UDP does not mean ignoring congestion. A UDP-based application must control its sending behavior or rely on a protocol that does.
Protocols above UDP can be reliable. QUIC demonstrates that UDP can serve as a foundation for reliable, secure streams.
TCP and UDP provide different transport contracts over IP. TCP creates a reliable, ordered byte stream, recovering ordinary loss, suppressing duplicate bytes, controlling flow, and reacting to congestion. It does not preserve application message boundaries or prove that a remote application completed an operation.
UDP preserves independent datagram boundaries but does not guarantee delivery, order, duplicate suppression, recovery, or flow control. Its smaller header and lack of transport setup reduce overhead without making it universally faster.
TCP suits files, database traffic, remote shells, and other exchanges where every ordered byte matters. UDP suits time-sensitive or independently useful messages when the application can tolerate or manage loss. Protocols such as QUIC can add reliability above UDP, so the complete stack determines behavior.
Choose TCP when completeness and order are worth waiting for; choose UDP when message independence and control over timeliness matter more.
5 quizzes