What Klipper macros can do

How to make a Klipper macro wait

Klipper has three kinds of wait. A temperature wait blocks until a heater or sensor gets there, a dwell blocks for a set time, and a delayed G-code runs later without blocking anything. Here is which to use, the exact syntax, and why a wait sometimes never ends.

Published · Last verified

A printer touchscreen showing the extruder at 215 °C and the chamber at 40 °C
Photo: Creative Tools from Halmstad, Sweden, CC BY 2.0

To make a Klipper macro wait for temperature, use M109 S<temp> for the nozzle and M190 S<temp> for the bed. Each sets the target and blocks until the heater settles. To wait on any sensor for a threshold, use TEMPERATURE_WAIT SENSOR=<name> MINIMUM=<temp>. For a fixed pause, use G4 P<milliseconds>.

How do you make a Klipper macro wait for a temperature?

Put M190 S{BED} or M109 S{EXTRUDER} in the macro. Klipper’s G-code list says each one “always waits for temperature to settle at requested value.” To wait for a threshold instead, set the target first and then add TEMPERATURE_WAIT SENSOR=extruder MINIMUM=<temp>. The next line runs only once the condition is met.

[gcode_macro HEAT_AND_WAIT]
description: Heat bed and nozzle, wait for both
gcode:
    {% set BED = params.BED|default(60)|float %}
    {% set EXTRUDER = params.EXTRUDER|default(200)|float %}
    M140 S{BED}                    ; start the bed, don't wait
    M104 S{EXTRUDER}               ; start the nozzle, don't wait
    M190 S{BED}                    ; now wait for the bed
    M109 S{EXTRUDER}               ; then wait for the nozzle

Both heaters start before the first wait, so they heat at the same time. The macro parameters guide explains the params lines.

What “settled” means for M109 and M190

Klipper’s source decides when the wait ends, and the rule depends on the heater’s control setting:

  • pid (proportional-integral-derivative control): the temperature must be within 1 °C of the target and changing by less than 0.1 °C per second. The check works in both directions, so M109 S150 on a nozzle at 240 °C waits for it to cool to 150.
  • watermark (on/off control): the wait ends once the temperature is no more than max_delta below the target (default 2 °C). It never waits for cooling.

A target of 0 turns the heater off and skips the wait.

Waiting for a threshold with TEMPERATURE_WAIT

TEMPERATURE_WAIT waits “until the given temperature sensor is at or above the supplied MINIMUM and/or at or below the supplied MAXIMUM.” It leaves every target unchanged. Give it at least one limit, or Klipper returns “missing MINIMUM or MAXIMUM.”

# Inside a macro that sets EXTRUDER as above:
# start once the nozzle is within 5 degrees, skipping the settle time
M104 S{EXTRUDER}
TEMPERATURE_WAIT SENSOR=extruder MINIMUM={EXTRUDER - 5}

# In an end macro: wait for the bed to cool before removing the part
M140 S0
TEMPERATURE_WAIT SENSOR=heater_bed MAXIMUM=40

SENSOR= takes the full config section name. Klipper’s status reference gives examples such as extruder, heater_bed, heater_generic my_custom_heater and temperature_sensor electronics_temp. Quote a name that contains a space: SENSOR="temperature_sensor chamber". Unquoted, Klipper rejects the line as malformed. For a chamber heat soak with M141 and M191 macros, see chamber heater control.

How do you add a delay to a Klipper macro?

Use G4 P<milliseconds>. G4 P5000 pauses for five seconds and G4 P60000 for one minute. Klipper reads only the P value, so G4 S5 copied from other firmware becomes a zero-length dwell. Commands after the dwell wait their turn, including ones typed in the console. For a delay that blocks nothing, use [delayed_gcode].

[gcode_macro OOZE_WAIT]
gcode:
    G4 P2000                       ; dwell 2 seconds
    M400                           ; let the dwell finish completely
    RESPOND MSG="Done waiting"     ; needs a [respond] section

