Why does a 3D printer go wrong exactly at the corners?

The head slows into a turn and the melt does not: pressure in the nozzle falls more slowly than the speed changes. A small bead lands on the outside of the corner, and the wall a few millimetres later comes out thin. Klipper and Marlin both correct it with a term proportional to velocity, not to distance.

The tip of a nozzle with melt coming out of it. How much leaves at this instant is decided by the pressure inside — and that pressure changes more slowly than the speed of the head.
The tip of a nozzle with melt coming out of it. How much leaves at this instant is decided by the pressure inside — and that pressure changes more slowly than the speed of the head.Photo: David Elliott / Wikimedia Commons, licence CC BY 2.0 (creativecommons.org/licenses/by/2.0), downscaled.

Print a hollow square on a 3D printer at speed and look at one corner under a side light. On the outside of the turn sits a small raised bead of plastic, as though the nozzle had paused there. Follow the wall three or four millimetres past the corner and the line goes thin — narrower than the rest of the perimeter, sometimes with a visible gap against the layer below. The top solid surface shows the same thing as roughness wherever the direction changes.

The obvious reading is that too much plastic is coming out, so the fix is to drop the extrusion multiplier or add retraction. Marlin's documentation heads that off in one sentence: «Tuning flow and retraction can help, but this may lead to under-extrusion when starting new lines.»

But the second half of the symptom contradicts the whole idea of over-extrusion. A machine over-extruding everywhere would not also starve the wall four millimetres later, and over the layer as a whole the amount of plastic that leaves the nozzle is right.

Why the melt lags the command

The firmware commands the extruder in millimetres of filament and assumes those millimetres arrive at the plate on the same schedule as the head moves. Marlin's page states the default behaviour before it states the problem: «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.»

Klipper's kinematics document names the two physical laws that break the assumption: «Pressure increases when filament is pushed into the extruder (as in Hooke's law) and the pressure necessary to extrude is dominated by the flow rate through the nozzle orifice (as in Poiseuille's law).»

The free length of filament between the drive gear and the melt zone compresses like a spring, and the orifice lets melt out at a rate set by how hard that spring is currently pressing. Marlin's developer notes drop the simile: the length is a spring, K the spring constant.

Compression, not volume, is what the drive gear actually sets. Marlin: «The force required to push the filament through the nozzle aperture depends, in part, on the speed at which the material is being pushed into the nozzle. If the material is pushed faster (=printing fast), the filament needs to be compressed more before the pressure inside the nozzle is high enough to start extruding the material.» Every printing speed therefore has its own resting compression, and changing speed means changing that store first — by turning the extruder motor an amount the sliced g-code never contains.

A calibration line in Marlin's documentation is walked through six phases, two of which are the two halves of the defect. At the start of the fast section: «The pressure build up in the nozzle (= amount of extruded material) is lagging behind the acceleration of the print-head. This results in too little material and a starved line.» At the start of the deceleration: «The pressure decrease in the nozzle is lagging behind the deceleration of the print-head. This results in too much material being extruded». One more phase matters as much as either, because there the head has already finished slowing down: «Still the pressure in the nozzle is not in sync with the intended extrusion amount and the line is suffering from over-extrusion.»

The correction is a velocity term, not a distance term

Both firmwares fix this the same way. Marlin's assumption is written in the comment above the feature in Configuration_adv.h: advance = k * (delta velocity). Klipper writes its version as an offset applied to the commanded extruder position: pa_position = nominal_position + pressure_advance_coefficient * nominal_velocity.

Neither term contains distance.

The extra filament depends on how fast the extruder is turning at that instant, so along a straight wall at constant speed the offset is constant and does nothing you can see, while at a corner — the largest velocity change anywhere in the layer — it does everything. Klipper states the sign on each side: «the pressure advance system causes additional filament to be pushed into the extruder during acceleration. The higher the desired filament flow rate, the more filament must be pushed in during acceleration to account for pressure. During head deceleration the extra filament is retracted (the extruder will have a negative velocity).»

The same factor of twenty in both firmwares

Marlin and Klipper measure the correction with different coefficients, so their numbers do not carry over from one to the other. What to look at is not the ends of each range but the ratio between them.

Marlin, LIN_ADVANCE v1.5Klipper, pressure advance
Unit of the coefficient«mm of filament compression needed per 1mm/s extrusion speed»its own convention, no unit named
Working range«around 0.1-2.0»0.050 to 1.000
End to end20×20×

The spans match: 2.0 ÷ 0.1 = 20, and 1.000 ÷ 0.050 = 20 as well. Two documents were written independently, and that factor of twenty in both is not scatter in anyone's measurements.

What varies twentyfold is the length of filament that gets to compress.

The tuning tower in Klipper prices that length directly. On a direct drive extruder the procedure steps the coefficient by FACTOR=.005 per millimetre of tower height; on a long bowden it steps by FACTOR=.020 — four times the range over the same tower, because that is where the answer is expected to sit. Marlin says the same thing in words: «Bowden systems need a pressure advance feature the most as they usually have the most problems with speed changes.»

A row of identical desktop 3D printers on a long bench, a white tube running from the spool at the top of each to its print head
Printers on a bowden drive: the white tube from spool to head is exactly the free length of filament that gets to compress. It is why machines like these need the largest correction. Photo: Smuconlaw / wikimedia, licence CC BY-SA 4.0 (https://creativecommons.org/licenses/by-sa/4.0/), unmodified.

Overcorrection has its own signature, and it is not a worse bead. Marlin: «A too high K-Factor essentially reverses the above picture. The extruded amount will overshoot at the start of an acceleration and starve in the deceleration phase.» Klipper describes the same failure on its tuning tower, where «layers above the ideal setting can lead to rounded corners and poor extrusion leading up to the corner». A corner that has gone soft and rounded is not asking for more correction.

How to read your own number off the tower

On Klipper the calibration starts with two commands. The first exists to make the defect visible — SET_VELOCITY_LIMIT SQUARE_CORNER_VELOCITY=1 ACCEL=500, and the documentation says why: «This command makes the nozzle travel slower through corners to emphasize the effects of extruder pressure.» Then TUNING_TOWER COMMAND=SET_PRESSURE_ADVANCE PARAMETER=ADVANCE START=0 FACTOR=.005 on a direct drive and .020 on a bowden, printing the hollow square from docs/prints/square_tower.stl at roughly 100 mm/s with zero infill and a layer height around 75% of the nozzle diameter.

Find the height with the cleanest corners. Measure it with calipers and read the answer off the tower: pressure_advance = <start> + <measured_height> * <factor>. The worked example in the document is 0 + 12.90 * .020, which gives .258.

The Marlin test is flat rather than vertical. Its pattern prints one line per candidate value, each line running 20 mm at the slow speed, then 40 mm fast, then 20 mm slow again — so every line crosses the transition twice, and the transition is what you grade, not the line. The chosen value goes into the start g-code as M900 Kxx. Before either test comes the unglamorous part: Klipper's page requires the extruder rotation_distance and the nozzle temperature to be tuned beforehand, since both of them move the answer.

Klipper warns that the correction is tied to the machine and to the material alike: «The pressure advance value is dependent on the extruder, the nozzle, and the filament. It is common for filament from different manufactures or with different pigments to require significantly different pressure advance values.» Open your slicer profiles and see whether one number is doing duty for every spool you own. If it is, the corners on most of those spools are being corrected with a figure calibrated on somebody else's plastic.

A printed test boat held in one hand; individual layers and the ridges at its corners are clearly visible on the hull and cabin
A test model printed in a wood-filled filament. A spool like this is the case Klipper warns about: a figure calibrated on ordinary PLA has to be found again here. Photo: #3DBenchy / flickr, licence CC BY 2.0 (https://creativecommons.org/licenses/by/2.0/), unmodified.

What the correction cannot do

Pressure advance moves plastic in time, not the toolhead in space. Klipper is explicit that the system «does not change the timing or path of the toolhead», so a corner rounded by acceleration limits stays rounded. And the model is linear in velocity only: Marlin's notes concede that variable-width moves are unhandled, since on a gap fill narrowing to a point «the extruder speed and therefore needed pressure gets smaller and smaller». Where the width changes instead of the speed, the correction term is zero and the defect is not.

The sources this article was written from

  • Klipper documentation, Pressure Advance — tuning procedure, tuning tower factors, typical coefficient range. Verbatim: «This command makes the nozzle travel slower through corners to emphasize the effects of extruder pressure»; «the pressure advance system causes additional filament to be pushed into the extruder during acceleration. The higher the desired filament flow rate, the more filament must be pushed in during acceleration to account for pressure. During head deceleration the extra filament is retracted (the extruder will have a negative velocity)»; «Typical pressure advance values are between 0.050 and 1.000 (the high end usually only with bowden extruders)»; «layers above the ideal setting can lead to rounded corners and poor extrusion leading up to the corner»; «The pressure advance value is dependent on the extruder, the nozzle, and the filament. It is common for filament from different manufactures or with different pigments to require significantly different pressure advance values»; «does not change the timing or path of the toolhead»
    Klipper documentation, Pressure advance — https://www.klipper3d.org/Pressure_Advance.html
  • Klipper documentation, Kinematics — the pressure model and the pa_position formula. Verbatim: «Pressure increases when filament is pushed into the extruder (as in Hooke's law) and the pressure necessary to extrude is dominated by the flow rate through the nozzle orifice (as in Poiseuille's law)»
    Klipper documentation, Kinematics — https://www.klipper3d.org/Kinematics.html
  • Marlin documentation, Linear Advance — the six phases of a calibration line, K-factor units and range. Verbatim: «Tuning flow and retraction can help, but this may lead to under-extrusion when starting new lines»; «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»; «The force required to push the filament through the nozzle aperture depends, in part, on the speed at which the material is being pushed into the nozzle. If the material is pushed faster (=printing fast), the filament needs to be compressed more before the pressure inside the nozzle is high enough to start extruding the material»; «A too high K-Factor essentially reverses the above picture. The extruded amount will overshoot at the start of an acceleration and starve in the deceleration phase»; «Bowden systems need a pressure advance feature the most as they usually have the most problems with speed changes»; «mm of filament compression needed per 1mm/s extrusion speed», «around 0.1-2.0»; «the extruder speed and therefore needed pressure gets smaller and smaller»
    Marlin documentation, Linear Advance — https://marlinfw.org/docs/features/lin_advance.html

Read next