diff --git a/Marlin/Configuration_adv.h b/Marlin/Configuration_adv.h
index f750c42fac..a3cb9f0ea2 100644
--- a/Marlin/Configuration_adv.h
+++ b/Marlin/Configuration_adv.h
@@ -496,6 +496,26 @@
   #define BABYSTEP_MULTIPLICATOR 1 //faster movements
 #endif
 
+// Enabling ENSURE_SMOOTH_MOVES ensures your printer will never stutter (for example in circles with a short segments). That's done in two steps:
+// --1--
+// During short segments like in circles, the update of the LCD Display can take so long that the block buffer gets completely drained.
+// If that happens, the movement of the printer gets very jerky until a longer segment like a longer straight line allows the buffer
+// to be filled again. This small stops also effects print quality in a bad way.
+// Enable ENSURE_SMOOTH_MOVES to update the LCD only when there is enough time during a move to do so.
+// Note that this means the display will not show actual values during this time and your printer will also not react to buttons
+// pressed immediately, except ALWAYS_ALLOW_MENU is also enabled.
+// --2--
+// No block is allowed to take less time than MIN_BLOCK_TIME. That's the time it takes in the main loop to add a new block to the buffer, checking temps,
+// including all interruptions due to interrupts, but without LCD update. If we would allow shorter moves, the buffer would start continously draining.
+//#define ENSURE_SMOOTH_MOVES
+#if ENABLED(ENSURE_SMOOTH_MOVES)
+  //#define ALWAYS_ALLOW_MENU // If enabled, the menu will be always accessible.
+                              // WARNING: If the menu is entered or navigated during short moves, the printer will stutter like without ENSURE_SMOOTH_MOVES!
+  #define LCD_UPDATE_THRESHOLD 170 // Minimum duration in ms of the current segment to allow a LCD update.
+                                   // Default value is valid for graphical LCDs like the REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER.
+  #define MIN_BLOCK_TIME 6 // Minimum duration in ms a single block has to take. You shouldn't need to modify this.
+#endif
+
 // @section extruder
 
 // extruder advance constant (s2/mm3)
diff --git a/Marlin/planner.cpp b/Marlin/planner.cpp
index ab03d9fe3e..c9d681e9be 100644
--- a/Marlin/planner.cpp
+++ b/Marlin/planner.cpp
@@ -937,12 +937,24 @@ void Planner::_buffer_line(const float &a, const float &b, const float &c, const
       if (segment_time < min_segment_time) {
         // buffer is draining, add extra time.  The amount of time added increases if the buffer is still emptied more.
         inverse_mm_s = 1000000.0 / (segment_time + lround(2 * (min_segment_time - segment_time) / moves_queued));
-        #ifdef XY_FREQUENCY_LIMIT
+        #if defined(XY_FREQUENCY_LIMIT) || ENABLED(ENSURE_SMOOTH_MOVES)
           segment_time = lround(1000000.0 / inverse_mm_s);
         #endif
       }
     }
   #endif
+  
+  #if ENABLED(ENSURE_SMOOTH_MOVES)
+    #if DISABLED(SLOWDOWN)
+      unsigned long segment_time = lround(1000000.0 / inverse_mm_s);
+    #endif
+    if (segment_time < (MIN_BLOCK_TIME) * 1000UL) {
+      // buffer will be draining, set to MIN_BLOCK_TIME.
+      inverse_mm_s = 1000000.0 / (1000.0 * (MIN_BLOCK_TIME));
+      segment_time = (MIN_BLOCK_TIME) * 1000UL;
+    }
+    block->segment_time = segment_time;
+  #endif
 
   block->nominal_speed = block->millimeters * inverse_mm_s; // (mm/sec) Always > 0
   block->nominal_rate = ceil(block->step_event_count * inverse_mm_s); // (step/sec) Always > 0
diff --git a/Marlin/planner.h b/Marlin/planner.h
index 8b8d498658..8ec45f76ab 100644
--- a/Marlin/planner.h
+++ b/Marlin/planner.h
@@ -123,6 +123,10 @@ typedef struct {
   #if ENABLED(BARICUDA)
     uint32_t valve_pressure, e_to_p_pressure;
   #endif
+  
+  #if ENABLED(ENSURE_SMOOTH_MOVES)
+    uint32_t segment_time;
+  #endif
 
 } block_t;
 
@@ -366,6 +370,17 @@ class Planner {
         return NULL;
     }
 
+    #if ENABLED(ENSURE_SMOOTH_MOVES)
+      static bool long_move() {
+        if (blocks_queued()) {
+          block_t* block = &block_buffer[block_buffer_tail];
+          return (block->segment_time > (LCD_UPDATE_THRESHOLD * 1000UL));
+        }
+        else
+          return true;
+      }
+    #endif
+
     #if ENABLED(AUTOTEMP)
       static float autotemp_max;
       static float autotemp_min;
diff --git a/Marlin/ultralcd.cpp b/Marlin/ultralcd.cpp
index 2216a9f1cb..cd56f60794 100755
--- a/Marlin/ultralcd.cpp
+++ b/Marlin/ultralcd.cpp
@@ -2710,15 +2710,24 @@ void lcd_update() {
     // We arrive here every ~100ms when idling often enough.
     // Instead of tracking the changes simply redraw the Info Screen ~1 time a second.
     static int8_t lcd_status_update_delay = 1; // first update one loop delayed
-    if (
-      #if ENABLED(ULTIPANEL)
-        currentScreen == lcd_status_screen &&
-      #endif
-        !lcd_status_update_delay--) {
-      lcd_status_update_delay = 9;
-      lcdDrawUpdate = LCDVIEW_REDRAW_NOW;
-    }
+    #if ENABLED(ENSURE_SMOOTH_MOVES) && ENABLED(ALWAYS_ALLOW_MENU)
+      if (planner.long_move()) {
+    #endif
+        if (
+          #if ENABLED(ULTIPANEL)
+            currentScreen == lcd_status_screen &&
+          #endif
+            !lcd_status_update_delay--) {
+          lcd_status_update_delay = 9;
+          lcdDrawUpdate = LCDVIEW_REDRAW_NOW;
+        }
+    #if ENABLED(ENSURE_SMOOTH_MOVES) && ENABLED(ALWAYS_ALLOW_MENU)
+      }
+    #endif
 
+    #if ENABLED(ENSURE_SMOOTH_MOVES) && DISABLED(ALWAYS_ALLOW_MENU)
+      if (planner.long_move()) {
+    #endif
     if (lcdDrawUpdate) {
 
       switch (lcdDrawUpdate) {
@@ -2779,6 +2788,9 @@ void lcd_update() {
         break;
     }
 
+    #if ENABLED(ENSURE_SMOOTH_MOVES) && DISABLED(ALWAYS_ALLOW_MENU)
+      }
+    #endif
   }
 }