211

What is the maximum packet size for a TCP connection or how can I get the maximum packet size?

informatik01
  • 15,174
  • 9
  • 67
  • 100
Alexa
  • 2,141
  • 2
  • 13
  • 4
  • 24
    TCP is stream based. Is there a specific reason you're worrying about individual packets? – Matti Virkkunen Apr 10 '10 at 14:39
  • 29
    Because the layers below it are packet based...Typical Implementation -> Layer 1 - Ethernet PHY, Layer 2 - Ethernet MAC (MAC Packet Definition, Layer 3 - Internet Protocol ( IP Packet Definition ), Layer 4 - TCP (Transmission Control Protocol ) - Uses packet based service below it. –  Jul 19 '12 at 16:04
  • 2
    There is no such thing as a 'TCP packet'. There are TCP *segments*, whose length is described by a 32-bit word, and they are contained within or across *IP* packets, whose length is described in 16 bits. There are also Ethernet frames, which contain all these things. Which of these things are you asking about? In any case if you're using TCP you don't have to worry about any of them in any way: TCP and IP look after it all for you. – user207421 Mar 19 '18 at 01:43

10 Answers10

192

The absolute limitation on TCP packet size is 64K (65535 bytes), but in practicality this is far larger than the size of any packet you will see, because the lower layers (e.g. ethernet) have lower packet sizes.

The MTU (Maximum Transmission Unit) for Ethernet, for instance, is 1500 bytes. Some types of networks (like Token Ring) have larger MTUs, and some types have smaller MTUs, but the values are fixed for each physical technology.

Ether
  • 48,919
  • 12
  • 83
  • 153
  • 18
    "But the values are fixed for each physical technology" -- this isn't true. Ethernet used to have a maximum MTU of 1500, but you could use a lower one. With the advent of jumbo frames, there is no real specified maximum, and the maximum varies depending on the hardware and driver. – WhirlWind Apr 10 '10 at 17:08
  • 4
    @Whirl: true, they are configurable, but generally they aren't; "configurable" is subjective because one would have to delve into the kernel to do so. It's not something one can tinker with at the application level, which is where the OP seems to be at. – Ether Apr 10 '10 at 17:12
  • Very relevant...for estimating how many packets your site takes to load....if ethernet is at 1500 why is the average GET only around 600 Bytes ? –  Jun 17 '12 at 19:02
  • 3
    @HiroProtagonist: 1500 is a maximum, so having 600 is not surprising. – Nicolas Raoul Jul 19 '12 at 09:13
  • Ethernet PHYs (Layer 1 of the ISO OSI), for example the Cirrus Logic 8900A, are defined as MB/s...10/100/1000 for example...I haven't read a spec in a while but this likely is defined in the data sheet for the device....usually a chip will implement the PHY and MAC layer ( layer 1 and 2 )...this is the hardware definition of ethernet...need to see if MTU is defined there as well. –  Jul 19 '12 at 16:00
  • 33
    why is it 64K(65535 bytes) the limitation? Because the Window Size attribute in the TCP Header is only 16 bits. I just wanted to mention, could help someone sometime..... great answer btw @Ether! – Cacho Santa Apr 06 '13 at 23:08
  • @Ether can we achieve the line rate at 1500 packet size in Linux? – user2087340 Nov 06 '13 at 16:51
  • 2
    Also, it is possible to boost it up by using window scaling. In that case the maximum is 1 GiB – Martin Melka Apr 24 '14 at 10:59
  • Correct Max = 65535 bytes and beyond this value, you will get exception error. – Ashraf Sada Jan 15 '15 at 13:35
  • 1
    Does the packet size change depending on what you're sending? Like if I send something much smaller than a particular packet size, does the rest of the packet just get padded with empty data? If not, does that make packets a variable size unit? How does the computer decided what the appropriate packet size for any particular data transfer then? – CMCDragonkai Mar 20 '15 at 07:02
  • 1
    @CMCDragonkai this is too complicated to explain in a SO comment. :) I would recommend you pick up a copy of the "TCP/IP Illustrated" series by Stevens, or indeed any book by Stevens is excellent. – Ether Mar 20 '15 at 18:01
  • @Martin!elka Window scaling affects the receive window, not the packet size. – user207421 Oct 23 '16 at 21:20
  • @ether: you can set the MTU/MSS/etc for an individual socket or interface at the application level (`setsockopt`/`ioctl`), or by using ifconfig/ethtool etc in Linux. No kernel. – EML May 17 '17 at 11:02
  • @Ether can you suggest some resources to study more about this ? –  May 18 '17 at 09:15
  • @user2087340 http://pubs.opengroup.org/onlinepubs/009695399/functions/setsockopt.html – Garet Claborn Nov 13 '17 at 06:04
