UDP vs TCP, how much faster is it? [closed] - networking

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 3 years ago.
The community reviewed whether to reopen this question 1 year ago and left it closed:
Original close reason(s) were not resolved
Improve this question
For general protocol message exchange, which can tolerate some packet loss. How much more efficient is UDP over TCP?

People say that the major thing TCP gives you is reliability. But that's not really true. The most important thing TCP gives you is congestion control: you can run 100 TCP connections across a DSL link all going at max speed, and all 100 connections will be productive, because they all "sense" the available bandwidth. Try that with 100 different UDP applications, all pushing packets as fast as they can go, and see how well things work out for you.
On a larger scale, this TCP behavior is what keeps the Internet from locking up into "congestion collapse".
Things that tend to push applications towards UDP:
Group delivery semantics: it's possible to do reliable delivery to a group of people much more efficiently than TCP's point-to-point acknowledgement.
Out-of-order delivery: in lots of applications, as long as you get all the data, you don't care what order it arrives in; you can reduce app-level latency by accepting an out-of-order block.
Unfriendliness: on a LAN party, you may not care if your web browser functions nicely as long as you're blitting updates to the network as fast as you possibly can.
But even if you care about performance, you probably don't want to go with UDP:
You're on the hook for reliability now, and a lot of the things you might do to implement reliability can end up being slower than what TCP already does.
Now you're network-unfriendly, which can cause problems in shared environments.
Most importantly, firewalls will block you.
You can potentially overcome some TCP performance and latency issues by "trunking" multiple TCP connections together; iSCSI does this to get around congestion control on local area networks, but you can also do it to create a low-latency "urgent" message channel (TCP's "URGENT" behavior is totally broken).

In some applications TCP is faster (better throughput) than UDP.
This is the case when doing lots of small writes relative to the MTU size. For example, I read an experiment in which a stream of 300 byte packets was being sent over Ethernet (1500 byte MTU) and TCP was 50% faster than UDP.
The reason is because TCP will try and buffer the data and fill a full network segment thus making more efficient use of the available bandwidth.
UDP on the other hand puts the packet on the wire immediately thus congesting the network with lots of small packets.
You probably shouldn't use UDP unless you have a very specific reason for doing so. Especially since you can give TCP the same sort of latency as UDP by disabling the Nagle algorithm (for example if you're transmitting real-time sensor data and you're not worried about congesting the network with lot's of small packets).

UDP is faster than TCP, and the simple reason is because its non-existent acknowledge packet (ACK) that permits a continuous packet stream, instead of TCP that acknowledges a set of packets, calculated by using the TCP window size and round-trip time (RTT).
For more information, I recommend the simple, but very comprehensible Skullbox explanation (TCP vs. UDP)

with loss tolerant
Do you mean "with loss tolerance" ?
Basically, UDP is not "loss tolerant". You can send 100 packets to someone, and they might only get 95 of those packets, and some might be in the wrong order.
For things like video streaming, and multiplayer gaming, where it is better to miss a packet than to delay all the other packets behind it, this is the obvious choice
For most other things though, a missing or 'rearranged' packet is critical. You'd have to write some extra code to run on top of UDP to retry if things got missed, and enforce correct order. This would add a small bit of overhead in certain places.
Thankfully, some very very smart people have done this, and they called it TCP.
Think of it this way: If a packet goes missing, would you rather just get the next packet as quickly as possible and continue (use UDP), or do you actually need that missing data (use TCP). The overhead won't matter unless you're in a really edge-case scenario.

