The Internet for web developers: UDP and ports

This post is part of a series:

  1. Introduction
  2. Protocols
  3. Internet Protocol
  4. User Datagram Protocol
  5. Transmission Control Protocol
  6. Domain Name System

Hello, transport layer! The User Datagram Protocol (UDP) is a simple, no frills protocol that plays an important, but sometimes neglected, role on the Internet. UDP is preferred when its main rival, TCP, is too heavyweight.

It’s our first protocol on the transport layer, so let’s begin by reviewing that.

The transport layer

Recall our four layer model. The link layer handles communication between physically connected machines. The internet layer handles communication across network boundaries. Both examples of good, honest work.

The transport layer is a bit more high-falutin'. It provides services that the lower layers lack. What are “services”, then? The answer depends on the exact protocol in question. I initially found it tricky to get a handle on the transport layer as a whole because all the definitions seemed so vague. If you feel the same way, please hold on. Things should make more sense as we continue.

The Transmission Control Protocol (TCP) is the most common transport layer protocol on the Internet. TCP provides the service of a persistent, reliable connection between two hosts. We’ll see how it works when we examine TCP in more detail soon. For now, just bear in mind that such benefits come with a performance cost because the protocol has to do a lot more work sending various book-keeping messages back and forth.

UDP is little more that a thin wrapper around IP. It’s connection-less, stateless and doesn’t guarantee delivery. It does none of TCP’s extra work and so has none of the extra cost. UDP offers only two new features: a checksum that ensures the payload is correct and a port number identifying which application layer protocol is in the payload.

Its simplicity makes it fast and ideal for situations where speed is more important that delivering absolutely every packet in order. It’s also used by other protocols, such as DNS, which only need a simple query-response delivery. For some applications, a reliable connection is simply not worth the performance cost. UDP fills that gap.

UDP headers

The UDP header format is almost embarrassingly simple:

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|          Source Port          |        Destination Port       |
|             Length            |            Checksum           |

The length value is pretty self-explanatory.

The checksum, like the checksums in Ethernet and IP, is a value computed from the packet contents. The receiver recomputes the checksum for the received packet and checks that it matches the value recorded in the header. If they don’t match, that means that the packet was corrupted in transit.

Unlike the Ethernet and IP checksums, the UDP checksum is computed from the whole payload, not just the headers. This is the first time that we’ve seen a protocol that ensures the payload itself has not been corrupted.

So that’s our first service. IP alone doesn’t guarantee that the packet will be delivered and, even if it is, it might arrive corrupted. UDP doesn’t guarantee that the packet will be delivered either, but it does guarantee that any successfully delivered packet is uncorrupted.

Application ports

The most interesting fields (from an admittedly extremely small selection) are the port fields. We’ve seen already that other protocol headers include a field indicating the payload’s protocol type. Without these fields, the receiver wouldn’t know how to interpret the payload data. Ports are a generalisation of this concept.

A port is a numbered mailbox. Programs running on the receiver can listen on a port by registering themselves with the OS, which takes the received packet and passes it to the correct port. The assumption is that a program listening on a given port will be able to parse packets coming in on that port.

Ports numbered below 1024 are designated “well-known” ports and have an assigned application level protocol so that everyone knows which port they should be addressing for a given protocol. There’s nothing stopping you from making your own protocol and using one of the well-known ports, but you won’t be able to use it to communicate with anyone else because they will expect that port to use the standard protocol. Remember that in networking, convention is key!

Here are the port numbers of a few common application layer protocols:

Service Purpose Port number
SMTP email 25
DNS domain names 53
HTTP web content 80
HTTPS secure web content 443
FTP file transfer 20, 21
SSH remote shells 22

TCP, as we’ll see, uses the same port system. In theory, UDP ports are only meaningful to UDP and TCP ports are only meaningful to TCP. In practice, protocols are usually assigned the same ports on both UDP and TCP to avoid confusion.

