Bed Leveling: A Methodical Approach

Jun. 27, 2022


At least for me, the single biggest frustration in hobbyist 3D printing has been the bed and first layer. Leveling, offsets, temperatures, mesh, adhesion, bed materials - it can be quite a lot to get around. And I think this is made worse by all the hacky and conflicting documentation/tutorials on the web, which sometimes work and sometimes don’t, and even when they work, don’t really explain why. In this article, I want to talk about what I’ve learned in the past 4 years in regards to this. Most importantly, I want to take (what I think is) a more methodical approach instead of try random stuff until your first layer sticks.

Printer Notes

Most of my work has been on my own Ender 3 (v1) printer. However, recently, I’ve worked with my club’s Voron 2.4, which brings its own interesting characteristics. Nonetheless, the material in this article should be applicable to most printers.

Software/Firmware Notes

I use the Klipper 3D printer firmware on both my Ender and the Voron. I feel that the feature set offered by klipper, including some routines for bed leveling, are superior to those provided by Marlin. However, most of them are purely for convenience - there is no reason why you shouldn’t be able to get a perfect first layer running Marlin, RepRapFirmware, or anything else.

Additionally, I don’t change anything in my slicer. Separation of concerns: I feel that the slicer should only focus on creating g-code for printing the model, not have tweaks to account for weird bed adhesion. Klipper (and probably other firmwares) have configuration options and routines for leveling and offsets, so my recommendation is to keep things confined to the firmware.


Before we start, we need to clarify some terminology.

For starters, the term “leveling” is horrible naming that has nothing to do with being level. Some poor souls who are new to printing think they should be using a spirit level to level their printer, which couldn’t be further from the truth! In fact, your bed will most likely not actually be level with the Earth.

Creating a good first layer comes down to three main aspects, which I will explain down below:

Bed Adhesion

Bed adhesion is completely separate from the first two points and it’s important that we treat it as such. It’s common to have a perfectly trammed and calibrated first layer that doesn’t actually stick to the bed, such as on glass, or have a untrammed or badly offset first layer that still sticks because of good adhesion to the surface, such as on textured/powder-coated surfaces (buildtak style). Bed adhesion is out of the scope of this article. However, I will say that for the most part it’s a bad idea to let adhesion influence your calibration of the other two aspects. This will make more sense later, but for example, don’t increase or decrease first layer squish just to improve adhesion or make the part easier to remove - figure out your adhesion separately.

Scales and Precision

Keep in mind that the average first layer is 0.2mm (200 micron) thick. This is a pretty small amount. It is worth noting that the average printer paper is 100 microns thick and the average human hair is 70 microns thick (give or take 30 microns). But compare that to the 0.2mm micron thickness of the layer - 100 micron is 50% of that layer. Put another way, a piece of paper is the difference between a correct first layer and one that is 50% too high or too low, which can cause a huge difference in results.

To quote the klipper docs, adjustment for first layer quality usually happens on the order of 10-25 microns (5-12.5%). This is a very small amount. You cannot accurately “see” differences on this scale - you need to either feel them or infer based on the results of a first layer print. Remember, a little bit of adjustment goes a long way.

Also, remember that your 3D printer is far more accurate than you are. Let your printer do the work whenever possible instead of hand adjustment. This will become clear later on, especially for the offset calibration.

Preparation and Squaring

The first step to leveling your bed has nothing to do with the bed. I know this might sound obvious, but I’ve found huge gantry alignment issues on two Ender 3s which were causing first layer inconsistency.


Most of bed leveling is actually what’s referred to in the machining world as tramming. Tramming a CNC machine is to square up the toolhead and gantry to the work surface. Doing so means that during a horizontal move, the toolhead remains the exact same distance from the work surface at every location. In fact, the main way to tram a 3D printer is using this - measuring the distance between the nozzle and bed at different points and adjusting the bed to make this consistent across the bed.

Tramming requires you to “probe” the distance between the nozzle and bed at multiple locations. I’ve discussed the many ways of doing this (from manual paper to inductive and tactile auto probes) after this section. However, remember this: tramming is all about making sure the distance from the bed to the nozzle is consistent across the entire bed. It doesn’t matter at this stage what that distance actually is. I know, you need to have the right distance to actually get a good first layer. But that’s a problem for part 2, Z offset. Worrying about the exact distance right now will just cause you more pain.