When speaking of "what is faster" - there are at least two very different aspects: throughput and latency.
If speaking about throughput - TCP's flow control (as mentioned in other answers), is extremely important and doing anything comparable over UDP, while certainly possible, would be a Big Headache(tm). As a result - using UDP when you need throughput, rarely qualifies as a good idea (unless you want to get an unfair advantage over TCP).
However, if speaking about latencies - the whole thing is completely different. While in the absence of packet loss TCP and UDP behave extremely similar (any differences, if any, being marginal) - after the packet is lost, the whole pattern changes drastically.
After any packet loss, TCP will wait for retransmit for at least 200ms (1sec per paragraph 2.4 of RFC6298, but practical modern implementations tend to reduce it to 200ms). Moreover, with TCP, even those packets which did reach destination host - will not be delivered to your app until the missing packet is received (i.e., the whole communication is delayed by ~200ms) - BTW, this effect, known as Head-of-Line Blocking, is inherent to all reliable ordered streams, whether TCP or reliable+ordered UDP. To make things even worse - if the retransmitted packet is also lost, then we'll be speaking about delay of ~600ms (due to so-called exponential backoff, 1st retransmit is 200ms, and second one is 200*2=400ms). If our channel has 1% packet loss (which is not bad by today's standards), and we have a game with 20 updates per second - such 600ms delays will occur on average every 8 minutes. And as 600ms is more than enough to get you killed in a fast-paced game - well, it is pretty bad for gameplay. These effects are exactly why gamedevs often prefer UDP over TCP.
However, when using UDP to reduce latencies - it is important to realize that merely "using UDP" is not sufficient to get substantial latency improvement, it is all about HOW you're using UDP. In particular, while RUDP libraries usually avoid that "exponential backoff" and use shorter retransmit times - if they are used as a "reliable ordered" stream, they still have to suffer from Head-of-Line Blocking (so in case of a double packet loss, instead of that 600ms we'll get about 1.5*2*RTT - or for a pretty good 80ms RTT, it is a ~250ms delay, which is an improvement, but it is still possible to do better). On the other hand, if using techniques discussed in http://gafferongames.com/networked-physics/snapshot-compression/ and/or http://ithare.com/udp-from-mog-perspective/#low-latency-compression , it IS possible to eliminate Head-of-Line blocking entirely (so for a double-packet loss for a game with 20 updates/second, the delay will be 100ms regardless of RTT).
And as a side note - if you happen to have access only to TCP but no UDP (such as in browser, or if your client is behind one of 6-9% of ugly firewalls blocking UDP) - there seems to be a way to implement UDP-over-TCP without incurring too much latencies, see here: http://ithare.com/almost-zero-additional-latency-udp-over-tcp/ (make sure to read comments too(!)).

Which protocol performs better (in terms of throughput) - UDP or TCP - really depends on the network characteristics and the network traffic. Robert S. Barnes, for example, points out a scenario where TCP performs better (small-sized writes). Now, consider a scenario in which the network is congested and has both TCP and UDP traffic. Senders in the network that are using TCP, will sense the 'congestion' and cut down on their sending rates. However, UDP doesn't have any congestion avoidance or congestion control mechanisms, and senders using UDP would continue to pump in data at the same rate. Gradually, TCP senders would reduce their sending rates to bare minimum and if UDP senders have enough data to be sent over the network, they would hog up the majority of bandwidth available. So, in such a case, UDP senders will have greater throughput, as they get the bigger pie of the network bandwidth. In fact, this is an active research topic - How to improve TCP throughput in presence of UDP traffic. One way, that I know of, using which TCP applications can improve throughput is by opening multiple TCP connections. That way, even though, each TCP connection's throughput might be limited, the sum total of the throughput of all TCP connections may be greater than the throughput for an application using UDP.

Each TCP connection requires an initial handshake before data is transmitted. Also, the TCP header contains a lot of overhead intended for different signals and message delivery detection. For a message exchange, UDP will probably suffice if a small chance of failure is acceptable. If receipt must be verified, TCP is your best option.

I will just make things clear. TCP/UDP are two cars are that being driven on the road. suppose that traffic signs & obstacles are Errors TCP cares for traffic signs, respects everything around. Slow driving because something may happen to the car. While UDP just drives off, full speed no respect to street signs. Nothing, a mad driver. UDP doesn't have error recovery, If there's an obstacle, it will just collide with it then continue. While TCP makes sure that all packets are sent & received perfectly, No errors , so , the car just passes obstacles without colliding. I hope this is a good example for you to understand, Why UDP is preferred in gaming. Gaming needs speed. TCP is preffered in downloads, or downloaded files may be corrupted.

UDP is slightly quicker in my experience, but not by much. The choice shouldn't be made on performance but on the message content and compression techniques.
If it's a protocol with message exchange, I'd suggest that the very slight performance hit you take with TCP is more than worth it. You're given a connection between two end points that will give you everything you need. Don't try and manufacture your own reliable two-way protocol on top of UDP unless you're really, really confident in what you're undertaking.