G4 pauses the motion queue, and Klipper’s host stops reading ahead once it is about one second ahead of the printer. A host-side line straight after G4, such as RESPOND or M117, can therefore run up to a second early. M400 (“wait for current moves to finish”) closes that gap. Use it after any move when the next line must wait for the toolhead to stop. Klipper’s [delayed_gcode] example uses M400 this way, so its “Load Complete!” message appears only after the extrusion finishes.

A long heat soak works the same way: G4 P1800000 is 30 minutes.

Klipper macro delay without blocking

To run something later without holding up the printer, put it in a [delayed_gcode] section and start its timer with UPDATE_DELAYED_GCODE. The calling macro carries on straight away.

[delayed_gcode lights_off]
gcode:
    SET_PIN PIN=caselight VALUE=0      ; placeholder: your [output_pin] name

[gcode_macro PRINT_END]
gcode:
    TURN_OFF_HEATERS
    UPDATE_DELAYED_GCODE ID=lights_off DURATION=600   ; 10 minutes later

DURATION is in seconds. Klipper’s G-code reference says “a value of 0 will cancel a pending delayed gcode.” Calling UPDATE_DELAYED_GCODE again restarts the timer from now with the new duration. The section’s initial_duration option runs the G-code that many seconds after Klipper becomes ready. A delayed G-code that updates its own ID repeats, which is how you poll a value. The delayed G-code guide covers that pattern.

Why a macro still sees the old temperature after a wait

Klipper’s command templates page says macros “are first evaluated in entirety and only then are the resulting commands executed.” Every printer. value and {% if %} test is read before the first wait runs. A test placed after M190 still sees the cold bed.

Move the check into a second macro. A called macro “is evaluated when it is invoked”, which happens after the wait finishes.

[gcode_macro HEAT_THEN_CHECK]
gcode:
    M190 S{params.BED|default(60)|float}
    _REPORT_BED                 ; evaluated after M190 returns

[gcode_macro _REPORT_BED]
gcode:
    RESPOND MSG="Bed at {printer.heater_bed.temperature|round(1)} C"

The leading underscore hides the helper from the Mainsail and Fluidd macro panels. If/else in macros has more on conditions.

When a Klipper wait never ends

M109, M190 and TEMPERATURE_WAIT have no timeout. A target the heater cannot reach blocks the macro until you stop it. Check these first:

  • Impossible limit. A MAXIMUM below room temperature, or a MINIMUM above what the heater can reach.
  • Unsettled PID heater. M109 waits as long as the temperature swings more than 1 °C around the target. Re-run PID_CALIBRATE at that temperature.
  • Wrong sensor name. This does not hang. Klipper’s source treats an unknown SENSOR= name as an internal error and shuts down, so fix the name and run FIRMWARE_RESTART.

While a wait runs, Klipper prints the temperatures once a second and runs no other G-code. Klipper’s API documentation says a script sent during a running command “will be queued”, so console commands, CANCEL_PRINT included, wait behind it. The emergency stop button skips that queue. It behaves “similarly to the G-Code M112 command” and shuts Klipper down until a FIRMWARE_RESTART.

Sources

  1. Klipper documentation, G-Codes (accessed October 10, 2026)
  2. Klipper documentation, Command templates (accessed October 10, 2026)
  3. Klipper documentation, Configuration reference (accessed October 10, 2026)
  4. Klipper documentation, Status reference (accessed October 10, 2026)
  5. Klipper source, klippy/extras/heaters.py (accessed October 10, 2026)
  6. Klipper source, klippy/toolhead.py (accessed October 10, 2026)
  7. Klipper source, klippy/extras/delayed_gcode.py (accessed October 10, 2026)
  8. Klipper source, klippy/gcode.py (accessed October 10, 2026)
  9. Klipper documentation, API server (accessed October 10, 2026)
  10. Mainsail documentation, Hide macros, outputs or fans (accessed October 10, 2026)
  11. Fluidd documentation, Hide macros, output pins and fans (accessed October 10, 2026)