diff --git a/Manifest.toml b/Manifest.toml
index 64219c72c2d1ef26f8218a5503ef3c7b9e1c6fbd..d8b59bfd71247eca9ca9bd345466f4a20b59b520 100644
--- a/Manifest.toml
+++ b/Manifest.toml
@@ -2,7 +2,7 @@
 
 julia_version = "1.8.2"
 manifest_format = "2.0"
-project_hash = "d37bc0692e4cb75dce4365cae9dc31c02a907c73"
+project_hash = "2a3d26785ece5a51ad6d73d93147b49dbedd4551"
 
 [[deps.AbstractFFTs]]
 deps = ["ChainRulesCore", "LinearAlgebra"]
diff --git a/Project.toml b/Project.toml
index b8113f05e0b920a935d0d0e62c27979c43a3eef5..b262f0423e8bcf1ea002ce3523343c589fee53e1 100644
--- a/Project.toml
+++ b/Project.toml
@@ -13,6 +13,7 @@ LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
 Logging = "56ddb016-857b-54e1-b83d-db4d58db5568"
 Makie = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a"
 Meshes = "eacbb407-ea5a-433e-ab97-5258b1ca43fa"
+NearestNeighbors = "b8a86587-4115-5ab1-83bc-aa920d37bbce"
 Observables = "510215fc-4207-5dde-b226-833fc4488ee2"
 ObservationPolicies = "6317928a-6b1a-42e8-b853-b8e2fc3e9ca3"
 OrderedCollections = "bac558e1-5e72-5ebc-8fee-abe8a469f55d"
diff --git a/src/LarvaTagger.jl b/src/LarvaTagger.jl
index 2c17d668ec916ae681c920a6aaee17977e3c0cd6..58da163c87baf6ac5d216113117b1d22947a70c9 100644
--- a/src/LarvaTagger.jl
+++ b/src/LarvaTagger.jl
@@ -18,6 +18,7 @@ import Dates
 using OrderedCollections
 using Random
 using LinearAlgebra
+using NearestNeighbors
 
 export larvaviewer, larvaeditor
 
diff --git a/src/plots.jl b/src/plots.jl
index 7853f171bc182fa4126b6b240d531eba9f976141..5a28ee503244d57829ee605826fa1843335d5d37 100644
--- a/src/plots.jl
+++ b/src/plots.jl
@@ -118,6 +118,7 @@ struct SingleLarvaView
     usertags::Observable
     visible::Observable{Bool}
     path::Observable{PathOrOutline}
+    pathtree::Observable{<:NNTree}
     outline::Observable{PathOrOutline}
     outline_color::Observable{String}
     #
@@ -139,6 +140,7 @@ function SingleLarvaView(larvae::Vector{LarvaModel}, controller; editabletags::B
     usertags = Observable(larva.usertags)
     visible = Observable(false)
     path = Observable(larva.path)
+    pathtree = map(KDTree, path)
     shape_outline = Observable(outline(Makie.Point2f, state))
     shape_color = Observable(html_color(color))
 
@@ -207,7 +209,7 @@ function SingleLarvaView(larvae::Vector{LarvaModel}, controller; editabletags::B
     segment_visible = Observable(false)
 
     SingleLarvaView(controller, model, usertags, visible,
-                    path, shape_outline, shape_color,
+                    path, pathtree, shape_outline, shape_color,
                     segment, segment_color, segment_visible)
 end
 
@@ -218,10 +220,9 @@ norm2(p) = p[1]^2 + p[2]^2
 
 function pick_timestep(scene, larva)
     pos = mouseposition(scene)
-    dist2 = norm2(larva.path[], pos)
-    best = argmin(dist2)
+    best, dist = nn(larva.pathtree[], pos)
     timestep = larva.model[].alignedsteps[best]
-    return timestep, best, dist2[best]
+    return timestep, best, dist
 end
 
 function setinitialstep!(initialstep, larva)
@@ -241,13 +242,13 @@ function setinitialstep!(initialstep, larva)
 end
 
 function pick_timesegment(scene, larva, initialstep)
-    timestep, best, dist2 = pick_timestep(scene, larva)
+    timestep, best, dist = pick_timestep(scene, larva)
     path = larva.path[]
     if initialstep isa Ref
         initialstep = initialstep[]
     end
     segment = initialstep <= best ? path[initialstep:best] : path[best:initialstep]
-    return timestep, segment, dist2
+    return timestep, segment, dist
 end
 
 function assign_tag_to_segment!(larvaview, firststep)
@@ -359,7 +360,7 @@ function setmouseevents!(scene, larva::SingleLarvaView;
         return Consume(false)
     end
 
-    dodrag = newobservable(Cooldown(0.2), true)
+    dodrag = newobservable(Cooldown(0.1), true)
 
     Makie.onmouseleftdrag(mouseevents) do _
         if dragging[]
@@ -380,9 +381,9 @@ function setmouseevents!(scene, larva::SingleLarvaView;
         if b
             @info "Dragging"
             if iseditable(larva)
-                timestep, segment, dist2 = pick_timesegment(scene, larva, initialstep)
+                timestep, segment, dist = pick_timesegment(scene, larva, initialstep)
                 settimestep!(larva.controller, timestep)
-                if dist2 > (2reference_larva_size)^2
+                if dist > 2reference_larva_size
                     assignmentfailed!(larva.controller, "mouse pointer away")
                     stop()
                 else