89

This is an excellent question and I run in to this a lot at work actually. There are a lot of "technically correct" answers such as 65k and 1500. I've done a lot of work writing network interfaces and using 65k is silly, and 1500 can also get you in to big trouble. My work goes on a lot of different hardware / platforms / routers, and to be honest the place I start is 1400 bytes. If you NEED more than 1400 you can start to inch your way up, you can probably go to 1450 and sometimes to 1480'ish? If you need more than that then of course you need to split in to 2 packets, of which there are several obvious ways of doing..

The problem is that you're talking about creating a data packet and writing it out via TCP, but of course there's header data tacked on and so forth, so you have "baggage" that puts you to 1500 or beyond.. and also a lot of hardware has lower limits.

If you "push it" you can get some really weird things going on. Truncated data, obviously, or dropped data I've seen rarely. Corrupted data also rarely but certainly does happen.

Nektarios
  • 9,551
  • 7
  • 57
  • 91
  • Why are GET requests averaging about 600 Bytes ? –  Jun 17 '12 at 19:03
  • 11
    You mean 64K, not 65K. I don't know what you mean by 'the place I start is 1400 bytes'. You don't have to worry about packet sizes in the TCP API. It takes care of determining and observing the path MTU. There is no reason why you can't write 2G in one `send()` if it's convenient. – user207421 Feb 05 '13 at 06:20
  • @Nektario can we achieve the line rate at 1500 packet size in Linux? – user2087340 Nov 06 '13 at 16:51
  • 22
    Your `1480'ish` should be `1460`. The IP header and the TCP header take up 20 bytes each at least (unless optional header fields are used) and thus the max for (non-Jumbo frame) Ethernet is `1500 - 20 -20 = 1460`. – Evgeniy Berezovsky Jul 28 '14 at 07:02
  • 2
    I have seen via wireshark that a server sends large packets (over 1400 bytes) and the client receives it disassembled as few packets of 1400 bytes maximum. who is responsible for the disassembling of the packet? @Nektario ...? – inbaly Mar 31 '15 at 07:02
  • "so you have "baggage" that puts you to 1500 or beyond" - all this baggage goes *inside* the MTU of the lower-level link layer (ie. your "1500"), so is not relevant. – EML May 17 '17 at 11:15
  • 2
    @EugeneBeresovsky well with the optional headers thats + up to 40 more bytes, but it's variable so 1420 would seem the limit. with the suggestion of 1400 you get a little padding. i'll go with 1408 since it's divisible by 128 – Garet Claborn Nov 13 '17 at 06:09
24

At the application level, the application uses TCP as a stream oriented protocol. TCP in turn has segments and abstracts away the details of working with unreliable IP packets.

TCP deals with segments instead of packets. Each TCP segment has a sequence number which is contained inside a TCP header. The actual data sent in a TCP segment is variable.

There is a value for getsockopt that is supported on some OS that you can use called TCP_MAXSEG which retrieves the maximum TCP segment size (MSS). It is not supported on all OS though.

I'm not sure exactly what you're trying to do but if you want to reduce the buffer size that's used you could also look into: SO_SNDBUF and SO_RCVBUF.

Brian R. Bondy
  • 314,085
  • 114
  • 576
  • 619
7