The combination of IP address and port number uniquely identifies an application on a particular host: // HTTP, used by web servers // Same host but this time connecting to SSH // HTTP but on different host

Looking back at the UDP header diagram, we can see that port numbers are 16 bits long and so can hold 65,536 unique values. If only 1,024 are “well-known”, what about the rest? They are free for whatever you want. The higher port values (the exact range varies from system to system) are considered “ephemeral” and are used as source ports. The source port is written into the header so that any responses can be routed to the application that made the original request.

On Unix-like systems, a program normally needs superuser privileges (i.e. using sudo) to connect to a well-known port. The original idea was to stop some random user logging into a shared computer and replacing a well-known service such as FTP with their own nefarious program. This restriction has actually become something of a security issue itself because it means that lots of Internet-facing programs need to run with escalated privileges. Web servers such as nginx try to mitigate the security risk by using the superuser privileges to listen on port 80/443 and then immediately de-escalate themselves to lower privilege levels.

Ports are a simple but very useful service. Without them, a machine would receive packets and have no way of identifying which application should handle them. Multiple applications can run on the same machine and share the same IP address as long as they have unique port numbers. This is known as multiplexing.

UDP’s use cases

The two advantages of UDP over other transport layer protocols are that it is 1) fast and 2) simple. Its use cases follow from that.

UDP makes sense when the application layer protocol has very basic requirements and the benefits of a persistent TCP connection are not worth the costs. For example, here is my computer requesting the IP address using DNS:

A DNS request captured in Wireshark

We’ll look at DNS in detail in a later post. What’s important to know now is that it sends out its request in a single packet. The response comes in a single packet too. Why bother with some fancy TCP connection? All we need UDP to do is identify the payload as a DNS request (note the destination port value 53) and checksum the payload.

Incidentally, this image is a neat demonstration of how protocols are nested. We have DNS inside UDP inside IP inside Ethernet. Wireshark is a free tool that monitors the packets coming and going on your connection. I highly recommend you download it and have a poke around. You might be surprised at all the programs using your network!

UDP also makes sense when speed is more important than correct delivery. You might be thinking “but Tom, when would correct delivery ever not be important?!”. One word: streaming.

In order to correctly deliver a message in order, TCP needs to hold on to the message’s packets as they arrive, put them in order and request retransmission of any that were dropped by the network. Only when every packet has been safely delivered can it pass the message on to the receiving application. Usually that’s what we want and everything’s hunky dory. Sometimes, though, that’s a problem. Holding on to packets implies some delay, or latency.

As anyone who’s spent a large part of the last year on Zoom will know, latency can really affect the quality of things like video chats, streaming services, online games and so on. Such applications work by sending a constant stream of updates. It is more important that the recipient is up to date than that it receives every single update. It doesn’t really matter if you lose one frame out of ten arriving every second, but you’ll definitely notice more latency.

UDP really shines here. It can send out updates as fast as the network and recipients can handle them. Zoom, for example, will attempt to use UDP when it can.


UDP is our first transport layer protocol. It’s a petit and bijou little protocol that’s really not much more that a thin wrapper around IP. It only offers two services: a payload checksum and source/destination ports. Like IP, it does not guarantee delivery.

Ports act like virtual mailboxes, allowing potentially thousands of applications to multiplex over one IP address. Some lower numbered ports are considered allocated to well-known application layer protocols. The remainder can be used for whatever you want.

Because UDP is unreliable but very lightweight, it’s popular with application layer protocols that have very simple requirements. Streaming and multimedia also services frequently choose UDP because they prioritise low latency over reliability.

I hope this post has whetted your appetite for more transport layer goodness. In the next post, we’ll tackle the big daddy of Internet protocols: the Transmission Control Protocol. Don’t miss it!

Did you find this useful?

Sign up to the mailing list and get free content sent to your inbox every few weeks.

* indicates required