Making Your 3D Printer Pause or Wait with G-Code in Marlin

Whether it’s to troubleshoot a print problem without having to abort the print and start over or to change the filament spool mid-print, there is no denying that temporarily pausing the 3D printing process is a crucial tool that can become necessary at any given moment.

In this guide, we will walk you through the various G-Code commands you can utilize in Marlin firmware to pause a print indefinitely until you manually resume it, to resume a print you have paused indefinitely, and to get your 3D printer to wait for a certain amount of time and automatically resume the print afterward, without requiring you to unpause.

Making Your 3D Printer Pause with G-Code Commands in Marlin Firmware

There are a fair few different G-code commands in Marlin firmware that you can use to pause a print, and each of these commands works in slightly different ways and has diverse requirements.

M0/M1 (Unconditional Stop)

Using the M0 (or M1, which is an alias) G-code command is the most standard way of initiating a pause in Marlin firmware, which causes the 3D printer to stop printing once it completes its last movement and stay that way until you resume the print yet again.

For your 3D printer to actually pause the print once you issue the M0 G-code command, one essential pre-requisite is for either an LCD controller to be attached to the 3D printer or EMERGENCY_PARSER to be defined in Marlin firmware Configuration_adv.h file, as one of these two factors is required for you to be able to unpause the print reliably later on.

marlin emergency parser explanation


On the other hand, in a scenario where neither EMERGENCY_PARSER is defined; nor your 3D printer has an LCD controller, Marlin will ignore the M0 G-code command, and a pause won’t take place as a result.

Given that you know the exact points where you would like to pause a print, the most reliable way of using the M0 G-code command is to directly insert it into the G-code file that your slicer has produced, as this will ensure that your 3D printer stops printing as soon as it reaches that particular G-code line.

example of using m0 in a gcode file


On the other hand, if you need to make an unexpected pause, your only option would be to send the M0 command directly through a G-code terminal instead, in which case you may experience a short delay before the pause actually takes place due to more G-code commands landing in the queue as the print progresses until the M0 command you have sent is received.

octoprint using m0 in gcode terminal


Additionally, if you use OctoPrint, you may have noticed that the M0 command isn’t going through to your 3D printer, even with the pre-requisite fulfilled, with OctoPrint throwing you a message about the command being blocked.

octoprint m0 being blocked example


In essence, the reason behind this behavior is OctoPrint not sending the M0 G-code command to your 3D printer and instead using a different method to pause the print in a way that would allow it to be resumed through the OctoPrint interface without requiring you to interact with the LCD panel or manually send a G-code command.

So, under normal circumstances, you should observe that OctoPrint pauses the print when you send the M0 G-code command, even when it says that the command is blocked, with the Resume button available on the OctoPrint interface to resume the print whenever necessary.

octoprint resume button active example


On the other hand, if you remove M0 from the list of blocked commands in the Protocol Fine Tuning section (wrench icon on the top-right -> Serial Connection -> Firmware & Protocol), you will notice that the warning message doesn’t pop up anymore when you issue the command, as OctoPrint forwards the M0 G-code command to your 3D printer as usual.

octoprint blocked commands


In this case, you will also notice that the M0 pause behavior changes, with the OctoPrint Resume button becoming unusable and the pause dialog coming up on the LCD screen of your 3D printer, which is the intended behavior of the M0 G-code command.

octoprint resume button inactive example


When it comes to deciding on whether to remove the M0 G-code command from the OctoPrint blocked command list or not, our recommendation would be to remove it only if OctoPrint’s way of pausing the print does not work or doesn’t suit your purposes, as the ability to unpause your print by clicking a single button on the interface is otherwise quite convenient.

M25 (Pause SD Print)

Under normal circumstances, the purpose of the M25 G-code command is to pause a print that you have started through the SD card, which essentially makes its behavior no different than the M0 G-code command if you’re using an SD card to print.

That being said, unlike M0, which you can use either by adding into a G-code file or sending through a G-code terminal, you’re only supposed to use the M25 G-code command from the terminal due to it being a non-blocking command that is not meant to be used from within a G-code file.

marlin m25 standard behavior


As you may predict, in cases where you aren’t printing from an SD card, the M25 G-code command is designed to do nothing at all, as different ways, such as using the M0 command, are readily available to pause non-SD prints in such a scenario.

With that said, this isn’t all there is to the M25 G-code command, as its behavior drastically changes when a particular variable, known as PARK_HEAD_ON_PAUSE, is defined through the Configuration_adv.h file.

marlin park head on pause variable


With PARK_HEAD_ON_PAUSE defined (which in turn requires ADVANCED_PAUSE_FEATURE to be defined), the M25 G-code command internally calls the M125 G-code command (we will be explaining this command in the next section) instead, and interestingly, it does this without performing a check for whether the current print job is from an SD card or not.

