diff --git a/Marlin/src/feature/I2CPositionEncoder.cpp b/Marlin/src/feature/I2CPositionEncoder.cpp
index 7c80ff3a390dc4b530731566402a6cd0efe2569a..9d7e4bddb83ddb83cf36f9440c8a6dc80b5b5fce 100644
--- a/Marlin/src/feature/I2CPositionEncoder.cpp
+++ b/Marlin/src/feature/I2CPositionEncoder.cpp
@@ -358,7 +358,7 @@ bool I2CPositionEncoder::test_axis() {
 
   stepper.synchronize();
 
-  planner.buffer_line(startCoord[X_AXIS],startCoord[Y_AXIS],startCoord[Z_AXIS],
+  planner.buffer_line(startCoord[X_AXIS], startCoord[Y_AXIS], startCoord[Z_AXIS],
                       stepper.get_axis_position_mm(E_AXIS), feedrate, 0);
   stepper.synchronize();
 
@@ -415,10 +415,10 @@ void I2CPositionEncoder::calibrate_steps_mm(const uint8_t iter) {
   startCoord[encoderAxis] = startDistance;
   endCoord[encoderAxis] = endDistance;
 
-  LOOP_L_N(i, iter) {
-    stepper.synchronize();
+  stepper.synchronize();
 
-    planner.buffer_line(startCoord[X_AXIS],startCoord[Y_AXIS],startCoord[Z_AXIS],
+  LOOP_L_N(i, iter) {
+    planner.buffer_line(startCoord[X_AXIS], startCoord[Y_AXIS], startCoord[Z_AXIS],
                         stepper.get_axis_position_mm(E_AXIS), feedrate, 0);
     stepper.synchronize();
 
@@ -427,7 +427,7 @@ void I2CPositionEncoder::calibrate_steps_mm(const uint8_t iter) {
 
     //do_blocking_move_to(endCoord[X_AXIS],endCoord[Y_AXIS],endCoord[Z_AXIS]);
 
-    planner.buffer_line(endCoord[X_AXIS],endCoord[Y_AXIS],endCoord[Z_AXIS],
+    planner.buffer_line(endCoord[X_AXIS], endCoord[Y_AXIS], endCoord[Z_AXIS],
                         stepper.get_axis_position_mm(E_AXIS), feedrate, 0);
     stepper.synchronize();
 
diff --git a/Marlin/src/feature/fwretract.cpp b/Marlin/src/feature/fwretract.cpp
index 06065f2631acd8e485a68a5d83dc40bbc10d273e..efd916f38154fbe8af6f3cd45b874fe86bfd7dd4 100644
--- a/Marlin/src/feature/fwretract.cpp
+++ b/Marlin/src/feature/fwretract.cpp
@@ -108,7 +108,7 @@ void FWRetract::retract(const bool retracting
     // G11 priority to recover the long retract if activated
     if (!retracting) swapping = retracted_swap[active_extruder];
   #else
-    const bool swapping = false;
+    constexpr bool swapping = false;
   #endif
 
   /* // debugging
@@ -118,62 +118,57 @@ void FWRetract::retract(const bool retracting
     for (uint8_t i = 0; i < EXTRUDERS; ++i) {
       SERIAL_ECHOPAIR("retracted[", i);
       SERIAL_ECHOLNPAIR("] ", retracted[i]);
-      SERIAL_ECHOPAIR("retracted_swap[", i);
-      SERIAL_ECHOLNPAIR("] ", retracted_swap[i]);
+      #if EXTRUDERS > 1
+        SERIAL_ECHOPAIR("retracted_swap[", i);
+        SERIAL_ECHOLNPAIR("] ", retracted_swap[i]);
+      #endif
     }
     SERIAL_ECHOLNPAIR("current_position[z] ", current_position[Z_AXIS]);
     SERIAL_ECHOLNPAIR("current_position[e] ", current_position[E_AXIS]);
     SERIAL_ECHOLNPAIR("hop_amount ", hop_amount);
   //*/
 
-  const float old_feedrate_mm_s = feedrate_mm_s;
+  const float old_feedrate_mm_s = feedrate_mm_s,
+              renormalize = RECIPROCAL(planner.e_factor[active_extruder]),
+              base_retract = swapping ? swap_retract_length : retract_length,
+              old_z = current_position[Z_AXIS],
+              old_e = current_position[E_AXIS];
 
   // The current position will be the destination for E and Z moves
   set_destination_from_current();
-  stepper.synchronize();  // Wait for buffered moves to complete
-
-  const float renormalize = 1.0 / planner.e_factor[active_extruder];
 
   if (retracting) {
     // Retract by moving from a faux E position back to the current E position
     feedrate_mm_s = retract_feedrate_mm_s;
-    current_position[E_AXIS] += (swapping ? swap_retract_length : retract_length) * renormalize;
-    sync_plan_position_e();
-    prepare_move_to_destination();  // set_current_to_destination
+    destination[E_AXIS] -= base_retract * renormalize;
+    prepare_move_to_destination();                        // set_current_to_destination
 
     // Is a Z hop set, and has the hop not yet been done?
-    // No double zlifting
-    // Feedrate to the max
     if (retract_zlift > 0.01 && !hop_amount) {            // Apply hop only once
-      const float old_z = current_position[Z_AXIS];
       hop_amount += retract_zlift;                        // Add to the hop total (again, only once)
       destination[Z_AXIS] += retract_zlift;               // Raise Z by the zlift (M207 Z) amount
       feedrate_mm_s = planner.max_feedrate_mm_s[Z_AXIS];  // Maximum Z feedrate
       prepare_move_to_destination();                      // Raise up, set_current_to_destination
-      current_position[Z_AXIS] = old_z;                   // Spoof the Z position in the planner
-      SYNC_PLAN_POSITION_KINEMATIC();
     }
   }
   else {
     // If a hop was done and Z hasn't changed, undo the Z hop
     if (hop_amount) {
-      current_position[Z_AXIS] += hop_amount;             // Set actual Z (due to the prior hop)
-      SYNC_PLAN_POSITION_KINEMATIC();                     // Spoof the Z position in the planner
+      destination[Z_AXIS] -= hop_amount;                  // Move back down by the total hop amount
       feedrate_mm_s = planner.max_feedrate_mm_s[Z_AXIS];  // Z feedrate to max
       prepare_move_to_destination();                      // Lower Z, set_current_to_destination
       hop_amount = 0.0;                                   // Clear the hop amount
     }
 
-    // A retract multiplier has been added here to get faster swap recovery
+    destination[E_AXIS] += (base_retract + (swapping ? swap_retract_recover_length : retract_recover_length)) * renormalize;
     feedrate_mm_s = swapping ? swap_retract_recover_feedrate_mm_s : retract_recover_feedrate_mm_s;
-
-    current_position[E_AXIS] -= (swapping ? swap_retract_length + swap_retract_recover_length
-                                          : retract_length + retract_recover_length) * renormalize;
-    sync_plan_position_e();
     prepare_move_to_destination();                        // Recover E, set_current_to_destination
   }
 
   feedrate_mm_s = old_feedrate_mm_s;                      // Restore original feedrate
+  current_position[Z_AXIS] = old_z;                       // Restore Z and E positions
+  current_position[E_AXIS] = old_e;
+  SYNC_PLAN_POSITION_KINEMATIC();                         // As if the move never took place
 
   retracted[active_extruder] = retracting;                // Active extruder now retracted / recovered
 
@@ -189,8 +184,10 @@ void FWRetract::retract(const bool retracting
     for (uint8_t i = 0; i < EXTRUDERS; ++i) {
       SERIAL_ECHOPAIR("retracted[", i);
       SERIAL_ECHOLNPAIR("] ", retracted[i]);
-      SERIAL_ECHOPAIR("retracted_swap[", i);
-      SERIAL_ECHOLNPAIR("] ", retracted_swap[i]);
+      #if EXTRUDERS > 1
+        SERIAL_ECHOPAIR("retracted_swap[", i);
+        SERIAL_ECHOLNPAIR("] ", retracted_swap[i]);
+      #endif
     }
     SERIAL_ECHOLNPAIR("current_position[z] ", current_position[Z_AXIS]);
     SERIAL_ECHOLNPAIR("current_position[e] ", current_position[E_AXIS]);
diff --git a/Marlin/src/feature/pause.cpp b/Marlin/src/feature/pause.cpp
index 96663665440086c36710858b3ed2c9209fc9b589..913316ecf91a1265e6cf81238e092a52d5b489bb 100644
--- a/Marlin/src/feature/pause.cpp
+++ b/Marlin/src/feature/pause.cpp
@@ -121,8 +121,8 @@ static void do_pause_e_move(const float &length, const float &fr) {
   set_destination_from_current();
   destination[E_AXIS] += length / planner.e_factor[active_extruder];
   planner.buffer_line_kinematic(destination, fr, active_extruder);
-  stepper.synchronize();
   set_current_from_destination();
+  stepper.synchronize();
 }
 
 /**
@@ -366,12 +366,12 @@ bool pause_print(const float &retract, const point_t &park_point, const float &u
   #endif
   print_job_timer.pause();
 
-  // Wait for synchronize steppers
-  stepper.synchronize();
-
   // Save current position
   COPY(resume_position, current_position);
 
+  // Wait for buffered blocks to complete
+  stepper.synchronize();
+
   // Initial retract before move to filament change position
   if (retract && thermalManager.hotEnoughToExtrude(active_extruder))
     do_pause_e_move(retract, PAUSE_PARK_RETRACT_FEEDRATE);
diff --git a/Marlin/src/gcode/bedlevel/G26.cpp b/Marlin/src/gcode/bedlevel/G26.cpp
index 616cc58ee4d4993671e9af75b10b6f7f4916f23a..9f3f4c03c830a048d75151b51f72ef111dfe3136 100644
--- a/Marlin/src/gcode/bedlevel/G26.cpp
+++ b/Marlin/src/gcode/bedlevel/G26.cpp
@@ -240,8 +240,6 @@ void move_to(const float &rx, const float &ry, const float &z, const float &e_de
     destination[E_AXIS] = current_position[E_AXIS];
 
     G26_line_to_destination(feed_value);
-
-    stepper.synchronize();
     set_destination_from_current();
   }
 
@@ -256,8 +254,6 @@ void move_to(const float &rx, const float &ry, const float &z, const float &e_de
   destination[E_AXIS] += e_delta;
 
   G26_line_to_destination(feed_value);
-
-  stepper.synchronize();
   set_destination_from_current();
 }
 
@@ -499,13 +495,11 @@ inline bool prime_nozzle() {
           if (Total_Prime >= EXTRUDE_MAXLENGTH) return G26_ERR;
         #endif
         G26_line_to_destination(planner.max_feedrate_mm_s[E_AXIS] / 15.0);
-
+        set_destination_from_current();
         stepper.synchronize();    // Without this synchronize, the purge is more consistent,
                                   // but because the planner has a buffer, we won't be able
                                   // to stop as quickly. So we put up with the less smooth
                                   // action to give the user a more responsive 'Stop'.
-        set_destination_from_current();
-        idle();
       }
 
       wait_for_release();
@@ -526,7 +520,6 @@ inline bool prime_nozzle() {
     set_destination_from_current();
     destination[E_AXIS] += g26_prime_length;
     G26_line_to_destination(planner.max_feedrate_mm_s[E_AXIS] / 15.0);
-    stepper.synchronize();
     set_destination_from_current();
     retract_filament(destination);
   }
@@ -700,7 +693,6 @@ void GcodeSuite::G26() {
 
   if (current_position[Z_AXIS] < Z_CLEARANCE_BETWEEN_PROBES) {
     do_blocking_move_to_z(Z_CLEARANCE_BETWEEN_PROBES);
-    stepper.synchronize();
     set_current_from_destination();
   }
 
diff --git a/Marlin/src/gcode/bedlevel/abl/G29.cpp b/Marlin/src/gcode/bedlevel/abl/G29.cpp
index 49b1fa7cb1cc4ab282adb3f6e4be92568cee2c34..8f33033af9c4ce56fae12fac8a74ede368160307 100644
--- a/Marlin/src/gcode/bedlevel/abl/G29.cpp
+++ b/Marlin/src/gcode/bedlevel/abl/G29.cpp
@@ -949,8 +949,8 @@ void GcodeSuite::G29() {
       #if ENABLED(DEBUG_LEVELING_FEATURE)
         if (DEBUGGING(LEVELING)) SERIAL_ECHOLNPAIR("Z Probe End Script: ", Z_PROBE_END_SCRIPT);
       #endif
-      enqueue_and_echo_commands_P(PSTR(Z_PROBE_END_SCRIPT));
       stepper.synchronize();
+      enqueue_and_echo_commands_P(PSTR(Z_PROBE_END_SCRIPT));
     #endif
 
     // Auto Bed Leveling is complete! Enable if possible.
diff --git a/Marlin/src/gcode/control/M80_M81.cpp b/Marlin/src/gcode/control/M80_M81.cpp
index eb300b01db5316b243ad42071179050f929def08..eae35d1c4ea72d58509780cd1f4bc3afbda8e94e 100644
--- a/Marlin/src/gcode/control/M80_M81.cpp
+++ b/Marlin/src/gcode/control/M80_M81.cpp
@@ -108,7 +108,6 @@ void GcodeSuite::M81() {
   safe_delay(1000); // Wait 1 second before switching off
 
   #if HAS_SUICIDE
-    stepper.synchronize();
     suicide();
   #elif HAS_POWER_SWITCH
     PSU_OFF();
diff --git a/Marlin/src/gcode/geometry/G92.cpp b/Marlin/src/gcode/geometry/G92.cpp
index 0b10aab5b8c3c57a53dd14f88f53a1654a071a32..933a6e1cdb835add8152aa32d4f6c80073c32da6 100644
--- a/Marlin/src/gcode/geometry/G92.cpp
+++ b/Marlin/src/gcode/geometry/G92.cpp
@@ -33,8 +33,6 @@
  */
 void GcodeSuite::G92() {
 
-  stepper.synchronize();
-
   #if ENABLED(CNC_COORDINATE_SYSTEMS)
     switch (parser.subcode) {
       case 1:
@@ -94,10 +92,8 @@ void GcodeSuite::G92() {
       COPY(coordinate_system[active_coordinate_system], position_shift);
   #endif
 
-  if (didXYZ)
-    SYNC_PLAN_POSITION_KINEMATIC();
-  else if (didE)
-    sync_plan_position_e();
+  if    (didXYZ) SYNC_PLAN_POSITION_KINEMATIC();
+  else if (didE) sync_plan_position_e();
 
   report_current_position();
 }
diff --git a/Marlin/src/gcode/host/M114.cpp b/Marlin/src/gcode/host/M114.cpp
index 5ca83eedaaabff39d1da9c955a5ffa0f7722e411..af50da56565f66a2df63ac0f1648678f90e18d82 100644
--- a/Marlin/src/gcode/host/M114.cpp
+++ b/Marlin/src/gcode/host/M114.cpp
@@ -43,8 +43,6 @@
 
   void report_current_position_detail() {
 
-    stepper.synchronize();
-
     SERIAL_PROTOCOLPGM("\nLogical:");
     const float logical[XYZ] = {
       LOGICAL_X_POSITION(current_position[X_AXIS]),
@@ -79,6 +77,8 @@
       report_xyz(delta);
     #endif
 
+    stepper.synchronize();
+
     SERIAL_PROTOCOLPGM("Stepper:");
     LOOP_XYZE(i) {
       SERIAL_CHAR(' ');
diff --git a/Marlin/src/gcode/lcd/M0_M1.cpp b/Marlin/src/gcode/lcd/M0_M1.cpp
index bd41673f35d4aa8631e1b8069eb26f45911a401c..453d02cd03d2863bc05b54ffc4fe72b9a892fec5 100644
--- a/Marlin/src/gcode/lcd/M0_M1.cpp
+++ b/Marlin/src/gcode/lcd/M0_M1.cpp
@@ -58,6 +58,8 @@ void GcodeSuite::M0_M1() {
 
   const bool has_message = !hasP && !hasS && args && *args;
 
+  stepper.synchronize();
+
   #if ENABLED(ULTIPANEL)
 
     if (has_message)
@@ -81,8 +83,6 @@ void GcodeSuite::M0_M1() {
   KEEPALIVE_STATE(PAUSED_FOR_USER);
   wait_for_user = true;
 
-  stepper.synchronize();
-
   if (ms > 0) {
     ms += millis();  // wait until this time for a click
     while (PENDING(millis(), ms) && wait_for_user) idle();
diff --git a/Marlin/src/module/motion.cpp b/Marlin/src/module/motion.cpp
index 66da4137411bc80d62ba83e4ccb33c306522298e..fdb92fb03e62305e0f67f3f97985d14b55d2ccd9 100644
--- a/Marlin/src/module/motion.cpp
+++ b/Marlin/src/module/motion.cpp
@@ -396,13 +396,13 @@ void do_blocking_move_to(const float rx, const float ry, const float rz, const f
 
   #endif
 
-  stepper.synchronize();
-
   feedrate_mm_s = old_feedrate_mm_s;
 
   #if ENABLED(DEBUG_LEVELING_FEATURE)
     if (DEBUGGING(LEVELING)) SERIAL_ECHOLNPGM("<<< do_blocking_move_to");
   #endif
+
+  stepper.synchronize();
 }
 void do_blocking_move_to_x(const float &rx, const float &fr_mm_s/*=0.0*/) {
   do_blocking_move_to(rx, current_position[Y_AXIS], current_position[Z_AXIS], fr_mm_s);
@@ -881,8 +881,8 @@ float soft_endstop_min[XYZ] = { X_MIN_BED, Y_MIN_BED, Z_MIN_POS },
               current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS],
               planner.max_feedrate_mm_s[X_AXIS], 1
             );
-            SYNC_PLAN_POSITION_KINEMATIC();
             stepper.synchronize();
+            SYNC_PLAN_POSITION_KINEMATIC();
             extruder_duplication_enabled = true;
             active_extruder_parked = false;
             #if ENABLED(DEBUG_LEVELING_FEATURE)
@@ -1106,7 +1106,7 @@ static void do_homing_move(const AxisEnum axis, const float distance, const floa
     planner.buffer_line(delta[A_AXIS], delta[B_AXIS], delta[C_AXIS], current_position[E_AXIS], fr_mm_s ? fr_mm_s : homing_feedrate(axis), active_extruder);
   #else
     sync_plan_position();
-    current_position[axis] = distance;
+    current_position[axis] = distance; // Set delta/cartesian axes directly
     planner.buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], fr_mm_s ? fr_mm_s : homing_feedrate(axis), active_extruder);
   #endif
 
diff --git a/Marlin/src/module/planner.cpp b/Marlin/src/module/planner.cpp
index 8aa08cd54b36370d2d26889d109999929a2ecc59..4be4b2af5940fa2a071c64301f9ca0b8cae4728d 100644
--- a/Marlin/src/module/planner.cpp
+++ b/Marlin/src/module/planner.cpp
@@ -1382,15 +1382,9 @@ void Planner::_buffer_steps(const int32_t (&target)[XYZE]
   const float esteps_float = de * e_factor[extruder];
   const int32_t esteps = abs(esteps_float) + 0.5;
 
-  // Calculate the buffer head after we push this byte
-  const uint8_t next_buffer_head = next_block_index(block_buffer_head);
-
-  // If the buffer is full: good! That means we are well ahead of the robot.
-  // Rest here until there is room in the buffer.
-  while (block_buffer_tail == next_buffer_head) idle();
-
-  // Prepare to set up new block
-  block_t* block = &block_buffer[block_buffer_head];
+  // Wait for the next available block
+  uint8_t next_buffer_head;
+  block_t * const block = get_next_free_block(next_buffer_head);
 
   // Clear all flags, including the "busy" bit
   block->flag = 0x00;
@@ -2032,6 +2026,26 @@ void Planner::_buffer_steps(const int32_t (&target)[XYZE]
 
 } // _buffer_steps()
 
+/**
+ * Planner::buffer_sync_block
+ * Add a block to the buffer that just updates the position
+ */
+void Planner::buffer_sync_block() {
+  // Wait for the next available block
+  uint8_t next_buffer_head;
+  block_t * const block = get_next_free_block(next_buffer_head);
+
+  block->steps[A_AXIS] = position[A_AXIS];
+  block->steps[B_AXIS] = position[B_AXIS];
+  block->steps[C_AXIS] = position[C_AXIS];
+  block->steps[E_AXIS] = position[E_AXIS];
+
+  block->flag = BLOCK_FLAG_SYNC_POSITION;
+
+  block_buffer_head = next_buffer_head;
+  stepper.wake_up();
+} // buffer_sync_block()
+
 /**
  * Planner::buffer_segment
  *
@@ -2160,19 +2174,19 @@ void Planner::_set_position_mm(const float &a, const float &b, const float &c, c
   #else
     #define _EINDEX E_AXIS
   #endif
-  const int32_t na = position[A_AXIS] = LROUND(a * axis_steps_per_mm[A_AXIS]),
-                nb = position[B_AXIS] = LROUND(b * axis_steps_per_mm[B_AXIS]),
-                nc = position[C_AXIS] = LROUND(c * axis_steps_per_mm[C_AXIS]),
-                ne = position[E_AXIS] = LROUND(e * axis_steps_per_mm[_EINDEX]);
+  position[A_AXIS] = LROUND(a * axis_steps_per_mm[A_AXIS]),
+  position[B_AXIS] = LROUND(b * axis_steps_per_mm[B_AXIS]),
+  position[C_AXIS] = LROUND(c * axis_steps_per_mm[C_AXIS]),
+  position[E_AXIS] = LROUND(e * axis_steps_per_mm[_EINDEX]);
   #if HAS_POSITION_FLOAT
-    position_float[X_AXIS] = a;
-    position_float[Y_AXIS] = b;
-    position_float[Z_AXIS] = c;
+    position_float[A_AXIS] = a;
+    position_float[B_AXIS] = b;
+    position_float[C_AXIS] = c;
     position_float[E_AXIS] = e;
   #endif
-  stepper.set_position(na, nb, nc, ne);
   previous_nominal_speed = 0.0; // Resets planner junction speeds. Assumes start from rest.
   ZERO(previous_speed);
+  buffer_sync_block();
 }
 
 void Planner::set_position_mm_kinematic(const float (&cart)[XYZE]) {
@@ -2220,23 +2234,23 @@ void Planner::set_position_mm(const AxisEnum axis, const float &v) {
   #if HAS_POSITION_FLOAT
     position_float[axis] = v;
   #endif
-  stepper.set_position(axis, position[axis]);
   previous_speed[axis] = 0.0;
+  buffer_sync_block();
 }
 
 // Recalculate the steps/s^2 acceleration rates, based on the mm/s^2
 void Planner::reset_acceleration_rates() {
   #if ENABLED(DISTINCT_E_FACTORS)
-    #define HIGHEST_CONDITION (i < E_AXIS || i == E_AXIS + active_extruder)
+    #define AXIS_CONDITION (i < E_AXIS || i == E_AXIS + active_extruder)
   #else
-    #define HIGHEST_CONDITION true
+    #define AXIS_CONDITION true
   #endif
   uint32_t highest_rate = 1;
   LOOP_XYZE_N(i) {
     max_acceleration_steps_per_s2[i] = max_acceleration_mm_per_s2[i] * axis_steps_per_mm[i];
-    if (HIGHEST_CONDITION) NOLESS(highest_rate, max_acceleration_steps_per_s2[i]);
+    if (AXIS_CONDITION) NOLESS(highest_rate, max_acceleration_steps_per_s2[i]);
   }
-  cutoff_long = 4294967295UL / highest_rate;
+  cutoff_long = 4294967295UL / highest_rate; // 0xFFFFFFFFUL
 }
 
 // Recalculate position, steps_to_mm if axis_steps_per_mm changes!
diff --git a/Marlin/src/module/planner.h b/Marlin/src/module/planner.h
index 031cee7451ba4ce315a936102fb493d75bfeec68..eceb31f3a14582ee0ceff2ff9afda988b6a7d414 100644
--- a/Marlin/src/module/planner.h
+++ b/Marlin/src/module/planner.h
@@ -57,14 +57,18 @@ enum BlockFlagBit : char {
   BLOCK_BIT_BUSY,
 
   // The block is segment 2+ of a longer move
-  BLOCK_BIT_CONTINUED
+  BLOCK_BIT_CONTINUED,
+
+  // Sync the stepper counts from the block
+  BLOCK_BIT_SYNC_POSITION
 };
 
 enum BlockFlag : char {
   BLOCK_FLAG_RECALCULATE          = _BV(BLOCK_BIT_RECALCULATE),
   BLOCK_FLAG_NOMINAL_LENGTH       = _BV(BLOCK_BIT_NOMINAL_LENGTH),
   BLOCK_FLAG_BUSY                 = _BV(BLOCK_BIT_BUSY),
-  BLOCK_FLAG_CONTINUED            = _BV(BLOCK_BIT_CONTINUED)
+  BLOCK_FLAG_CONTINUED            = _BV(BLOCK_BIT_CONTINUED),
+  BLOCK_FLAG_SYNC_POSITION        = _BV(BLOCK_BIT_SYNC_POSITION)
 };
 
 /**
@@ -422,6 +426,20 @@ class Planner {
 
     #endif
 
+
+    /**
+     * Planner::get_next_free_block
+     *
+     * - Get the next head index (passed by reference)
+     * - Wait for a space to open up in the planner
+     * - Return the head block
+     */
+    FORCE_INLINE static block_t* get_next_free_block(uint8_t &next_buffer_head) {
+      next_buffer_head = next_block_index(block_buffer_head);
+      while (block_buffer_tail == next_buffer_head) idle(); // while (is_full)
+      return &block_buffer[block_buffer_head];
+    }
+
     /**
      * Planner::_buffer_steps
      *
@@ -439,6 +457,12 @@ class Planner {
       , float fr_mm_s, const uint8_t extruder, const float &millimeters=0.0
     );
 
+    /**
+     * Planner::buffer_sync_block
+     * Add a block to the buffer that just updates the position
+     */
+    static void buffer_sync_block();
+
     /**
      * Planner::buffer_segment
      *
@@ -518,7 +542,7 @@ class Planner {
     static void set_position_mm_kinematic(const float (&cart)[XYZE]);
     static void set_position_mm(const AxisEnum axis, const float &v);
     FORCE_INLINE static void set_z_position_mm(const float &z) { set_position_mm(Z_AXIS, z); }
-    FORCE_INLINE static void set_e_position_mm(const float &e) { set_position_mm(AxisEnum(E_AXIS), e); }
+    FORCE_INLINE static void set_e_position_mm(const float &e) { set_position_mm(E_AXIS, e); }
 
     /**
      * Sync from the stepper positions. (e.g., after an interrupted move)
@@ -528,7 +552,7 @@ class Planner {
     /**
      * Does the buffer have any blocks queued?
      */
-    static bool has_blocks_queued() { return (block_buffer_head != block_buffer_tail); }
+    FORCE_INLINE static bool has_blocks_queued() { return (block_buffer_head != block_buffer_tail); }
 
     /**
      * "Discard" the block and "release" the memory.
diff --git a/Marlin/src/module/stepper.cpp b/Marlin/src/module/stepper.cpp
index 04c6c270f53b1ba7a86ebd79953719306b9f4c02..4e6747a1242df1824716202e27ad38dc722500b8 100644
--- a/Marlin/src/module/stepper.cpp
+++ b/Marlin/src/module/stepper.cpp
@@ -109,10 +109,10 @@ int16_t Stepper::cleaning_buffer_counter = 0;
   bool Stepper::locked_z_motor = false, Stepper::locked_z2_motor = false;
 #endif
 
-long Stepper::counter_X = 0,
-     Stepper::counter_Y = 0,
-     Stepper::counter_Z = 0,
-     Stepper::counter_E = 0;
+int32_t Stepper::counter_X = 0,
+        Stepper::counter_Y = 0,
+        Stepper::counter_Z = 0,
+        Stepper::counter_E = 0;
 
 volatile uint32_t Stepper::step_events_completed = 0; // The number of step events executed in the current block
 
@@ -159,7 +159,7 @@ volatile int32_t Stepper::count_position[NUM_AXIS] = { 0 };
 volatile signed char Stepper::count_direction[NUM_AXIS] = { 1, 1, 1, 1 };
 
 #if ENABLED(MIXING_EXTRUDER)
-  long Stepper::counter_m[MIXING_STEPPERS];
+  int32_t Stepper::counter_m[MIXING_STEPPERS];
 #endif
 
 uint8_t Stepper::step_loops, Stepper::step_loops_nominal;
@@ -169,7 +169,7 @@ hal_timer_t Stepper::OCR1A_nominal;
   hal_timer_t Stepper::acc_step_rate; // needed for deceleration start point
 #endif
 
-volatile long Stepper::endstops_trigsteps[XYZ];
+volatile int32_t Stepper::endstops_trigsteps[XYZ];
 
 #if ENABLED(X_DUAL_ENDSTOPS) || ENABLED(Y_DUAL_ENDSTOPS) || ENABLED(Z_DUAL_ENDSTOPS)
   #define LOCKED_X_MOTOR  locked_x_motor
@@ -1217,6 +1217,16 @@ void Stepper::isr() {
     // Anything in the buffer?
     if ((current_block = planner.get_current_block())) {
 
+      // Sync block? Sync the stepper counts and return
+      while (TEST(current_block->flag, BLOCK_BIT_SYNC_POSITION)) {
+        _set_position(
+          current_block->steps[A_AXIS], current_block->steps[B_AXIS],
+          current_block->steps[C_AXIS], current_block->steps[E_AXIS]
+        );
+        planner.discard_current_block();
+        if (!(current_block = planner.get_current_block())) return;
+      }
+
       // Initialize the trapezoid generator from the current block.
       static int8_t last_extruder = -1;
 
@@ -1976,12 +1986,7 @@ void Stepper::synchronize() { while (planner.has_blocks_queued() || cleaning_buf
  * This allows get_axis_position_mm to correctly
  * derive the current XYZ position later on.
  */
-void Stepper::set_position(const long &a, const long &b, const long &c, const long &e) {
-
-  synchronize(); // Bad to set stepper counts in the middle of a move
-
-  CRITICAL_SECTION_START;
-
+void Stepper::_set_position(const int32_t &a, const int32_t &b, const int32_t &c, const int32_t &e) {
   #if CORE_IS_XY
     // corexy positioning
     // these equations follow the form of the dA and dB equations on http://www.corexy.com/theory.html
@@ -2004,29 +2009,15 @@ void Stepper::set_position(const long &a, const long &b, const long &c, const lo
     count_position[Y_AXIS] = b;
     count_position[Z_AXIS] = c;
   #endif
-
-  count_position[E_AXIS] = e;
-  CRITICAL_SECTION_END;
-}
-
-void Stepper::set_position(const AxisEnum &axis, const long &v) {
-  CRITICAL_SECTION_START;
-  count_position[axis] = v;
-  CRITICAL_SECTION_END;
-}
-
-void Stepper::set_e_position(const long &e) {
-  CRITICAL_SECTION_START;
   count_position[E_AXIS] = e;
-  CRITICAL_SECTION_END;
 }
 
 /**
  * Get a stepper's position in steps.
  */
-long Stepper::position(const AxisEnum axis) {
+int32_t Stepper::position(const AxisEnum axis) {
   CRITICAL_SECTION_START;
-  const long count_pos = count_position[axis];
+  const int32_t count_pos = count_position[axis];
   CRITICAL_SECTION_END;
   return count_pos;
 }
@@ -2095,9 +2086,9 @@ void Stepper::endstop_triggered(const AxisEnum axis) {
 
 void Stepper::report_positions() {
   CRITICAL_SECTION_START;
-  const long xpos = count_position[X_AXIS],
-             ypos = count_position[Y_AXIS],
-             zpos = count_position[Z_AXIS];
+  const int32_t xpos = count_position[X_AXIS],
+                ypos = count_position[Y_AXIS],
+                zpos = count_position[Z_AXIS];
   CRITICAL_SECTION_END;
 
   #if CORE_IS_XY || CORE_IS_XZ || IS_DELTA || IS_SCARA
diff --git a/Marlin/src/module/stepper.h b/Marlin/src/module/stepper.h
index 88bbab8743945c8029463d9ac8baddcecb122c96..19bfeec685b2b4a17e42e6a37648f4c7917d68d5 100644
--- a/Marlin/src/module/stepper.h
+++ b/Marlin/src/module/stepper.h
@@ -94,7 +94,7 @@ class Stepper {
     #endif
 
     // Counter variables for the Bresenham line tracer
-    static long counter_X, counter_Y, counter_Z, counter_E;
+    static int32_t counter_X, counter_Y, counter_Z, counter_E;
     static volatile uint32_t step_events_completed; // The number of step events executed in the current block
 
     #if ENABLED(BEZIER_JERK_CONTROL)
@@ -137,8 +137,8 @@ class Stepper {
       static hal_timer_t acc_step_rate; // needed for deceleration start point
     #endif
 
-    static volatile long endstops_trigsteps[XYZ];
-    static volatile long endstops_stepsTotal, endstops_stepsDone;
+    static volatile int32_t endstops_trigsteps[XYZ];
+    static volatile int32_t endstops_stepsTotal, endstops_stepsDone;
 
     //
     // Positions of stepper motors, in step units
@@ -154,7 +154,7 @@ class Stepper {
     // Mixing extruder mix counters
     //
     #if ENABLED(MIXING_EXTRUDER)
-      static long counter_m[MIXING_STEPPERS];
+      static int32_t counter_m[MIXING_STEPPERS];
       #define MIXING_STEPPERS_LOOP(VAR) \
         for (uint8_t VAR = 0; VAR < MIXING_STEPPERS; VAR++) \
           if (current_block->mix_event_count[VAR])
@@ -191,9 +191,32 @@ class Stepper {
     //
     // Set the current position in steps
     //
-    static void set_position(const long &a, const long &b, const long &c, const long &e);
-    static void set_position(const AxisEnum &a, const long &v);
-    static void set_e_position(const long &e);
+    static void _set_position(const int32_t &a, const int32_t &b, const int32_t &c, const int32_t &e);
+
+    FORCE_INLINE static void _set_position(const AxisEnum a, const int32_t &v) { count_position[a] = v; }
+
+    FORCE_INLINE static void set_position(const int32_t &a, const int32_t &b, const int32_t &c, const int32_t &e) {
+      synchronize();
+      CRITICAL_SECTION_START;
+      _set_position(a, b, c, e);
+      CRITICAL_SECTION_END;
+    }
+
+    static void set_position(const AxisEnum a, const int32_t &v) {
+      synchronize();
+      CRITICAL_SECTION_START;
+      count_position[a] = v;
+      CRITICAL_SECTION_END;
+    }
+
+    FORCE_INLINE static void _set_e_position(const int32_t &e) { count_position[E_AXIS] = e; }
+
+    static void set_e_position(const int32_t &e) {
+      synchronize();
+      CRITICAL_SECTION_START;
+      count_position[E_AXIS] = e;
+      CRITICAL_SECTION_END;
+    }
 
     //
     // Set direction bits for all steppers
@@ -203,7 +226,7 @@ class Stepper {
     //
     // Get the position of a stepper, in steps
     //
-    static long position(const AxisEnum axis);
+    static int32_t position(const AxisEnum axis);
 
     //
     // Report the positions of the steppers, in steps