What Klipper macros can do

Klipper adaptive bed meshing explained

Adaptive meshing probes only the part of the bed the current print uses. This page covers the config, the start macro line, the slicer setting, how it relates to KAMP, and what to check when Klipper still meshes the whole bed.

Published · Last verified

A Voron toolhead seen face-on, close above the build plate
Photo: disinterpreter, CC BY-SA 2.0

Adaptive bed meshing makes Klipper probe only the rectangle covered by the objects in the current print, not the whole bed. Add an empty [exclude_object] section to printer.cfg, slice with object labels, and run BED_MESH_CALIBRATE ADAPTIVE=1 in your start macro. Klipper has done this natively since January 2024 (release 0.13.0), without the KAMP (Klipper Adaptive Meshing and Purging) add-on.

What is adaptive bed meshing in Klipper?

Adaptive bed meshing is a mode of Klipper’s bed_mesh module that probes only the area used by the objects in the current file, plus an optional margin. It reads the object outlines from the [exclude_object] module and shrinks the mesh to the rectangle around them. The probe count shrinks in proportion, so small parts mesh quickly.

In Klipper’s own example, objects covering half the width and depth of a 100 by 100 mm mesh turn a probe_count of 7,7 into 4,4. The source code (bed_mesh.py) adds three rules:

  • Minimum points. At least 3 per axis, or 4 when the other axis needs more than 6.
  • Clamped. The adapted area, margin included, stays inside mesh_min and mesh_max.
  • Not saved. The mesh is named adaptive-… and goes into no profile. Klipper says adapted meshes “should not be re-used”.

Klipper recommends it for beds whose full mesh varies by one layer height or less. Otherwise, moves outside the probed area risk “undesirable results”.

How to set up adaptive bed meshing in Klipper

  1. Update Klipper. Builds from before January 2024 have no adaptive mode.
  2. Enable object tracking. Add [exclude_object] to printer.cfg. It takes no options.
  3. Label objects in the slicer. The file needs EXCLUDE_OBJECT_DEFINE lines.
  4. Set the full-bed density. Adaptive mode scales probe_count down, so a 3 by 3 grid stays 3 by 3.
  5. Call it at print start. Run BED_MESH_CALIBRATE ADAPTIVE=1 after heating the bed and homing.
  6. Test with a real print. Check the console for the adapted-mesh lines.
[exclude_object]

[bed_mesh]
mesh_min: 35, 6        # placeholder: nearest point your probe can reach
mesh_max: 240, 198     # placeholder: farthest point your probe can reach
probe_count: 7, 7      # density for a full-bed mesh; adaptive scales it down
adaptive_margin: 5     # mm added around the objects; default 0

Raise adaptive_margin if a skirt, brim or purge line lands outside the object outlines. ADAPTIVE_MARGIN=10 on the command overrides it once.

Klipper adaptive bed mesh start G-code

Mesh after heating the bed and homing, and before heating the nozzle:

[gcode_macro PRINT_START]
gcode:
    {% set BED = params.BED|default(60)|int %}
    {% set EXTRUDER = params.EXTRUDER|default(210)|int %}
    M190 S{BED}                     ; heat the bed and wait
    G28                             ; home at temperature
    BED_MESH_CALIBRATE ADAPTIVE=1   ; probe only where the objects sit
    M109 S{EXTRUDER}                ; heat the nozzle and wait

Without a macro, the line goes in the slicer’s start G-code after G28. Do not also run BED_MESH_PROFILE LOAD=default, which Klipper warns “may produce unexpected results, especially with adaptive meshing.” The PRINT_START macro guide covers passing temperatures from the slicer.

Adaptive bed mesh with OrcaSlicer

In OrcaSlicer, set Printer settings > G-code flavor to Klipper and tick Print settings > Others > G-code output > Exclude objects (off in Orca’s base defaults). Orca then writes an EXCLUDE_OBJECT_DEFINE line with an outline for each object at the top of the file, ahead of your start G-code.

  • PrusaSlicer 2.7.0 or newer: set G-code flavor to Klipper and Print Settings > Output options > Label objects to Firmware-specific (Mainsail docs).
  • Other slicers: add enable_object_processing: True under [file_manager] in moonraker.conf. Moonraker then adds the definitions on upload, though it warns this is file I/O intensive and not recommended on a Pi Zero.

