diff --git a/source/funkin/ui/debug/charting/ChartEditorHoldNoteSprite.hx b/source/funkin/ui/debug/charting/ChartEditorHoldNoteSprite.hx
index 6da27ef82..d64cc33a1 100644
--- a/source/funkin/ui/debug/charting/ChartEditorHoldNoteSprite.hx
+++ b/source/funkin/ui/debug/charting/ChartEditorHoldNoteSprite.hx
@@ -142,8 +142,9 @@ class ChartEditorHoldNoteSprite extends SustainTrail
     {
       // noteData.stepTime is a calculated value which accounts for BPM changes
       var stepTime:Float = this.noteData.stepTime;
-      var roundedStepTime:Float = Math.floor(stepTime + 0.01); // Add epsilon to fix rounding issues
-      this.y = roundedStepTime * ChartEditorState.GRID_SIZE;
+      // Add epsilon to fix rounding issues?
+      // var roundedStepTime:Float = Math.floor((stepTime + 0.01) / noteSnapRatio) * noteSnapRatio;
+      this.y = stepTime * ChartEditorState.GRID_SIZE;
     }
 
     this.x += ChartEditorState.GRID_SIZE / 2;
diff --git a/source/funkin/ui/debug/charting/ChartEditorState.hx b/source/funkin/ui/debug/charting/ChartEditorState.hx
index 6c7beb744..298725acd 100644
--- a/source/funkin/ui/debug/charting/ChartEditorState.hx
+++ b/source/funkin/ui/debug/charting/ChartEditorState.hx
@@ -1120,6 +1120,11 @@ class ChartEditorState extends HaxeUIState
    */
   var gridGhostNote:Null<ChartEditorNoteSprite> = null;
 
+  /**
+   * A sprite used to indicate the note that will be placed on click.
+   */
+  var gridGhostHoldNote:Null<ChartEditorHoldNoteSprite> = null;
+
   /**
    * A sprite used to indicate the event that will be placed on click.
    */
@@ -1293,6 +1298,13 @@ class ChartEditorState extends HaxeUIState
     add(gridGhostNote);
     gridGhostNote.zIndex = 11;
 
+    gridGhostHoldNote = new ChartEditorHoldNoteSprite(this);
+    gridGhostHoldNote.alpha = 0.6;
+    gridGhostHoldNote.noteData = new SongNoteData(0, 0, 0, "");
+    gridGhostHoldNote.visible = false;
+    add(gridGhostHoldNote);
+    gridGhostHoldNote.zIndex = 11;
+
     gridGhostEvent = new ChartEditorEventSprite(this);
     gridGhostEvent.alpha = 0.6;
     gridGhostEvent.eventData = new SongEventData(-1, '', {});
@@ -2265,6 +2277,8 @@ class ChartEditorState extends HaxeUIState
           }
           else
           {
+            // Clicking and dragging.
+
             // Scroll the screen if the mouse is above or below the grid.
             if (FlxG.mouse.screenY < MENU_BAR_HEIGHT)
             {
@@ -2392,15 +2406,17 @@ class ChartEditorState extends HaxeUIState
       {
         // Handle extending the note as you drag.
 
-        // TODO: This should be beat snapped?
         var dragLengthSteps:Float = Conductor.getTimeInSteps(cursorSnappedMs) - currentPlaceNoteData.stepTime;
+        var dragLengthMs:Float = dragLengthSteps * Conductor.stepLengthMs;
+        var dragLengthPixels:Float = dragLengthSteps * GRID_SIZE;
 
-        // Without this, the newly placed note feels too short compared to the user's input.
-        var INCREMENT:Float = 1.0;
-        // TODO: Make this not busted with BPM changes
-        var dragLengthMs:Float = Math.floor(dragLengthSteps + INCREMENT) * Conductor.stepLengthMs;
+        gridGhostHoldNote.visible = true;
+        gridGhostHoldNote.noteData = gridGhostNote.noteData;
+        gridGhostHoldNote.noteDirection = gridGhostNote.noteData.getDirection();
 
-        // TODO: Add and update some sort of preview?
+        gridGhostHoldNote.setHeightDirectly(dragLengthPixels);
+
+        gridGhostHoldNote.updateHoldNotePosition(renderedHoldNotes);
 
         if (FlxG.mouse.justReleased)
         {
@@ -2556,6 +2572,7 @@ class ChartEditorState extends HaxeUIState
           if (cursorColumn == eventColumn)
           {
             if (gridGhostNote != null) gridGhostNote.visible = false;
+            gridGhostHoldNote.visible = false;
 
             if (gridGhostEvent == null) throw "ERROR: Tried to handle cursor, but gridGhostEvent is null! Check ChartEditorState.buildGrid()";
 
@@ -2600,6 +2617,7 @@ class ChartEditorState extends HaxeUIState
         else
         {
           if (gridGhostNote != null) gridGhostNote.visible = false;
+          if (gridGhostHoldNote != null) gridGhostHoldNote.visible = false;
           if (gridGhostEvent != null) gridGhostEvent.visible = false;
           Cursor.cursorMode = Default;
         }
@@ -2608,6 +2626,7 @@ class ChartEditorState extends HaxeUIState
     else
     {
       if (gridGhostNote != null) gridGhostNote.visible = false;
+      if (gridGhostHoldNote != null) gridGhostHoldNote.visible = false;
       if (gridGhostEvent != null) gridGhostEvent.visible = false;
     }