What is a good bed mesh range?
Aim for a range below your first layer height, usually 0.2 mm. Under that, the mesh only evens out small differences. No firmware publishes a target. Makers’ own figures run from about 0.05 mm, where Voron’s docs say a mesh may not be needed, to 0.5 mm “normal” on the Snapmaker U1 and 3 mm on the Creality K1.
The calculator compares your range with your first layer height. A range larger than the first layer means no single Z offset gives the whole bed a usable first layer, so mesh compensation must stay enabled. What printer makers write about their own machines:
| Source | Figure | What it says |
|---|---|---|
| Voron docs | about 0.05 mm | “For total variance under ~0.05mm, a bed mesh may not be necessary.” |
| Raise3D, Pro3 series | 0.15 | Flatness at or under 0.15 (no unit given): “the printer can print normally” |
| Snapmaker U1 | 0.5 mm | “Range under 0.5mm considered normal.” |
| Sovol SV08 | 0.6 mm | Within 0.6 mm “will not have any impact on the printing”; between 0.8 and 1.2 mm, measure the bed’s curve with a ruler |
| Creality CR-10 SE | 2 mm | “less than 2mm from the maximum to the minimum is considered normal” |
| Creality K1 | 3 mm | Under 3 mm “is within the normal range”; above 5 mm, retighten the Z axis |
The large figures are fault checks (is something broken?), not print-quality targets. Bambu Lab, Elegoo, QIDI, Anycubic and Flashforge publish no number. Neither do Klipper, Marlin or Prusa.
Range, variance and deviation
- Range is the highest probed point minus the lowest. Mainsail’s “Range” and the range in Fluidd’s profile list are exactly this, from the probed points. In Mainsail’s code the getter is called “variance”, and Voron’s docs say “total variance” for the same number.
- Fluidd’s chart shows the range of the interpolated mesh by default, the smoothed grid between probe points. It can read a little different from the probed range; switch the chart to “Probed matrix” to compare like with like.
- Standard deviation (σ) is the typical distance of a point from the mean, worked out the same way as Klipper’s
graph_mesh.py analyze. A bed with one high corner has a big range but a small σ; a bed with ripples everywhere has both large. - Deviation usually means one point’s distance from the mean or from the reference point. The highest and lowest points the calculator lists are those deviations.
Check your probe before reading small differences. Klipper’s docs call a spread up to 0.005 mm between repeat readings normal; above 0.025 mm, the probe “does not have sufficient accuracy for typical bed leveling procedures.” Klipper’s PROBE_ACCURACY command measures it. Two meshes that differ by less than your probe’s spread differ only by noise.
What should my bed mesh look like?
Mostly flat, with a range below your first layer height and smooth steps between neighboring points. A steady slope from one edge to the other is tilt, which the leveling screws remove. A bowl, dome or twist is the bed’s own shape, which the mesh corrects. A single point far from its neighbors is worth probing again.
| What the map shows | What it is | What to do |
|---|---|---|
| One edge or corner high, a steady ramp to the other side | Tilt | Level the screws: the calculator links the tilt to the bed leveling screw calculator |
| Center high or low, edges the other way (dome or bowl) | The bed’s shape | Leave it to the mesh, measured with the bed at printing temperature |
| Two opposite corners high, the other two low (a twist) | The bed’s shape | Leave it to the mesh |
| One point far from its neighbors | A probe misread, debris on the sheet or a real dent | Clean the sheet and probe again. If it stays, it’s real |
Heat soak the bed before you judge its shape. For an SV08 range over 1 mm, Sovol advises holding the bed at 65 °C for 30 minutes before meshing.
How the numbers are calculated
The calculator reads every probed point into a grid, front row first, then works out:
range = highest − lowest
mean = sum of all points / number of points
σ = √(sum of (point − mean)² / number of points)
Tilt comes from a least-squares plane through all the points: the flat, tilted surface that sits closest to the mesh. Its slope from the left edge to the right edge is the left-to-right tilt; front edge to back edge is the front-to-back tilt. Subtract the plane from every point and what’s left is the bed’s own shape; its range is “Shape left without the tilt”. That is roughly what you’d see after perfect leveling.
The example mesh (a saved Klipper mesh from an Elegoo Neptune) shows the split well: 0.803 mm of range, with the front 0.723 mm higher than the back. Take the tilt out and about 0.10 mm of shape is left. The two parts don’t sum to the total range: the highest and lowest points of each part fall in different places.
The “Turn this tilt into screw turns” link sends the plane’s height at the four corners of the mesh to the bed leveling screw calculator. Screws usually sit outside the probed area, so the real adjustment is a little larger than the corners suggest; run the mesh again after one round of turns.
Where to copy your mesh from
| Firmware | Command or file | Rows printed |
|---|---|---|
| Klipper | BED_MESH_OUTPUT, the “Mesh Leveling Probed Z positions” lines |
Front row first |
| Klipper | printer.cfg, the #*# [bed_mesh default] block’s points |
Front row first |
| Klipper | BED_MESH_OUTPUT, the “Measured points” lines |
Back row first, and interpolated |
| Marlin bilinear or mesh bed leveling | M420 V, or the grid G29 prints |
Row 0 is the front |
| Marlin UBL (Unified Bed Leveling) | G29 T or M420 V |
Top row is the back |
| Prusa MK4, Core One, XL, MINI | The UBL report: their firmware uses Marlin’s code (Prusa documents no text output) | Top row is the back |
| Prusa MK3, MK2.5 | G81 |
Back row first |
The calculator recognizes each of these from the lines around the numbers and puts the rows in the right order. Two traps:
- Klipper’s “Measured points” is not what was measured. It’s the interpolated mesh, printed back row first, and the “Mesh Range” line above it comes from the same interpolated grid. Paste the “Probed Z positions” lines, or the saved profile, for the real probe readings.
- Prusa’s G81 always prints 7 × 7. With the factory setting of 3 × 3 probing, 40 of the 49 numbers are interpolated, so the standard deviation and the tilt rest on nine real points.
Klipper subtracts the Z at zero_reference_position from every point when one is set, so the mesh reads 0 at that position. That shifts every value equally: range, σ, tilt and shape stay the same. Only the mean and the highest and lowest values move.
After the mesh: fade and per-side correction
- Fade. Klipper’s fade is off by default (
fade_end: 0), so the mesh correction applies at every layer. Its docs suggestfade_end: 10if you want the correction to taper out over the first 10 mm. Marlin’sDEFAULT_LEVELING_FADE_HEIGHTis 10 mm in the stock configuration, andM420 Z0disables fade. - Prusa’s Bed Level Correction shifts the left, right, front or back by up to ±100 µm. Prusa’s knowledge base says even 20 µm can make a big difference. Next to the ranges above, a usable correction is tiny.
Published · Figures last checked
Sources
- Klipper source, klippy/extras/bed_mesh.py (BED_MESH_OUTPUT, saved profiles, zero reference) (accessed 2026-10-19)
- Klipper source, klippy/extras/bed_mesh.py (probed points stored front row first) (accessed 2026-10-19)
- Klipper source, scripts/graph_mesh.py (range, mean, standard deviation) (accessed 2026-10-19)
- Klipper documentation, Bed mesh: mesh fade (accessed 2026-10-19)
- Klipper documentation, Bed mesh: zero reference position (accessed 2026-10-19)
- Klipper documentation, Configuration reference: bed_mesh (accessed 2026-10-19)
- Klipper documentation, Probe calibration: repeatability check (accessed 2026-10-19)
- Marlin source, src/feature/bedlevel/bedlevel.cpp (print_2d_array) (accessed 2026-10-19)
- Marlin source, src/feature/bedlevel/ubl/ubl.cpp (topography report) (accessed 2026-10-19)
- Marlin source, Configuration.h (DEFAULT_LEVELING_FADE_HEIGHT) (accessed 2026-10-19)
- Marlin Firmware documentation, M420 Bed Leveling State (accessed 2026-10-19)
- Marlin Firmware documentation, G29 Mesh Bed Leveling (accessed 2026-10-19)
- Prusa-Firmware (MK3), mesh_bed_leveling.cpp (G81 output) (accessed 2026-10-19)
- Prusa-Firmware (MK3), mesh_bed_calibration.cpp (3 × 3 probing default) (accessed 2026-10-19)
- Prusa-Firmware-Buddy, ubl.cpp (MK4, Core One, XL, MINI topography report) (accessed 2026-10-19)
- Prusa Knowledge Base, P.I.N.D.A./SuperPINDA sensor testing (G81) (accessed 2026-10-19)
- Prusa Knowledge Base, Bed level correction (accessed 2026-10-19)
- Mainsail source, bedmesh.ts (Range) (accessed 2026-10-19)
- Fluidd source, store/mesh/getters.ts (profile Range) (accessed 2026-10-19)
- Fluidd source, store/mesh/state.ts (chart shows the mesh matrix by default) (accessed 2026-10-19)
- Voron documentation, Secondary printer tuning (bed mesh) (accessed 2026-10-19)
- Snapmaker Wiki, U1 first layer printing troubleshooting (accessed 2026-10-19)
- Sovol Wiki, SV08: the hotbed is not level or the heightmap values vary greatly (accessed 2026-10-19)
- Sovol Wiki, How to enhance SV08 first layer printing (accessed 2026-10-19)
- Raise3D Support, Pro3 series: how to level the bed (accessed 2026-10-19)
- Creality Wiki, CR-10 SE first layer troubleshooting (accessed 2026-10-19)
- Creality Wiki, K1 leveling issue resolution (accessed 2026-10-19)
- Example mesh: a saved Klipper mesh from an Elegoo Neptune (GitHub issue) (accessed 2026-10-19)