Orca’s separate adaptive bed mesh settings fill the bounds into BED_MESH_CALIBRATE through placeholders such as {adaptive_bed_mesh_min[0]}. Use that or ADAPTIVE=1, not both.

Why is Klipper adaptive bed mesh not working?

Klipper adaptive bed mesh usually fails because Klipper sees no objects when the mesh runs, so it probes the full bed. The causes are a missing [exclude_object] section, a G-code file without EXCLUDE_OBJECT_DEFINE lines, definitions placed after the mesh call, or a macro that overrides BED_MESH_CALIBRATE and drops ADAPTIVE=1.

A working run prints Found N objects, Adapted mesh bounds and Adapted probe count. Without those lines, check:

  • Exclude objects not enabled. Using full mesh... The config lacks [exclude_object].
  • No message, full mesh. The file defines no objects. Search the G-code for EXCLUDE_OBJECT_DEFINE. The same command with no parameters lists the objects Klipper knows.
  • Definitions below PRINT_START. Klipper clears the object list when a print starts, so definitions must precede the mesh call. KAMP notes Moonraker’s processor can place them late; an M117 line before PRINT_START usually restores the order.
  • An override. A macro that renames BED_MESH_CALIBRATE passes only the arguments it chooses. KAMP’s meshing file never passes ADAPTIVE, and KAMP warns that Klicky and Euclid probe macros define their own. Search your config for rename_existing.
  • Old firmware. Any build based on Klipper from before January 2024, vendor forks included, has no adaptive code.

Console tests between prints mislead. The object list survives “until another action resets it”, so the mesh follows the last print’s objects.

KAMP and the built-in adaptive mesh

KAMP is a macro set that meshed adaptively before Klipper could. Its Adaptive_Meshing.cfg renames BED_MESH_CALIBRATE and calls the original with bounds taken from the same object outlines.

Use one. On current Klipper, leave [include ./KAMP/Adaptive_Meshing.cfg] commented out in KAMP_Settings.cfg and use ADAPTIVE=1. KAMP’s version keeps two extras: fuzz_amount randomizes the bounds to spread nozzle-probe wear (KAMP recommends 3 mm at most), and probe_dock_enable handles dockable probes.

A KAMP start print macro

To pair KAMP’s purge and park with Klipper’s mesh, include ./KAMP/Line_Purge.cfg and ./KAMP/Smart_Park.cfg in KAMP_Settings.cfg, then add [include KAMP_Settings.cfg] to printer.cfg:

[gcode_macro PRINT_START]
gcode:
    {% set BED = params.BED|default(60)|int %}
    {% set EXTRUDER = params.EXTRUDER|default(210)|int %}
    M190 S{BED}                     ; heat the bed and wait
    G28                             ; home at temperature
    BED_MESH_CALIBRATE ADAPTIVE=1   ; Klipper's adaptive mesh
    SMART_PARK                      ; KAMP: park near the print area
    M109 S{EXTRUDER}                ; heat the nozzle and wait
    LINE_PURGE                      ; KAMP: purge beside the print

KAMP puts SMART_PARK before the final heat and the purge last. LINE_PURGE needs max_extrude_cross_section: 5 under [extruder], or KAMP skips the purge with a warning. To purge without KAMP, see the purge line macro.

Sources

  1. Klipper documentation, Bed mesh (accessed October 10, 2026)
  2. Klipper documentation, Exclude objects (accessed October 10, 2026)
  3. Klipper documentation, Configuration reference (accessed October 10, 2026)
  4. Klipper documentation, G-Codes (accessed October 10, 2026)
  5. Klipper documentation, Releases (accessed October 10, 2026)
  6. Klipper commit 5e3daa6, bed_mesh: Implement adaptive bed mesh (#6461) (accessed October 10, 2026)
  7. Klipper source, klippy/extras/bed_mesh.py (accessed October 10, 2026)
  8. Moonraker documentation, Configuration (accessed October 10, 2026)
  9. Mainsail documentation, OrcaSlicer (accessed October 10, 2026)
  10. Mainsail documentation, PrusaSlicer (accessed October 10, 2026)
  11. OrcaSlicer source, src/libslic3r/PrintConfig.cpp (accessed October 10, 2026)
  12. OrcaSlicer wiki, Adaptive bed mesh (accessed October 10, 2026)
  13. Klipper Adaptive Meshing and Purging (KAMP) on GitHub (accessed October 10, 2026)
  14. KAMP source, Configuration/Adaptive_Meshing.cfg (accessed October 10, 2026)