According to http://en.wikipedia.org/wiki/Maximum_segment_size, the default largest size for a IPV4 packet on a network is 536 octets (bytes of size 8 bits). See RFC 879

Robert Jacobs
  • 2,932
  • 1
  • 15
  • 29
4

Generally, this will be dependent on the interface the connection is using. You can probably use an ioctl() to get the MTU, and if it is ethernet, you can usually get the maximum packet size by subtracting the size of the hardware header from that, which is 14 for ethernet with no VLAN.

This is only the case if the MTU is at least that large across the network. TCP may use path MTU discovery to reduce your effective MTU.

The question is, why do you care?

WhirlWind
  • 13,246
  • 2
  • 39
  • 41
4

There're no packets in TCP API.

There're packets in underlying protocols often, like when TCP is done over IP, which you have no interest in, because they have nothing to do with the user except for very delicate performance optimizations which you are probably not interested in (according to the question's formulation).

If you ask what is a maximum number of bytes you can send() in one API call, then this is implementation and settings dependent. You would usually call send() for chunks of up to several kilobytes, and be always ready for the system to refuse to accept it totally or partially, in which case you will have to manually manage splitting into smaller chunks to feed your data into the TCP send() API.

Pavel Radzivilovsky
  • 17,994
  • 3
  • 54
  • 65
  • 8
    TCP has packets, as well as a packet header, part of which overlaps the IP header. Just because you're not supposed to see it doesn't mean it doesn't exist. TCP is *always* done over IP. You can't do it without IP because the headers overlap. – WhirlWind Apr 10 '10 at 14:49
  • 24
    @WhirlWind TCP has *segments.* IP has packets. – user207421 Feb 05 '13 at 06:18
  • @EJP - what is the harm in calling "segments" and "frames" by the generic name "packet" - TCP packet, Ethernet packet, etc? – Nathan Long Jul 23 '13 at 16:38
  • 3
    TCP has segments (or call them packets, it's ok). TCP API has no packets. – Pavel Radzivilovsky Jul 26 '13 at 08:25
  • 15
    @NathanLong The harm is that you cause needless confusion. TCP has segments, UDP has datagrams, IP has packets, Ethernet has frames, ... – user207421 Dec 31 '15 at 10:54
  • @EJP Well technically all IP packets are datagrams as well... Not just the UDP ones. And I must agree with Nathan here, packet is a generic term even despite it being the somewhat preferred term for IP. – Chexxor Oct 16 '16 at 20:18
  • 1
    @Chexxor So what language are you going to use to describe TCP segments inside IP packets inside Ethernet frames? There is no need whatsoever to confuse the issue by using the same term for different things, when the authors of these things have gone to a lot of trouble to use different terms. – user207421 Mar 19 '18 at 01:42
3

If you are with Linux machines, "ifconfig eth0 mtu 9000 up" is the command to set the MTU for an interface. However, I have to say, big MTU has some downsides if the network transmission is not so stable, and it may use more kernel space memories.

DAG
  • 347
  • 2
  • 7
3

It seems most web sites out on the internet use 1460 bytes for the value of MTU. Sometimes it's 1452 and if you are on a VPN it will drop even more for the IPSec headers.

The default window size varies quite a bit up to a max of 65535 bytes. I use http://tcpcheck.com to look at my own source IP values and to check what other Internet vendors are using.

jkdev
  • 9,037
  • 14
  • 52
  • 75
3

The packet size for a TCP setting in IP protocol(Ip4). For this field(TL), 16 bits are allocated, accordingly the max size of packet is 65535 bytes: IP protocol details

rakwaht
  • 2,721
  • 1
  • 23
  • 37
Ziegfried
  • 91
  • 12
2

One solution can be to set socket option TCP_MAXSEG (http://linux.die.net/man/7/tcp) to a value that is "safe" with underlying network (e.g. set to 1400 to be safe on ethernet) and then use a large buffer in send system call. This way there can be less system calls which are expensive. Kernel will split the data to match MSS.

This way you can avoid truncated data and your application doesn't have to worry about small buffers.

hashtpaa
  • 379
  • 2
  • 11