For starters, let’s assume your bed is an infinitely stiff, perfectly flat piece of aluminum. In reality, this is definitely not the case, which causes more complications. I will address these afterwards.

It is best to do this tramming while the nozzle and bed are cold. I know a lot of documentation says to do it while hot, but this is a Klipper recommendation that I agree with; most of the expansion related issues only affect the z offset, not tramming. A hot bed just causes you to burn your hands. A hot nozzle causes plastic to ooze out and affects manual probing.

4 Point Screw Leveling

The most common bed leveling technique is the standard Ender 3 style 4 point leveling. Your bed is supported by four control points that can be raised or lowered, usually with a screw and spring. By raising and lowering the different corners, the objective is to square the bed to the gantry. In Klipper, the BED_SCREWS_ADJUST helps you out a lot, but you can do this by manually moving the toolhead around as well.

4 point leveling seems reasonably self explanatory. And it is, except for a few things to keep in mind:

  1. Make sure to “probe” the distance between nozzle and bed right on top of the screws. This prevents other variables, such as bed stress and bed warping, from affecting your results.
  2. Springs, especially the relatively weak ones on the Ender, don’t have infinite flexing range. Start with all your springs at the same tension, ideally around midway between tightest and loosest. If the nozzle isn’t close to correct at this height, adjust the Z=0 point by moving your z endstop or using a software offset. Also, putting too much tension on one spring can cause other corners to lose vertical range, so again, start with all the springs at a consistent, medium tension.
  3. It can take multiple passes across all four corners. This is normal, especially if you are making bigger changes. Be patient, even if it takes you more than 3 passes. Take the time to do it correctly.
  4. 4 point beds suffer from “see-saw”. If you raise one corner of the bed, you will most likely notice the opposite corner go down, especially with weaker springs. Imagine the bed see-sawing across the diagonal line created by the other two adjacent corners. One way I’ve noticed I can reduce this is by simultaneously adjusting the opposite corner in the same direction a little bit. But in the end, you will probably need multiple passes of the bed to get things trammed.

3 Point Screw Leveling

3 point leveling is getting more common, such as mods to the Ender that replaces the y carriage with a 3 point leveling system. The premise is that you need exactly 3 points to define a plane, and you should thus only be using 3 control points. The procedure is the same as 4 point leveling. However, while I haven’t tried it, I can see a few benefits:

  1. It is probably much less prone to see-sawing as mentioned above. This is just inherant to the geometry.

  2. 4 screws can create unwanted stress on the bed because you have more control points than you need. I’m not sure if this is a problem in reality but at least conceptually, adding additional control points to your “definition of a plane” might warp the bed slightly.

  3. It’s simply less work to adjust 3 control points than 4.

3 Point Motorized Leveling

Example, machines like the Voron Trident. The bed rests on three steppers with lead screws (or 3 z belts on mods like the Orion-Tri-Belt). The toolhead programatically probes the z distance on top of the three control points, and the bed is trammed by moving the motors (Klipper’s Z_TILT_ADJUST). This is beneficial since it is automated using an inductive or tactile probe. The Trident also features a sturdy z bed (due to the linear rails) which is always helpful.

4 Point Gantry Leveling

This is used on machines like the Voron 2.4, which have a flying gantry. The bed is secured permanently to the frame and never moves. Instead, z travel is accomplished by suspending the entire (core xy) gantry on 4 z belts and moving them up or down. The 4 belts can adjust up and down (Klipper’s QUAD_GANTRY_LEVEL) to tram the gantry to the bed.

The main benefit of this is that a fixed bed is more stable. No need to adjust the bed. Everything is rigid. The part can’t go flying off at high speeds. No flexing of the build plate (as long as your bed itself is thick enough). All you have to keep in mind here is to build the entire frame very square.

Fixed Plate/Z

The Voron Switchwire is a bedslinger like the Ender 3 and Prusa MK3, but features a completely hard mounted bed. The idea here is that as long as your printer frame is built square, there is no reason your bed should not be trammed to the gantry. Any minor issues can be accounted for using bed mesh (more on that later).

Enter: The Real World

Rigidity Issues

