Seeming pathfinding degradation on repeated use

I have a function for npcs that pathfinds them to a specific location and then back again. It works perfectly fine the first time it is called. If its called a second time, however, it slows WAY down. Npcs pathfind between each node slowly, then pause for an interval of time between them instead of moving smoothly. Any idea of why this might be and how to fix it?

Functions.PatrolToo = function(NPC,Location,ReturnToStart)
	local Halt = false
	local Origin = NPC.HumanoidRootPart.Position
	coroutine.wrap(function()
		while true do
			task.wait(0.3)
			local Check = Functions.CheckForPlayers(NPC)
			if Check ~= nil or Halt == true then
				Halt = true
				break
			end
		end
	end)()
	local path = PathfindingService:CreatePath({AgentRadius = 2.5})
	path:ComputeAsync(NPC.Torso.Position,Location)
	local waypoints = path:GetWaypoints()
	task.wait(0.2)
	for i, waypoint in pairs(waypoints) do
		if Halt == true then break end
		
		if waypoint.Action == Enum.PathWaypointAction.Jump then
			NPC.Humanoid:ChangeState(Enum.HumanoidStateType.Jumping)
		end
		NPC.Humanoid:MoveTo(waypoint.Position)
		NPC.Humanoid.MoveToFinished:Wait(2)
	end
	if ReturnToStart == true then
		for i = 1,5 do
			local P = NPC.Torso.Position
			local path2 = PathfindingService:CreatePath()
			path2:ComputeAsync(NPC.Torso.Position,Vector3.new(P.X+math.random(-25,25),P.Y,P.Z+math.random(-25,25)))
			local waypoints2 = path2:GetWaypoints()
			task.wait(0.2)
			for i, waypoint2 in pairs(waypoints2) do
				if Halt == true then break end

				if waypoint2.Action == Enum.PathWaypointAction.Jump then
					NPC.Humanoid:ChangeState(Enum.HumanoidStateType.Jumping)
				end
				NPC.Humanoid:MoveTo(waypoint2.Position)
				NPC.Humanoid.MoveToFinished:Wait(2)
			end
		end
		if Halt == false then
			local path2 = PathfindingService:CreatePath({AgentRadius = 2.5})
			path2:ComputeAsync(NPC.Torso.Position,Origin)
			local waypoints2 = path2:GetWaypoints()
			task.wait(0.2)
			for i, waypoint2 in pairs(waypoints2) do
				if Halt == true then break end

				if waypoint2.Action == Enum.PathWaypointAction.Jump then
					NPC.Humanoid:ChangeState(Enum.HumanoidStateType.Jumping)
				end
				NPC.Humanoid:MoveTo(waypoint2.Position)
				NPC.Humanoid.MoveToFinished:Wait(2)
			end
		end
	end
	return
end

(also the orginization is pretty bad sorry if that makes it hard to read)

Comment out your coroutine.wrap body and see if it runs better. My guess is depending on how frequently this gets called you’re throwing more and more loops to different threads, which’ll definitely eat away at your resources for sure.

I think rather a better approach would be to have one update function, which could get called by a RunService event instead.

e.g:

local function updateAI()
--//gets called every frame
end
game:GetService("RunService").Heartbeat:Connect(updateAI)

commenting out the entire detecting loop, coroutine included, doesn’t seem to make an impactful difference.

You also seem to be computing a lot of new path objects. Try caching one, and then when you want to recompute the path call the ComputeAsync method on the path object.