marlin m25 behavior with park head on pause enabled


So, if the Marlin fork you’re using has PARK_HEAD_ON_PAUSE defined in its configuration, you’ll find that the M25 G-code command pauses the print regardless of whether you’re printing with an SD card or not, but in a different way this time, which we will cover in the M125 section below.

M125 (Park Head)

We can consider using the M125 G-code command to be the preferred way of initiating a pause whenever possible, as it parks the printhead away from the print area (exact position determined by the X, Y, and Z parameters or NOZZLE_PARK_POINT) and brings it back to its original location once resumed.

This way, it becomes possible to freely work around the print area without having to worry about disrupting the position of the printhead in the process, as such a disruption can easily lead to print failure and defeat the purpose of pausing the print to fix things in the first place.

marlin nozzle park point variable


The pre-requisites for the M125 G-code command to work as intended are for the ADVANCED_PAUSE_FEATURE and PARK_HEAD_ON_PAUSE variables to be defined in Marlin configuration, which can be found in the Configuration_adv.h file.

As with any other command that has prerequisites, if you attempt to use this command without the variables defined, your 3D printer will end up ignoring it and move on to the following command in the queue without pausing the print.

Similar to M0, you’ll get the most reliable results out of M125 when you directly add it into the G-code file, as this will allow you to have complete control over the exact points of the print where you would like the pause to occur.

example of using m125 in a gcode file


That being said, sending M125 to your 3D printer through a G-code terminal will also work fine if you need to pause in a pinch, but the pause can be potentially delayed due to the same reasons we have explained in the M0 section.

example of using m125 in octoprint


Finally, since M125 triggers an advanced pause, you’ll find that it behaves slightly differently than an M0 pause in two ways when it comes to unpausing, which can also be something to keep in consideration when choosing this option.

First, in the case of nozzle temperature dropping below its target temperature during the pause (heater timeout due to idle time), the nozzle will start heating back up to reach the target temperature as soon as you break out of the pause, and the print will only resume once the nozzle is heated.

advanced pause heating


Second, if your 3D printer has an LCD display; or the firmware you’re using has HOST_PROMPT_SUPPORT and EMERGENCY_PARSER defined, the firmware will show you an additional prompt where you will need to choose between purging filament or continuing with the unpause.

advanced pause purge or continue dialog


M600 (Filament Change)

The primary purpose of the M600 G-code command is to initiate a filament change, which, alongside a pause, includes actions such as parking the printhead away from the print, ejecting the filament, and loading & priming the filament once you have confirmed that you have inserted the new spool.

For the M600 command to be active and usable, it’s necessary to define the ADVANCED_PAUSE_FEATURE variable in Configuration_adv.h, which is the only pre-requisite in this case.

Similar to how it always is, in a scenario where you attempt to use the M600 G-code command without ADVANCED_PAUSE_FEATURE enabled, your 3D printer will ignore the command and the print won’t be paused.

As you may predict, the best way to use the M600 command is to insert it directly into the G-code file your slicer has produced, so that you can choose the exact layer where you would like to initiate the filament change.

example of using m600 in a gcode file


That being said, even though the point where the pause happens won’t be as reliable, as we have mentioned earlier in the M0 and M125 sections, it’s entirely possible to use M600 through a G-code terminal to initiate a filament change in a pinch.

Finally, since M600 also triggers an advanced pause, similar to M125, you will again have the option between purging more filament and continuing with the print if your 3D printer has an LCD controller or the firmware has HOST_PROMPT_SUPPORT and EMERGENCY_PARSER enabled.

Making Your 3D Printer Wait (Timed Pause) with G-Code Commands in Marlin Firmware

While there aren’t as many options as a standard pause in this case, there is still more than one single G-code to initiate a wait (timed pause) in Marlin firmware as well with both commands once again having slight differences compared to one another.

M0/M1 (Unconditional Stop)

While the default behavior of the M0 G-code command is to pause the print indefinitely until you manually resume it, as we have mentioned, it also supports the usage of some extra parameters that turn it into a timed pause.

The S parameter, along with the value of your choice (M0 S10 for a 10-second pause, for instance), in terms of seconds, causes the M0 G-code command to pause the print for the set amount of time and resume it afterward.

example of waiting in octoprint with m0 s10


Similarly, the P parameter, once again along with the value of your choice (M0 P10000 for a 10-second pause, for instance), but this time in terms of milliseconds, also gets the M0 G-code command to initiate a timed pause.

Additionally, it’s worth mentioning that you will still have the option to break out of the pause manually in this case (whether with the LCD controller or with M108), as adding a timer to the pause doesn’t change the behavior of the M0 command in any other way.