There has been some work done to allow the programmer to have the benefits of both worlds.
SCTP
It is an independent transport layer protolol, but it can be used as a library providing additional layer over UDP. The basic unit of communication is a message (mapped to one or more UDP packets). There is congestion control built in. The protocol has knobs and twiddles to switch on
in order delivery of messages
automatic retransmission of lost messages, with user defined parameters
if any of this is needed for your particular application.
One issue with this is that the connection establishment is a complicated (and therefore slow process)
Other similar stuff
https://en.wikipedia.org/wiki/Reliable_User_Datagram_Protocol
One more similar proprietary experimental thing
https://en.wikipedia.org/wiki/QUIC
This also tries to improve on the triple way handshake of TCP and change the congestion control to better deal with fast lines.
Update 2022: Quic and HTTP/3
QUIC (mentioned above) has been standardized through RFCs and even became the basis of HTTP/3 since the original answer was written. There are various libraries such as lucas-clemente/quic-go or microsoft/msquic or google/quiche or mozilla/neqo (web-browsers need to be implementing this).
These libraries expose to the programmer reliable TCP-like streams on top the UDP transport. RFC 9221 (An Unreliable Datagram Extension to QUIC) adds working with individual unreliable data packets.

Keep in mind that TCP usually keeps multiple messages on wire. If you want to implement this in UDP you'll have quite a lot of work if you want to do it reliably. Your solution is either going to be less reliable, less fast or an incredible amount of work. There are valid applications of UDP, but if you're asking this question yours probably is not.

If you need to quickly blast a message across the net between two IP's that haven't even talked yet, then a UDP is going to arrive at least 3 times faster, usually 5 times faster.

It is meaningless to talk about TCP or UDP without taking the network condition into account.
If the network between the two point have a very high quality, UDP is absolutely faster than TCP, but in some other case such as the GPRS network, TCP may been faster and more reliability than UDP.

The network setup is crucial for any measurements. It makes a huge difference, if you are communicating via sockets on your local machine or with the other end of the world.
Three things I want to add to the discussion:
You can find here a very good article about TCP vs. UDP in the
context of game development.
Additionally, iperf (jperf enhance iperf with a GUI) is a
very nice tool for answering your question yourself by measuring.
I implemented a benchmark in Python (see this SO question). In average of 10^6 iterations the difference for sending 8 bytes is about 1-2 microseconds for UDP.

Related

Are there any fault-tolerant protocols based on unidirectional UDP?

I have encountered a situation where I need to replicate a small (<10 MB) database over unidirectional UDP. The physical ethernet cable prevents data flowing the other direction. Updates must be replicated within a few seconds with very low risk of losing data, but there is no way for the receiving side to ask for retransmission if it detects a failure, e.g. a packet loss, as the data-link is unidirectional.
A crude solution to lower the probability of lost updates would be to send each update multiple times, but that seems rather inefficient if the update frequency is high. A more sophisticated solution would be to use error-correcting codes to recover lost or corrupted packets.
Are there any implementations of such fault-tolerant unidirectional protocol?

Is a checksum needed for application data of a custom protocol?

