UART/Timing and trouble/The receive buffer
Lesson 8 of 12 · in 3D and VR

The receive buffer

A UART receiver does not hand each byte to your program as it arrives. It parks it in a small buffer, first in, first out. If the program reads slower than the bytes come in, the buffer fills, and the bytes that arrive after that are lost, with no resend.

Lonely BinaryUpdated 2026-10-014 min readNo board required

View it in VR

Lesson 8 of the UART course opens in a VR headset, on a table in front of you, and a voice starts three seconds after you arrive. Type this short address into the browser on a headset such as Meta Quest or Apple Vision Pro, and press Enter VR. No headset? Press Start the lesson: the same lesson, full screen.

learn.lonelybinary.com/vr/uart/8

When a receiver has read a whole frame, it has one byte and nowhere to give it. Your program is busy with something else, and the next frame is already on its way. So the byte goes into a small buffer, and the program takes bytes out when it gets round to it, oldest first. That buffer is a first in, first out buffer, a FIFO.

How big it is

On the ESP32, ESP32-S3 and ESP32-C3 the hardware FIFO is 128 bytes by default, for each UART and each direction. The RAM it uses can be re-divided between the UARTs, so the number is a default, not a law.

The Arduino core for the ESP32 does not leave it at that. Its serial driver keeps a receive buffer in software, 256 bytes by default, and fills it from the hardware FIFO. That 256 is a ring buffer on top of the chip's FIFO, and not a bigger FIFO. Calling it a 256-byte FIFO mixes the two up.

How fast it fills

A byte at 8N1 takes ten beats on the line. At 115200 baud that is about 87 microseconds, so 128 bytes arrive in about 11 milliseconds. At 9600 baud the same 128 bytes take about 133 milliseconds. Those times are for a line that is busy all the time, and they say how long the program can ignore the port: a print, a delay or a slow sensor read can be that long.

What happens when it is full

The next byte finds the FIFO full, and bytes are lost. The receiver raises an overrun flag. The ESP32's UART has an interrupt for it. Which byte is dropped depends on the layer, so the safe statement is that bytes are lost.

Nothing asks the sender to send them again. A UART frame has no acknowledgement and no resend, and the line was never at fault, so none of the line's checks sees anything wrong. The first sign is a message with a piece missing. If the receiver is the ESP32, the wire is not where to look; the program reading too late is.

What fixes it

Read more often or in a task of its own, so the program is never away for 11 milliseconds. Send slower, with a lower baud or gaps between messages. Make the buffer bigger, which buys time and does not remove the limit, because a longer burst fills any buffer. Or let the receiver tell the sender to stop, which is flow control, in lesson 10. The ESP32 book covers the driver's side in UART and baud rates.

Common mistakes

  • Calling the 256 bytes the UART's FIFO. The hardware FIFO is 128 bytes by default. The 256 is the Arduino driver's own buffer on top.
  • Looking at the wire for lost bytes. Overrun is the receiver falling behind. The frames that did arrive are good.
  • Making the buffer bigger and calling it fixed. A bigger buffer postpones the loss, and a longer burst fills it again.

Edit this page — content/fundamentals/uart/receive-buffer.mdx

Discuss this article

Ask about this page. The answer stays here, on the page it belongs to, for whoever hits the same wall next.

Browse Fundamentals on the forum →