Fairly long winded, but hopefully makes sense;

I understand that G-code is executed line-by-line, and in the main printing phase each instruction is effectively go to location XY (assuming staying within the layer) at a set speed with a set extrusion amount (not rate, as far as I can tell).

Imagine you were printing a single road width, say 10 mm long. If the single instruction says to move that 10 mm at a set speed and extrude 10mm of material (which is, I guess, not 10mm of filament), with infinite acceleration and deceleration of the nozzle and extruder gears, then a linear amount of material would be extruded per unit length along the 10 mm. However, given that there is some acceleration and deceleration, that extrusion must be non-linear.

My questions are as follows; - Is it possible to counteract this within a single line of Gcode by having a variable extrusion rate? - Can the machine do so regardless of the instructions given to it? - Is this effect embraced somehow? - Does the need to accelerate both the nozzle position and filament effectively cancel out? -Would/could you aim instead to split a single straight line of filament into multiple lines of G-code, some extruding (say in the middle), and some not (say at each end)?

  • $\begingroup$ Welcome to 3dPrinting.SE! $\endgroup$ Feb 12, 2019 at 14:13
  • $\begingroup$ The extrusion axis E follows the same acceleration profile as the X and Y axis in most firmware (Marlin). It's not like the E axis moves linearly while the others are accelerating. Those swells at the corners of your prints are due to physical lag in your extrusion system. $\endgroup$ Aug 8, 2019 at 20:21

5 Answers 5


My understanding is that the printer firmware will define the maximum acceleration and speeds for each axis (X, Y, Z, and E). When executing a line of g-code that involves more than one axis, the acceleration for each will be limited such that they all begin and end, including acceleration together.

During the start and end of a line, when the print nozzle is moving more slowly, the extruder will also move slowly. In the middle of the line, the extruder will move faster. The amount of material extruded per distance will be constant over the length of the line.

Another way to look at it - suppose you could accelerate quickly on X with a high top speed, but slowly on Y. A move only in the X direction could happen quickly. A move only in the Y direction would be slower. If you want to move at a 45-degree angle, you will need to slow down X so that it doesn't get ahead of Y.

If you did want to intentionally vary the amount of extrusion per distance during a line, you would need to break it into multiple segments with individual lines of g-code.


Let's see...

Is it possible to counteract this within a single line of Gcode by having a variable extrusion rate?

No, it cannot. G Code executes line by line. If you have a line : G1 X10 F100 F200 F300 some parseres will accept the first (F100), some will only accept the last (F300)

Can the machine do so regardless of the instructions given to it?

If you program a custom G code parser to do so, you still couldn't because there is no time scale to which you would want the effect to apply. To do this you would have to introduce a new letter to your parser (let's call it K), which you could use to instruct the machine to scale the extrusion accordingly (e.g. G1 X10 F100 K0.24). The machine would then know to scale the F parameter by 0.24 over the course of the movement.

Is this effect embraced somehow?

Uhm... no?

Does the need to accelerate both the nozzle position and filament effectively cancel out?

Cancel out how? The filament stepper as well as the gantry steppers are step synchronized so that they operate at the correct feedrate, at all times.

Would/could you aim instead to split a single straight line of filament into multiple lines of G-code, some extruding (say in the middle), and some not (say at each end)?

Absolutely not. Each line of gcode has to be completed by the machine before any other line can be considered. You can't have one motion governed by multiple lines of g-code, because there will be not way to control the timing of the execution of the lines.

  • 1
    $\begingroup$ Your formatting makes more sense Trish. thanks much. $\endgroup$
    – user77232
    Feb 13, 2019 at 1:22
  • $\begingroup$ Of course you can split one extrusion line! Just introduce several visiting positions in the middle! $\endgroup$ Aug 8, 2019 at 20:24

While Trish directly answers the G-Code part of your question, my answer offers an alternative if you use Marlin. RepRap has a similar feature called pressure advance, but this answer is focusing on Marlin's feature.

According to Marlin:

Under default conditions, extruder axis movement is treated in the same way as the XYZ linear axes. The extruder motor moves in linear proportion to all the other motors, maintaining exactly the same acceleration profile and start/stop points. But an extruder is not a linear system, so this approach leads, most obviously, to extra material being extruded at the end of each linear movement.

In short, corners result in being rounded instead of sharp due to the constant extrusion when laying down a line. One can mitigate this by changing the flow, though this might affect straight lines in other parts of the print, namely under extruding them. Marlin's answer to this is linear advance.