Since packets travel over the wire have checksums on different layers, Ethernet and IPv4 have checksums for their headers, TCP's checksum even covers the entire segment.
I know it is not impossible that a corrupted packet, from the standpoint of the application layer, can slip in without being discarded by Ethernet/IP/TCP, because there are chances that their checksums are correct, only the probability is low.
I am designing a custom binary protocol for an IM application. My question is do I need to add a checksum to ensure the integrity of my application data? Is a checksum really needed in practice?
There's actual research on this subject. It's old, but very relevant to the question at hand.
The paper, from 2000, is called "When the CRC and TCP checksum disagree" by Jonathan Stone and Craig Partridge, which investigate packet and frame errors, and look how often the TCP checksum is wrong, but the Ethernet CRC is fine. You can find the PDF here. Here are the important bits.
From the abstract:
Traces of Internet packets from the past two years show that between 1
packet in 1,100 and 1 packet in 32,000 fails the TCP checksum, even on
links where link-level CRCs should catch all but 1 in 4 billion
errors.
From the conclusion (with some of my highlighting)
In practice, the checksum is being asked to detect an error every
few thousand packets. After eliminating those errors that the checksum
always catches, the data suggests that, on average, between one packet
in 10 billion and one packet in a few millions will have an error that
goes undetected. The exact range depends on the type of data
transferred and the path being traversed. While these odds seem large,
they do not encourage complacency. In every trace, one or two 'bad
apple' hosts or paths are responsible for a huge proportion of the
errors. For applications which stumble across one of the `bad-apple'
hosts, the expected time until a corrupted data is accepted could be
as low as a few minutes. When compared to undetected error rates for
local I/O (e.g., disk drives), these rates are disturbing. Our
conclusion is that vital applications should strongly consider
augmenting the TCP checksum with an application sum.
I don't know of any newer research into that question (enlighten me if you know otherwise!), so the Internet could have become more reliable since then, and the numbers in the paper might be irrelevant.
However, and this is important, 17 years have passed, and the amount of Internet traffic simply exploded since that paper was written. At 1Gbps, which is not an uncommon connection speed nowadays, you're sending about 81K full TCP segments, with 1460 bytes of data, per second (or a lot more if the packets are smaller). That's a million big packets every 12.5 seconds, a billion in about 3.5 hours (or again, a lot more if the packets are small).
So to answer your question - that depends.
For transferring large files or other data, I'd definitely add additional checks if the data itself isn't protected in any way. For messaging, which pushes very little data into the network, you'll probably be fine with TCP's checksum, with maybe some sanity checks on the input you're getting to make sure that it's in the correct format, and various parameters and fields make sense.
I would not bother with a checksum because of packets getting corrupted in the network.
However, since you are working on a protocol that would presumably be used on the open internet, you will need to prepare for rare cases of an unintended application sending udp packets or making tcp connections to your receiving/listening ports. Also there will be maybe less port scans and hackers / script kiddies knocking on your gates.
So you should make your protocol such that it is easy to discard this kind of traffic. Using a checksum in every transmission would imho be one sensible way of doing that.

TCP vs UDP for real-time chat recommendation-engine?

I am building a chat application, where each keystroke presses of the user are sent to the server. At the server, a recommendation engine which is based on nlp generates recommendations based on the context of the typed message at that point of time.
For large scale deployment, which connection type would be preferable between TCP and UDP. UDP is fast but unreliable, whereas TCP, being reliable may be slow in real-time. For example:A user types the words "Hey, lets watch" and quickly clears the text-box,the recommendation of a movie should not be generated after he clears the text-box.
If the server has a recommendation, it should be guaranteed to deliver the recommendation back to the client.
The aim is to get real-time recommendation with low latency. Which type would be more preferable?
TCP and UDP are almost identical if the size of the data being sent at a time is less than the maximum payload of a single frame.
In that case UDP will be more "reliable" in terms of real-time behaviour since it is more within your hands how the data is processed. The downside of course is that you have to care of certain things yourself which TCP will give you for free.
With TCP on the other hand the TCP layer of the protocol stack can make a mess out of your real-time requirements and you don't even have a chance doing anything about it. Ever thought about re-transmitts (about +200ms transmittion time), nagle algorithm (small packets are delayed for up to 200ms), delayed TCP ACKs (may cause re-transmitts on some stacks)? And there is a lot more in stock for you if you have strickt real-tme requirements.
I'm working on a project which has a 20ms timeframe and transmitts a lot of data in that time using TCP. Even though we have a star architecture and real-time operating systems it is a hell to get this working reliable (well lots of the effects are due to one of our used Ethernet chips the smsc91c111).
Concluding there is no "best way" doing things like that since neither UDP nor TCP are real-time protocols. But since it is fairly easy to switch between them I recommend simply to test it and choose the protocol which works best.

TCP vs UDP for Microprocessor Communication

I am using TCP for communicating with an arduino (just open a socket and wait for a connection)using an ethernet shield, While watching/reading about various other project that use some sort of network interface for communication they all seem to use UDP instead of TCP for communication. What I was wondering is what would be my gain if I use UDP instead?
A UDP stack is considerably simpler than a TCP stack. You can easily write a UDP stack from scratch on your own, TCP is a bit harder, doable but harder. TCP has built in retries and other things so you dont lose reliability with UDP directly, it is what you do with it that could compare. UDP is significantly faster than TCP and is why it is or was used for video and various things back in the day. Also things like video could stand to lose a packet here and there and didnt care. For embedded UDP is quite nice for being small, fast, etc. If you are using someone elses library then UDP is likely not going to save you much on memory/flash resources, it will still be a bit faster. It is when you implement your own UDP that you save quite a bit on memory, because you can cut corners. You can do things like only implement arp and udp and nothing else (although ping is useful but somehow painful), and you can cut corners on arp/rarp depending on what you need to do with this thing. You can implement support only for the packet size you are interested in. Numbering your packets and having the requesting side send two or three of everything and responding to every request can greatly reduce the lost packet problem. Keeping the packet size very small helps both the embedded resource problem and avoids any mtu or other problems along the way. For simplicity you can even force a specific packet length.
I always ask the question the other way, what would I stand to gain by using TCP. There are times when it is useful, embedded, desktop or server though I still ask that question every time and have to justify the use of TCP over UDP otherwise I wont use it.
You gain multicasting, but lose reliability.
You gain code space, data memory, and determinism.
A fair amount of memory is required to reassemble a TCP stream, unless you want to NAK every packet that's not in-order. They are never guaranteed to come in order....
An asynchronous command-response protocol with timeouts, where all commands and responses fit into a single UDP packet, and commands are idempotent (can be applied many times and maintain the correct result) is a pretty robust protocol.

Giving Users an Option Between UDP & TCP?

After studying TCP/UDP difference all week, I just can't decide which to use. I have to send a large amount of constant sensor data, while at the same time sending important data that can't be lost. This made a perfect split for me to use both, then I read a paper (http://www.isoc.org/INET97/proceedings/F3/F3_1.HTM) that says using both causes packet/performance loss in the other. Is there any issue presented if I allow the user to choose which protocol to use (if I program both server side) instead of choosing myself? Are there any disadvantages to this?
The only other solution I came up with is to use UDP, and if there seems to be too great of loss of packets, switch to TCP (client-side).
I'd say go with TCP, unless you can't (because you have thousands of sensors, or the sensors very low energy budgets, or whatever). If you need reliability you'll have to roll your own reliability layer on top of UDP.
Try it out with TCP, and measure your performance. If it's OK, and you don't anticipate serious scaling issues, then just stay with TCP.
The article you link goes into detailed analysis on some corner cases. This probably does not apply in your situation. I would ignore this unless your own performance tests start showing problems. Start with the simplest setup (I'm guessing TCP for bulk data transfer and UDP for non-reliable sensor data), test, measure, find bottlenecks, re-factor.
The OP says:
... sending important data that can't be lost.
Therefore, TCP, by definition is the right answer over UDP.
Remember, the "U" in UDP stands for "unreliable"
Re:
The only other solution I came up with is to use UDP, and if there seems to be too great of loss of packets, switch to TCP (client-side).
Bad idea: things will tend to break at exactly the times that you don't expect them to. Your job, as an engineer, is to plan for the failure cases and mitigate them in advance. UDP will lose packets. If your data can't be lost, then don't use UDP.
I also would go with just TCP. UDP has its uses, and high-importance sensor data isn't really what comes to mind. If you can stand to lose plenty of sensor data, go with UDP, but I conjure that isn't what you want at all.
UDP is simpler protocol than TCP, and you can still simulate features of TCP using UDP. If you really have custom needs, UDP is easier to tweak.
However, I'd firstly just use both UDP and TCP, check their behavior in a real environment, and only then decide to reimplement TCP in terms of UDP in the exact way you need. Given proper abstraction, this should not be much work.
Maybe it would be enough for you to throttle your TCP usage not to fill up the bandwidth?
If you can't lose data, and you use UDP, you are reinventing TCP, at least a significant fraction of it. Whatever you gain in performance you are prone to lose in protocol design errors, as it is hard to design a protocol.
Constant sensor data: UDP. Important data that can't be lost: TCP.
You can implement your own mechanism to confirm the delivery of UDP packets that can't be lost.
I would say go with TCP. Also, if you're managing a lot of packet loss, the protocol of choice is your least concern. If you need important data, TCP. If the data is not important and can be supplemented later, UDP. If the data is mission-critical, TCP. UDP will be faster, but leave you with errors left and right from corrupt or non-existent packets. In the end, you'd be reinventing TCP to fix the problems.

Resources