In practice, a moving bed is not going to perfectly rigid. Unfortunately, there isn’t much you can do about this without improving your printer mechanically. A few tips, however:

Flatness Issues

Cheap aluminum is usually not very flat. The Ender 3 commonly has a bed warping problem, where the middle of the bed sags. But in reality, no bed is perfectly flat. Even Mandala Rose Works’ ultraflat Voron beds have 100 micron tolerance, meaning one side of the bed could be 100 micron higher or lower than the other side. This will still cause a first layer that looks perfect on one corner to be 50% off on the other corner. There are both software and hardware solutions to this problem:

The software solution is to use a bed mesh. This basically probes the bed at various points (not just the corners) and extrapolates a software “mesh” modelling the contour of the bed. The firmware can then compensate g-code Z values using this mesh while printing to ensure a consistent distance from the bed to the nozzle everywhere. Bed meshes can be probed both with a digital probe or manual paper method, although the paper method can get pretty tedious! I do recommend probing your bed mesh after heatsoak (see my thermal expansion section below). Ideally, especially on cheaper/less consistent hardware, it’s best to do an automatic bed mesh on every print start. May or may not be necessary for you.

The hardware solution is to get a better bed. I still recommend that you use a bed mesh on larger build plates, but smaller ones can usually get by with a good bed.


So before we get to the z offset and actually print something useful, let’s talk about the different ways you can probe your bed, and a few things to keep in mind.

The Paper Method

For a while, the paper method used to confuse me - how can rubbing paper between your nozzle and bed be an accurate and reliable way to level a bed? After all, not all paper is a consistent thickness. It can compress a little and/or tear. It turns out that paper does work well if you are using it correctly. The key is that manual probing methods (and most other probing methods for that matter, except for z calibration which I’ll cover later) are NOT about determining the exact distance between your nozzle and bed. You should NOT expect any such probing to give you accurate enough results for this. You’re simply trying to keep a consistent distance across the bed.

In case you somehow haven’t heard of this, the paper method involves putting a piece of paper between the nozzle and bed and moving it around as you adjust the z height of the bed. You then feel the amount of friction and use that to determine the height.

People often wonder how much resistance to put on the paper. After all, that will affect the height of the bed - but remember, it won’t affect how trammed the bed is. The important thing is to keep consistent pressure/resistance on each probe point. Nonetheless, I recommend feeling for only a little bit of resistance. This is for a few reasons:

  1. In my opinion, it is easier to feel the difference between no resistance and some resistance than between some and more resistance.
  2. Digging the nozzle further into the bed can cause the bed/carriage itself to flex or bend down, which invalidates your probing.
  3. It is more likely to compress or tear the paper.

A Note on Feeler Guages

Some people recommend using feeler guages in place of paper. I’ve tried this, and it does offer some benefits. However, I don’t think it’s necessarily worth getting them; paper works fine. I’ve found that trying to feel out the actual distance between the bed and nozzle this way is not accurate enough to be worth the effort. However, feeler guages are stiff and don’t scratch/tear that easily, or compress, which is nice.


I haven’t used this, so I don’t have that much to say about it. It works. I would still use level the bed manually to get it roughly flat (or as flat as you can) before using it. You still need to calibrate a z offset even if you’re using the BL-Touch with bed mesh.

Inductive Probe

I’ve used an Omron TL-Q5MC2 on the Voron 2.4. It’s quite accurate, but can be affected by electric currents or magnets near it. Also obviously can only be used on a metal surface, not glass bed. One mildly annoying thing about inductive probes are since they trigger long before contact, your z offset will most likely be quite large compared to a tactile probe.

Klicky Probe

The klicky probe is a really cool design - I’m currently using it on the Voron 2.4. I find the docking and attaching procedure really fun. But in practice, it’s also a very reliable and accurate probe that works well on any surface. You can also use it to do auto z calibration, which I’ll mention down below.

Z Offset

Okay, hopefully your bed is now trammed. The second part of leveling is setting the Z offset. That is, actually figuring out and compensating for the distance between your nozzle and the bed. Basically, when your printer is all heated up and ready, a command to move to Z=0 should have the nozzle tip move to exactly touch the bed - no gap, no pushing into the surface. That way, your first layer will go to Z=0.2 (or whatever your first layer height is) and will lay down like any other layer.

