Voice over IPsec is quoted as a codec bitrate, and that figure is wrong at every boundary except the codec's own. The audio is 8 kbit/s, the packet carrying it is larger, the ESP envelope is larger again, and the Ethernet frame adds framing that a capture on the tunnel never shows. Counting one packet from a stated format is the only way to learn what the physical link actually has to carry. The walk below does that for one direction only, and every number here is arithmetic rather than measurement.

Start from a packetization choice, not a codec figure

A codec chart gives the payload rate and nothing else: G.729 emits 8 kbit/s, which is 30 bytes of audio every 30 ms. It says nothing about headers, protection or framing, and those three dominate the result. The interval is a policy choice that both ends have to agree on, so pick it first and state it, because every later number depends on that single decision.

This example uses 30 ms, so the packet rate is 33.3 per second. It assumes a 12-byte RTP header, an 8-byte UDP header and a 20-byte inner IPv4 header with no options, and no SRTP, header compression or traffic-flow-confidentiality padding; any change moves the budget with it, which is why the assumptions belong next to the answer.

Add the inner headers, then the ESP envelope

The application sends payload plus RTP plus UDP plus IP, which is 70 bytes at this packetization. That inner stream works out to 18.7 kbit/s, already more than twice the codec rate, because headers rather than audio make up most of the packet. None of those bytes are voice, they are the price of addressing and sequencing it. A capture taken above the tunnel shows exactly this number, and it is the one people quote when they say the call is small.

It is also the number that never reaches the wire. ESP tunnel mode adds an 8-byte SPI and sequence number, an 8-byte explicit IV for AES-GCM, a 2-byte trailer and a 16-byte authentication tag. The 70-byte payload plus the trailer lands on 72, which already satisfies the four-byte alignment, so no extra padding is needed here. RFC 4106 fixes the GCM IV and tag sizes, and both belong in the arithmetic rather than in a footnote:

30  payload, G.729 at 30 ms
12  RTP
 8  UDP
20  inner IPv4
--
70  inner IP packet
 8  ESP SPI and sequence
 8  explicit IV
 2  pad length and next header
16  authentication tag
--
104 ESP packet

Add the outer headers that NAT traversal requires

Outside the ESP envelope sit a 20-byte outer IPv4 header and an 8-byte UDP header for NAT traversal, so the packet becomes 132 bytes. The UDP encapsulation exists because the packet has to survive a translating device between the peers, and it changes the outer shape without touching the protected payload. At 33.3 packets per second, 132 bytes is about 35.2 kbit/s, or roughly four times the codec's nominal rate.

Neither the tag nor the IV can be dropped from the estimate to make it smaller, because both are part of what the link will actually carry. An estimate that omits them describes a packet the receiver would reject. The same applies to the trailer, which exists to mark the payload boundary and the next header inside the protected region.

Name the boundary before quoting the number

An outer IP figure still excludes Ethernet framing. A tagged or untagged access link adds a 14-byte MAC header and a 4-byte frame check sequence, making the frame 150 bytes, which is the size a switch port counts. At the same packet rate that is 40 kbit/s, five times the codec rate, and the difference is not waste but the cost of carriage.

BoundaryPacket sizeRate at 33.3 packets/sWhat it counts
Codec payload30 bytes8.0 kbit/sThe audio alone
Inner IP packet70 bytes18.7 kbit/sApplication headers included
Outer IP packet132 bytes35.2 kbit/sESP and NAT-T included
Ethernet frame150 bytes40.0 kbit/sLink framing included

The 40 kbit/s figure still excludes the preamble, the interframe gap, VLAN tags, provider encapsulation, RTCP, signalling and the audio travelling the other way. It is a per-direction estimate, not a link reservation, and quoting it as one overstates what the link must reserve in one place while understating it in another. A host capture can also miss framing that the link adds, which is why the boundary has to be named alongside the number, and why a boundary table is more useful than a single headline figure. Reserve separately for the direction you did not count.

Check the arithmetic against the interface

Before trusting the estimate, compare it with what the interface reports for a known number of packets. Capture on the physical interface rather than the tunnel device, so the framing you are trying to account for is included, and expect a small disagreement rather than a perfect match.

sudo tcpdump -ni eth0 -c 50 'udp port 4500'
ip -s link show eth0

The capture confirms the outer packet size, while the interface counters show the rate including framing. If the two differ by about the Ethernet allowance, the arithmetic is right and only the boundary was mislabelled. A difference far larger than one frame header points at something else on the link, such as retransmissions or another flow sharing the interface. Write the packetization interval, the protection suite and the boundary next to the number, because an estimate without those three gets quoted as a measurement by the next person who reads it.

Nsɛm a ɛfa ho