G4 (Dwell)

Another G-code command you can use to get your printer to wait for a specified amount of time is G4.

Similar to the M0 G-code, you can specify the amount of time you would like your printer to pause by either passing the S parameter (for seconds) or the P parameter (for milliseconds) along with the value of your choice (G4 S10 / G4 P1000 for a 10-second pause, for instance).

waiting with g4 s10


On the other hand, unlike M0, you can’t manually break out of a pause you have initiated with G4, whether with the LCD controller or the M108 G-code command, as you’ll notice that your printer doesn’t technically go into a “paused” state in this case, but simply stops running the G-code commands in the queue.

While M0 is usually the primary choice for initiating a timed pause due to the flexibility that comes with it, the fact that G4 doesn’t require the presence of an LCD controller or the EMERGENCY_PARSER variable to be defined can make it your only option in some cases.

Making Your 3D Printer Resume from a Pause with G-Code Commands in Marlin Firmware

Finally, when it comes to resuming from a pause, you are presented with more than a single option yet again, but this time, the command you need to use essentially depends on the one you have used to initiate the pause earlier.

M108 (Break and Continue)

Using the M108 G-code command is the primary way of breaking your 3D printer out of a pause and resuming the print, regardless of whether it’s a regular M0 pause or an advanced pause triggered by M125 or M600, as it practically does the same thing as clicking the LCD button in any of these cases.

That being said, the processes of unpausing from an advanced pause and unpausing from an M0 pause are slightly different due to how the advanced pause feature works.

Things are pretty straightforward in the case of unpausing from a standard M0 pause, as you will notice that the print resumes as soon as you send M108 from the terminal, with no additional steps required.

breaking out of m0 pause with m108


On the other hand, when unpausing from an advanced pause, sending the M108 command won’t be enough in itself since the firmware will ask you whether you would like to purge more filament or continue with the unpause once you send M108 (or click the LCD controller button), which you will need to answer.

octoprint advanced pause dialog


Please note that the above only applies if M600_PURGE_MORE_RESUMABLE is true, which requires either an LCD controller to be present or for both HOST_PROMPT_SUPPORT and EMERGENCY_PARSER to be defined.

marlin advanced pause purgemore menu


While the standard way of answering this prompt involves the usage of the LCD screen, different ways, such as utilizing the dialog that pops up in OctoPrint or using the M876 G-code command (both require HOST_PROMPT_SUPPORT to be defined), will also allow you to achieve the same effect.

marlin host prompt support explanation


In the case of using the M876 G-code command to answer the prompt, you will need to pass the S parameter along with the index of the option you would like to choose, with the index of the leftmost option being 0.

So, if we consider the example in the above image, where the Purge option is on the left; and the Continue option is on the right, we would need to send the command M876 S1 to choose the Continue option (and S0 would be the Purge option) after sending M108, which would break the 3D printer out of the pause and resume the print.

example of using m876 s1 in octoprint


Please note that EMERGENCY_PARSER needs to be defined for both the M108 and M876 commands to work reliably, as a full queue, which cannot move forward due to the 3D printer being in a pause state, could otherwise prevent them from being processed and cause the printer to become stuck in a pause that can only be resolved through the LCD controller.

M24 (Start or Resume SD Print)

The M24 G-code command’s purpose is to either start or resume an SD card print, meaning that it’s the command you will need to use to resume a print that you have paused with the M25 G-code command, as M108 won’t work in this particular case.

marlin m24 gcode standard behavior


Additionally, the M24 G-code command is also supposed to break out of an advanced pause if PARK_HEAD_ON_PAUSE is defined, according to the Marlin source code, as the change in the behavior of M25 as a result of this variable being active also naturally affects the behavior of M24 due to it being M25‘s counterpart.

marlin m24 behavior with park head on pause


That being said, in our tests, we couldn’t get the M24 G-code command to break us out of an advanced pause (PARK_HEAD_ON_PAUSE active), regardless of whether we triggered it with M25, M125, or M600 and whether we printed with an SD card or with OctoPrint.

On the other hand, when we used the M108 G-code command, followed by M876 S1, as we explained in the previous section, we managed to get out of the advanced pause as usual, which is something to keep in mind if you’re also having issues with getting M24 to work with an advanced pause.

Conclusion

Now that you know the various G-code commands in Marlin firmware that you can use to pause your prints, getting your 3D printer to pause reliably, whenever it may be necessary, should be a straightforward task that won’t give you any trouble.

While the way the Marlin fork you’re using, in particular, can change the behavior of some of these commands, as we have mentioned in their respective sections, some trial and error or a quick glance over the Configuration.h and Configuration_adv.h files, if the source code is available, should allow you to put the pieces together pretty quickly.