Thermal Expansion

Yep, thermal expansion plays a significant part in your z offset. According to the klipper docs, the “expected amount of expansion” is around 100 microns. But whatever it is, you need to heat up your hotend and bed to your operating temperature and heatsoak it (let it sit there for some time). How long depends on the printer and your patience level, but I’d recommend 20-30 minutes. This allows everything to settle down at operating temperature. Larger beds also take some time for the heat to spread across the bed.

Thermal expansion can cause some other interesting effects, but that’s advanced material. I’ve included it at the end of this article.

Offset Compensation

If you used the paper method, your nozzle isn’t touching the bed (when cool), it’s separated by the 100 micron paper. According to the Klipper docs, the ~100 micron expansion of your frame tends to cancel out the ~100 micron thickness of the paper. I’ve found mixed results with this, and you should probably go on to do more compensation.

If you used an automatic probe, the offset is going to be some random value you need to figure out. This is due to the distance between the probe and the nozzle, plus the distance between activation and max travel of tactile switches.

In Klipper, the offset is set using the SET_GCODE_OFFSET Z=<x> command.

In some cases, you may be able to use auto z calibration (mentioned below). But for most simple cases, this z offset is found manually through trial and error. If it’s a large value, try a few prints until your first layers start looking like first layers, not spaghetti or scratches on your build surface. After that, make changes in 10 micron increments (5% of a 0.2mm layer height) until you like the results. AndrewEllis93 has a great guide as part of his Voron print tuning guide, but it applies to any printer:

I do have one tip to add here: as I mentioned before, don’t let the level of bed adhesion affect your Z offset. Bad first layer offset causes a lot of small defects, which may be just aesthetic but also could be difference between a functional part working or not. Often, people tend to push their Z offset too close to improve adhesion. This causes the elephant’s foot effect. It can also cause the nozzle to hit and drag up the first layer when it moves on to the next layer. If you don’t have sufficient adhesion, improve your build surface - wash it, sand it, add glue, or whatever else.

Auto Z Calibration

At some point, someone probably got tired of this manual z offset trial and error. And thus, was created. It probes and automatically calculates the offset between your nozzle and bed so you don’t have to. It’s great, if you have the required hardware:

  1. Klicky probe, usually used on Voron printers but adapted to others. Other tactiles switches may work, not sure? Inductive won’t.
  2. A nozzle touchoff endstop (which is how the Voron 2.4 homes Z - the nozzle touches a probe).

These two things allow the plugin to measure the height of the nozzle, probe, and bed, and use that to calculate the offset.

Thermal Expansion, Part 2: Electric Boogaloo

Thought thermal expansion was a simple offset? Think again.

(This may or may not apply to your printer. Feel free to read but don’t feel compelled to actually use any of the plugins below unless you’re actually seeing issues).

Bed Warping

Keep in mind that a rigidly anchored bed, especially one with more than 3 fixture points, may warp/change shape during heatsoak. This is why i.e. the Voron 2.4 build guide tells you to only keep one screw tight, and the others loose.

Additionally, Mandala Rose Works offers a Kinematic Mounting Kit (targeted at the Voron 2.4). The idea of Newton-style kinematic mounting is that your bed is constrained in exactly 6 degrees of freedom using 3 control points (in this case, one fixed point, one linear mount, and one flat surface). This prevents the bed from warping during expansion since it isn’t over constrained.

Frame Expansion Compensation

Okay, one step deeper. Your frame actually expands during a print, up to a few hours after you first start heating your bed. It takes some time for heat from your bed to spread through the frame and for everything to equalize. In fact, if your first layer is long enough, the frame expansion will cause your z offset to drift during the first layer. There’s a Klipper plugin to compensate for this: I haven’t tried it out yet. Have fun.

Bimetallic Gantry Expansion

Okay, now we’re getting to ridiculous levels of compensation. Printers like the Voron have an aluminum frame with steel linear rails. The rails expand differently from the aluminum, causing the gantry to bow a little. This plugin compensates for that: Again, I haven’t tried it. Have fun.

Closing Thoughts

Well, that was a handful. Sorry for the wall of text - hopefully some of it is useful to you, and clarifies some confusion!