How Much UART Baud Rate Error Is Too Much?
Every UART tutorial says "keep the baud rate error under 2%". Few say where the number comes from, which makes it hard to judge the cases that matter: a −3.5% divider that seems to work on the bench, a link that only fails on long bursts, or a 9-bit frame on an internal RC oscillator. The rule falls out of a short piece of arithmetic, and once you have it you can work out the budget for your own link.
What the receiver actually does
A UART has no clock line. The receiver waits for the falling edge of the start bit, then uses its own clock to sample each following bit in the middle of the bit period. It never looks at the edges again until the next start bit. Any difference between the transmitter's bit time and the receiver's bit time therefore accumulates across the frame, and resets to zero at the next start bit.
For the usual 8N1 frame there are 10 bits on the wire: one start bit, eight data bits, one stop bit. The last bit the receiver must read correctly is the stop bit, and its centre sits 9.5 bit times after the start edge. The frame is received correctly as long as that last sampling point has not drifted out of its bit, which means the accumulated drift must stay under half a bit:
drift at last sample = 9.5 bit times × relative clock error < 0.5 bit
relative clock error < 0.5 / 9.5 = 5.26 %
That 5.26% is the total mismatch between the two ends. It is not what each device may contribute, and it assumes a perfect receiver.
Three things that eat the budget
1. Start-edge uncertainty
The receiver finds the start edge by oversampling the line, normally 16 times per bit. It can therefore be late by up to one sixteenth of a bit before it even starts counting. With 8× oversampling the uncertainty doubles to one eighth of a bit. Subtract that from the half-bit margin:
| Frame | Bits on the wire | Ideal total budget | With 16× oversampling | With 8× oversampling |
|---|---|---|---|---|
| 8N1 | 10 | ±5.26% | ±4.61% | ±3.95% |
| 8E1 or 8N2 | 11 | ±4.76% | ±4.17% | ±3.57% |
| 9 data bits + parity, or 8E2 | 12 | ±4.35% | ±3.80% | ±3.26% |
Two things stand out. Longer frames are less tolerant, because the last sample is further from the start edge. And 8× oversampling, which is usually switched on to reach a higher baud rate or a better divider, costs about 0.7 percentage points of margin.
2. There are two clocks
The budget is shared. If both ends are equally bad in opposite directions, each may use half: about ±2.3% for 8N1 at 16× oversampling, and about ±1.9% for a 12-bit frame. This is where the 2% rule comes from. It is the per-device share of a roughly 4% total, rounded down.
It also means the rule is too strict in one common case and too loose in another. If the other end is a USB-serial adapter or a PC with a crystal-derived clock, its error is close to zero and your side can use almost the whole budget. If the other end is another microcontroller on an internal oscillator, 2% on your side may already be too much.
3. The signal is not ideal
Slow edges through an RS-485 transceiver or an opto-isolator, noise, and receivers that take three samples around the bit centre and vote all narrow the usable window further. None of these can be put into a universal number, which is why a design should aim well inside the calculated limit instead of at it.
Where the error comes from
Divider rounding
The baud rate is the peripheral clock divided by an integer, so only some rates are reachable exactly. For 115,200 baud:
| Clock and divider | Divider value | Actual baud | Error | Drift at the stop bit |
|---|---|---|---|---|
| 16 MHz, integer divider, 16× | 9 | 111,111 | −3.55% | 0.34 bit |
| 16 MHz, integer divider, 8× | 17 | 117,647 | +2.12% | 0.20 bit |
| 8 MHz, fractional divider (BRR 0x45) | 69 | 115,942 | +0.64% | 0.06 bit |
| 16 MHz, fractional divider (BRR 0x8B) | 139 | 115,108 | −0.08% | under 0.01 bit |
| 72 MHz, fractional divider (BRR 0x271) | 625 | 115,200 | 0% | none |
| 14.7456 MHz crystal, integer divider, 16× | 8 | 115,200 | 0% | none |
The first row is the classic 16 MHz AVR case. A drift of 0.34 bit is still inside the half-bit limit, which is why the link often works on the bench against a PC. But it has used 3.55 of the 4.61 percentage points available, leaving about 1% for the other end, the oscillator and the signal quality. It fails when any of those gets slightly worse.
The last row is why crystals with odd values such as 14.7456 MHz, 11.0592 MHz and 7.3728 MHz exist. They are multiples of the standard baud rates, so every standard rate divides out exactly.
Oscillator accuracy
Divider rounding is only half of the error. The clock itself is off by its own tolerance, and that adds directly. A crystal is accurate to tens of parts per million, which is thousands of times smaller than the budget and can be ignored. An internal RC oscillator is a different matter: it is often specified at around ±1% at room temperature and noticeably more across the full temperature and supply range. Read the oscillator table in your device's datasheet and add the worst-case figure to the divider error before comparing against the budget.
Symptoms that point to baud error
- The high bits are wrong first. Data is sent least significant bit first, so drift corrupts bit 7 and the stop bit before it touches bit 0. Bytes that differ from the expected value only in the top bit or two, together with framing errors, are a strong hint.
- Single bytes work, bursts fail. When the transmitter is faster than the receiver, the receiver can still be inside what it thinks is the stop bit when the next start bit arrives. Characters typed by hand get through, while a back-to-back block does not. A second stop bit on the transmitter is a quick way to confirm this.
- It works on the bench and fails in the field. Temperature moves an RC oscillator. A link with 1% of margin at 25 °C may have none at 70 °C.
Measuring the real error
Calculated error tells you what the divider should produce. To see what the board actually produces, transmit the byte 0x55 (ASCII U) continuously. Sent LSB first with a start and a stop bit, it gives a clean alternating pattern on the wire, a square wave at half the baud rate. Measure the width of one bit with an oscilloscope or logic analyser and compare:
| Baud rate | Expected bit time | Square wave from 0x55 |
|---|---|---|
| 9,600 | 104.17 µs | 4.8 kHz |
| 115,200 | 8.68 µs | 57.6 kHz |
| 921,600 | 1.085 µs | 460.8 kHz |
Measuring across several bits and dividing gives a better result than measuring one. The relative error is the expected bit time divided by the measured bit time, minus one. Do this for both ends of the link and add the two errors, taking the signs into account. If one end is fast and the other slow, the errors add up; if both are off in the same direction, they partly cancel.
A procedure that works
- Count the bits in your frame, including start, parity and stop bits, and take the total budget from the first table.
- Calculate the divider error for your clock and baud rate.
- Add the worst-case oscillator tolerance of your clock source.
- Do the same for the other end, or use its documented tolerance.
- If the sum is above roughly two thirds of the budget, change something: a fractional divider, a different oversampling setting, a different baud rate, or a crystal.
The two-thirds figure is a design margin for edge quality and noise, not a property of the UART. Use a smaller fraction for long cables and isolated links.
Run the numbers: UART Baud Rate Calculator does this calculation for your own values.
More guides
- ADC Resolution Is Not Accuracy: LSB Size, Reference Error, Settling and Oversampling
- C Struct Padding on Cortex-M: Where the Bytes Go and How to Control Them
- CAN Bit Timing Step by Step: Choosing BRP, Segments and Sample Point
- Why Your CRC Does Not Match: Polynomial, Init, Reflection and XOR-Out Explained
- Fixed-Point Arithmetic in Q Format: Scaling, Multiplying and Not Overflowing
- Floating-Point Pitfalls on Microcontrollers: Precision, Timestamps and Accidental Doubles
- Sizing I2C Pull-Up Resistors: Minimum, Maximum and What Bus Capacitance Does