With linear advance, the extrusion rate changes as the print head speed changes. When the print head moves faster, more plastic has to be pushed out to lay a consistent line and as soon as the head slows down, the extrusion rate slows down to compensate. The print should then have a consistent line. This is all done using a new factor called k. From Marlin:

K is now a meaningful value with the unit [mm of filament compression needed per 1mm/s extrusion speed] or [mm/mm/s].

One can determine the k value for their printer using Marlin's k calibration tool which prints out multiple straight lines and instructs the printer to print the start of each line slowly, then print fast, and end the line slow again. Each line has a different k value and the user chooses the k value from the line that is most consistent.

Some caveats

Bowden style extruders require larger k values which, even then, linear advancing may not work. This is due to the bowden tube itself and the material between the extruder motor and the hot end. This is along the same issue as trying to print flexible plastics with a bowden extruder. While linear advance is better suited for direct drives, it's not impossible to use it on a bowden.

Setting up linear advance requires an extra set of tuning. While this primarily means tuning the k value, print speeds may need adjusting (potentially allowing for faster speeds even).

Older linear advance version, at least on Marlin, had the extruder motor a lot more active. Some people report that printing is noticeably noisier. This feature might also add an extra load to the CPU. These issues should not be a problem anymore, as of v1.5, but YMMV.

One needs to change the firmware/G-Code so that each print can use linear advance. If the printer is only using one material the firmware can be changed. However, if multiple materials will be used within the printer's lifetime, the G-Code will have to include the following command at the end of the start script ( more found here). This k value will be different for each material. An example of the command is as follows:

M900 K75 ; Set k-factor for PLA

The link also recommends setting the k factor value to 0 when turning the feature on in the firmware. This essentially disables the hard-coded value in the firmware.

Finally, slicer settings like pressure advance, Coast at end, extra restart length after retract should be disabled when using linear advance as they do a similar operation. On the flip side, these settings may work for your printer so you may not need to even use linear advance.

  • $\begingroup$ I thought the "linear advance" is a firmware solution, not a hardware dependable one (referring to your answer: "Some printers are capable of"); Could you elaborate please? $\endgroup$
    – 0scar
    Feb 12, 2019 at 21:05
  • $\begingroup$ @0scar I guess I was thinking "some printers [due to their firmware]" which is ambiguous without that clarification. I shall replace printers with firmware since that is more accurate. Thanks! $\endgroup$ Feb 12, 2019 at 21:38
  • $\begingroup$ @0scar, you also got me thinking that linear advance may work only on Marlin firmware so I did some research and found that seems to be the case. So thanks for that as well. :) $\endgroup$ Feb 12, 2019 at 21:50

Not on one line, but...

On Hyrel systems, you can, manually, split one long move into several smaller moves, each with a different extrusion rate.

For example, let's start at X100 Y100, and move to X100 Y200. On a Hyrel, this would look like this (with an inherited F rate if not specified):

  G1 X100 Y200 E1

We could change this by specifying our Feed Rate Multiplier:

  M221 S0.9 ; set feed rate multiplier to 90%
  G1 X100 Y110 E1 ; print 10mm
  M221 S0.95 ; set feed rate multiplier to 95%
  G1 X100 Y120 E1 ; print 10mm
  M221 S1 ; set feed rate multiplier to 100%
  G1 X100 Y130 E1 ; print 10mm
  M221 S1.05 ; set feed rate multiplier to 105% 

We can also vary all of the parameters between moves, including print speed, acceleration, deceleration, cooling, and UV curing.

And we do use "linear advance" as well, so extrusion ramps up with travel speed.

Note: I work for Hyrel.

  • $\begingroup$ That is, technically, not one line of code though, as each part is one line of code. $\endgroup$
    – Trish
    Feb 12, 2019 at 22:35
  • $\begingroup$ @Trish True enough. I was thinking "one line" (printed). $\endgroup$
    – Davo
    Feb 12, 2019 at 22:36


G-code is written line separated, starting with one command what to do, then who does it with what factors. For example G1 X10 F100 E10 says this:

  • G1 Move...
  • X10 The X axis by 10
  • F100 Use the factor to 100 units
  • E10 Also: the Extruder by 10

To my knowledge any repeated or invalid expression is simply ignored (or overwritten). So G1 X10 F100 E10 F200 gets parsed as either G1 X10 F100 E10 or G1 X10 E10 F200, depending on how your firmware interpreter is set up.


You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .