diff --git a/xs/src/libslic3r/GCode/WipeTowerPrusaMM.cpp b/xs/src/libslic3r/GCode/WipeTowerPrusaMM.cpp
index ad7d91c50..bdafdfa23 100644
--- a/xs/src/libslic3r/GCode/WipeTowerPrusaMM.cpp
+++ b/xs/src/libslic3r/GCode/WipeTowerPrusaMM.cpp
@@ -792,9 +792,17 @@ void WipeTowerPrusaMM::toolchange_Unload(
     float xdist = std::abs(oldx-turning_point);
     float edist = -(m_cooling_tube_retraction+m_cooling_tube_length/2.f-42);
     writer.suppress_preview()
-          .load_move_x(turning_point,-15    , 60.f * std::hypot(xdist,15)/15 * 83 )    // fixed speed after ramming
-          .load_move_x(oldx         ,edist  , 60.f * std::hypot(xdist,edist)/std::abs(edist) * m_filpar[m_current_tool].unloading_speed )
-          .load_move_x(turning_point,-15    , 60.f * std::hypot(xdist,15)/15       * m_filpar[m_current_tool].unloading_speed*0.55f )
+          .load_move_x(turning_point,-15    , 60.f * std::hypot(xdist,15)/15 * 83 );    // fixed speed after ramming
+
+    // now an ugly hack: unload the filament with a check that the x speed is 50 mm/s
+    const float speed = m_filpar[m_current_tool].unloading_speed;
+    xdist = std::min(xdist, std::abs( 50 * edist / speed ));
+    const float feedrate = std::abs( std::hypot(edist, xdist) / ((edist / speed) / 60.f));
+    writer.load_move_x(writer.x() + (m_left_to_right ? -1.f : 1.f) * xdist ,edist, feedrate );
+    xdist = std::abs(oldx-turning_point); // recover old value of xdist
+
+
+    writer.load_move_x(turning_point,-15    , 60.f * std::hypot(xdist,15)/15       * m_filpar[m_current_tool].unloading_speed*0.55f )
           .load_move_x(oldx         ,-12    , 60.f * std::hypot(xdist,12)/12       * m_filpar[m_current_tool].unloading_speed*0.35f )
           .resume_preview();
 
@@ -876,11 +884,12 @@ void WipeTowerPrusaMM::toolchange_Load(
     float loading_speed = m_filpar[m_current_tool].loading_speed; // mm/s in e axis
     float turning_point = ( oldx-xl < xr-oldx ? xr : xl );
     float dist = std::abs(oldx-turning_point);
-    float edist = m_parking_pos_retraction-50-2; // loading is 2mm shorter that previous retraction, 50mm reserved for acceleration/deceleration
+    //float edist = m_parking_pos_retraction-50-2; // loading is 2mm shorter that previous retraction, 50mm reserved for acceleration/deceleration
+    float edist = m_parking_pos_retraction-50+m_extra_loading_move; // 50mm reserved for acceleration/deceleration
 	writer.append("; CP TOOLCHANGE LOAD\n")
 		  .suppress_preview()
 		  .load_move_x(turning_point, 20, 60*std::hypot(dist,20.f)/20.f * loading_speed*0.3f)  // Acceleration
-		  .load_move_x(oldx,edist,60*std::hypot(dist,edist)/edist * loading_speed)             // Fast phase
+		  .load_move_x(oldx,edist,std::abs( 60*std::hypot(dist,edist)/edist * loading_speed) ) // Fast phase
 		  .load_move_x(turning_point, 20, 60*std::hypot(dist,20.f)/20.f * loading_speed*0.3f)  // Slowing down
 		  .load_move_x(oldx, 10, 60*std::hypot(dist,10.f)/10.f * loading_speed*0.1f)           // Super slow
 		  .resume_preview();
diff --git a/xs/src/libslic3r/GCode/WipeTowerPrusaMM.hpp b/xs/src/libslic3r/GCode/WipeTowerPrusaMM.hpp
index 175de0276..daaabdfc0 100644
--- a/xs/src/libslic3r/GCode/WipeTowerPrusaMM.hpp
+++ b/xs/src/libslic3r/GCode/WipeTowerPrusaMM.hpp
@@ -43,8 +43,8 @@ public:
 	// width		-- width of wipe tower in mm ( default 60 mm - leave as it is )
 	// wipe_area	-- space available for one toolchange in mm
 	WipeTowerPrusaMM(float x, float y, float width, float rotation_angle, float cooling_tube_retraction,
-                     float cooling_tube_length, float parking_pos_retraction, float bridging, const std::vector<float>& wiping_matrix,
-                     unsigned int initial_tool) :
+                     float cooling_tube_length, float parking_pos_retraction, float extra_loading_move, float bridging,
+                     const std::vector<float>& wiping_matrix, unsigned int initial_tool) :
 		m_wipe_tower_pos(x, y),
 		m_wipe_tower_width(width),
 		m_wipe_tower_rotation_angle(rotation_angle),
@@ -54,6 +54,7 @@ public:
         m_cooling_tube_retraction(cooling_tube_retraction),
         m_cooling_tube_length(cooling_tube_length),
         m_parking_pos_retraction(parking_pos_retraction),
+        m_extra_loading_move(extra_loading_move),
 		m_bridging(bridging),
         m_current_tool(initial_tool)
  	{
@@ -197,6 +198,7 @@ private:
     float           m_cooling_tube_retraction   = 0.f;
     float           m_cooling_tube_length       = 0.f;
     float           m_parking_pos_retraction    = 0.f;
+    float           m_extra_loading_move        = 0.f;
     float           m_bridging                  = 0.f;
     bool            m_adhesion                  = true;
 
diff --git a/xs/src/libslic3r/Print.cpp b/xs/src/libslic3r/Print.cpp
index c19c97fae..c12cb64cd 100644
--- a/xs/src/libslic3r/Print.cpp
+++ b/xs/src/libslic3r/Print.cpp
@@ -202,6 +202,7 @@ bool Print::invalidate_state_by_config_options(const std::vector<t_config_option
             || opt_key == "parking_pos_retraction"
             || opt_key == "cooling_tube_retraction"
             || opt_key == "cooling_tube_length"
+            || opt_key == "extra_loading_move"
             || opt_key == "z_offset") {
             steps.emplace_back(psWipeTower);
         } else if (
@@ -1076,7 +1077,8 @@ void Print::_make_wipe_tower()
         float(this->config.wipe_tower_width.value),
         float(this->config.wipe_tower_rotation_angle.value), float(this->config.cooling_tube_retraction.value),
         float(this->config.cooling_tube_length.value), float(this->config.parking_pos_retraction.value),
-        float(this->config.wipe_tower_bridging), wiping_volumes, m_tool_ordering.first_extruder());
+        float(this->config.extra_loading_move.value), float(this->config.wipe_tower_bridging), wiping_volumes,
+        m_tool_ordering.first_extruder());
 
     //wipe_tower.set_retract();
     //wipe_tower.set_zhop();
diff --git a/xs/src/libslic3r/PrintConfig.cpp b/xs/src/libslic3r/PrintConfig.cpp
index 1e7e0bacc..75129f4fd 100644
--- a/xs/src/libslic3r/PrintConfig.cpp
+++ b/xs/src/libslic3r/PrintConfig.cpp
@@ -1045,6 +1045,15 @@ PrintConfigDef::PrintConfigDef()
     def->min = 0;
     def->default_value = new ConfigOptionFloat(92.f);
 
+    def = this->add("extra_loading_move", coFloat);
+    def->label = L("Extra loading distance");
+    def->tooltip = L("When set to zero, the distance the filament is moved from parking position during load "
+                      "is exactly the same as it was moved back during unload. When positive, it is loaded further, "
+                      " if negative, the loading move is shorter than unloading. ");
+    def->sidetext = L("mm");
+    def->cli = "extra_loading_move=f";
+    def->default_value = new ConfigOptionFloat(-2.f);
+
     def = this->add("perimeter_acceleration", coFloat);
     def->label = L("Perimeters");
     def->tooltip = L("This is the acceleration your printer will use for perimeters. "
diff --git a/xs/src/libslic3r/PrintConfig.hpp b/xs/src/libslic3r/PrintConfig.hpp
index 967a87310..62d8c7101 100644
--- a/xs/src/libslic3r/PrintConfig.hpp
+++ b/xs/src/libslic3r/PrintConfig.hpp
@@ -506,6 +506,7 @@ public:
     ConfigOptionFloat               cooling_tube_retraction;
     ConfigOptionFloat               cooling_tube_length;
     ConfigOptionFloat               parking_pos_retraction;
+    ConfigOptionFloat               extra_loading_move;
 
 
     std::string get_extrusion_axis() const
@@ -564,6 +565,7 @@ protected:
         OPT_PTR(cooling_tube_retraction);
         OPT_PTR(cooling_tube_length);
         OPT_PTR(parking_pos_retraction);
+        OPT_PTR(extra_loading_move);
     }
 };
 
diff --git a/xs/src/slic3r/GUI/Preset.cpp b/xs/src/slic3r/GUI/Preset.cpp
index d48c9bf8f..e4a4b2093 100644
--- a/xs/src/slic3r/GUI/Preset.cpp
+++ b/xs/src/slic3r/GUI/Preset.cpp
@@ -226,7 +226,7 @@ const std::vector<std::string>& Preset::printer_options()
             "octoprint_host", "octoprint_apikey", "octoprint_cafile", "use_firmware_retraction", "use_volumetric_e", "variable_layer_height",
             "single_extruder_multi_material", "start_gcode", "end_gcode", "before_layer_gcode", "layer_gcode", "toolchange_gcode",
             "between_objects_gcode", "printer_vendor", "printer_model", "printer_variant", "printer_notes", "cooling_tube_retraction",
-            "cooling_tube_length", "parking_pos_retraction", "max_print_height", "default_print_profile", "inherits",
+            "cooling_tube_length", "parking_pos_retraction", "extra_loading_move", "max_print_height", "default_print_profile", "inherits",
         };
         s_opts.insert(s_opts.end(), Preset::nozzle_options().begin(), Preset::nozzle_options().end());
     }
diff --git a/xs/src/slic3r/GUI/Tab.cpp b/xs/src/slic3r/GUI/Tab.cpp
index cc4b18c7c..8ffe27351 100644
--- a/xs/src/slic3r/GUI/Tab.cpp
+++ b/xs/src/slic3r/GUI/Tab.cpp
@@ -1743,6 +1743,7 @@ void TabPrinter::build_extruder_pages(){
                 optgroup->append_single_option_line("cooling_tube_retraction");
                 optgroup->append_single_option_line("cooling_tube_length");
                 optgroup->append_single_option_line("parking_pos_retraction");
+                optgroup->append_single_option_line("extra_loading_move");
             m_pages.insert(m_pages.begin()+1,page);
         }
     }