DEV Community

Jonas Hämmerle
Jonas Hämmerle

Posted on

QR code error correction levels: L vs M vs Q vs H, and when the tradeoff is actually worth it

Every QR code has a Reed-Solomon error-correction level baked in — L (~7% recovery), M (~15%), Q (~25%), H (~30%) — and picking the wrong one either wastes visual density or leaves you with a code that stops scanning the moment it gets a little damaged.

Here's the actual decision, not just the percentages:

  • L — clean digital display only (a code shown on a screen, never printed, never overlaid with anything). Smallest, least dense module grid for a given payload.
  • M — the safe default for most printed material. Handles minor print smudging or a slightly low-quality printer.
  • Q — printed material that gets handled a lot (product packaging, shipping labels) or is at moderate risk of scuffing.
  • H — anything with a logo or graphic overlaid on top of the code, since that overlay is itself "damage" the decoder has to recover from. Also the right call for outdoor/weather-exposed prints.

The mistake I see most often: defaulting to H everywhere "to be safe." Higher error correction means more modules for the same data, which means a denser, harder-to-scan-from-a-distance code with zero benefit if nothing's ever going to obscure it. Match the level to the actual damage risk, not to the theoretical maximum.

curl "https://qr-api.p.rapidapi.com/v1/qr?data=https://example.com&ecc=Q" \
  -H "X-RapidAPI-Key: <your-key>" \
  -H "X-RapidAPI-Host: qr-api.p.rapidapi.com" \
  --output qr.svg
Enter fullscreen mode Exit fullscreen mode

QR API exposes ecc as a plain query param (defaults to M) so you can set it per use case instead of hardcoding one level everywhere.

Top comments (0)