How to Reduce Physics Lag for raycasting Vehicle?

You can write your topic however you want, but you need to answer these questions:

  1. What do you want to achieve? Keep it simple and clear!
    i want to make my raycasting vehicle system be optimized
  2. What is the issue? Include screenshots / videos if possible!
    but, updating the wheels to follow the raycasting’s position and rotation with delta keeps lagging my game! i even tried grabbing the roblox jeep model and it still lags. i pinpointed where the lag is coming from and it is caused by me updating the wheels
  3. What solutions have you tried so far? Did you look for solutions on the Developer Hub?
    i tried using renderstepped:Wait but that wouldnt work, its not meant for physics. Stepped and hearbeat works but again, very laggy. i also couldnt find any post on the devforum that has the same problem for me.

The serverscript car chassis script

local Car = script.Parent
local Chassis = Car.Chassis
local Config = Car.Stats
local seat = Car.VehicleSeat


local WPos = {
	FL = Vector3.new(3.5, 0, 6),
	FR = Vector3.new(-3.5, 0, 6),
	RL = Vector3.new(3.5, 0, -5.5),
	RR = Vector3.new(-3.5, 0, -5.5),
}

local SpringLenghtMem = {}

for i,v in pairs(WPos)  do
	SpringLenghtMem[i] = 0.5
end

--Body
local WheelFolder = Car.Wheels
local FLW = WheelFolder.FL
local FRW = WheelFolder.FR
local RLW = WheelFolder.RL
local RRW = WheelFolder.RR

local Body = Car.Body
local RearLights = Body.RearLights


--Sounds
local EnterSound = Chassis.DoorOpen
local CloseSound = Chassis.DoorClose
local StartSound = Chassis.Enter
local StopSound = Chassis.Exit
local RunningSound = Chassis.Running
local DriftSound = Chassis.Drift
local BoostSound = Chassis.Boost
local HornSound = Chassis.Horn
--SETTINGS
local MaxLength = Config.MaxLength.Value
local WRadius = Config.WheelRadius.Value
local Stiffness = Config.Stiffness.Value
local Damp = Config.Damper.Value
local WheelFriction = Config.Friction
local MaxSpeed = Config.MaxSpeed.Value

local LS = script.CarChassis
local Plr 
local CanDrive = false

local DriftEvent = script.Drift
local BoostEvent = script.Boost
local HornEvent = script.Horn

local lowPlaybackSpeed = 0.5
local highPlaybackSpeed = 1.2
local transitionTime = 0.7

local isTransitioning = false
local currentPlaybackSpeed = lowPlaybackSpeed

local function AddWelds()
	for i, pos in pairs(WPos) do
		local weld = Instance.new("Weld",WheelFolder[i])
		weld.Part0 = Car.PrimaryPart
		weld.Part1 = WheelFolder[i]
		weld.C0 = CFrame.new(WPos[i])
		if pos.x>0 then weld.C0 = weld.C0 * CFrame.Angles(0,math.rad(180),0)end

	end
end

local WheelRotations = {}


AddWelds()

local function StartVehicle()
	EnterSound:Play()
	wait(1.1)
	CloseSound:Play()
	wait(0.4)
	StartSound:Play()
	wait(2.6)
	RunningSound:Play()
	CanDrive = true
end


Car.VehicleSeat:GetPropertyChangedSignal("Occupant"):Connect(function()
	if Car.VehicleSeat.Occupant and game.Players:FindFirstChild(Car.VehicleSeat.Occupant.Parent.Name) then
		local PlayerChar = Car.VehicleSeat.Occupant.Parent
		local player = game.Players:GetPlayerFromCharacter(PlayerChar)
		Plr = player
		local ClonedLS = LS:Clone()
		local CarValue = ClonedLS.Car
		CarValue.Value = Car
		ClonedLS.Parent = player.PlayerGui
		StartVehicle()
		Chassis:SetNetworkOwner(player)
		ClonedLS.Enabled = true
	elseif not Car.VehicleSeat.Occupant and Plr then
		local player = Plr
		local ClonedLS = player.PlayerGui:FindFirstChild(LS.Name)
		StopSound:Play()
		RunningSound:Stop()
		CanDrive = false
		if ClonedLS then
			ClonedLS:Destroy()
		end
		Chassis:SetNetworkOwner(nil)
	end
end)

seat:GetPropertyChangedSignal("Throttle"):Connect(function()
	if seat.Throttle == 1 then
		RearLights.BrickColor = BrickColor.new("Bright red")
		RearLights.Material = Enum.Material.SmoothPlastic
	elseif seat.Throttle == 0 then
		RearLights.BrickColor = BrickColor.new("Bright red")
		RearLights.Material = Enum.Material.Neon
	elseif seat.Throttle == -1 then
		RearLights.Material = Enum.Material.Neon
		RearLights.BrickColor = BrickColor.new("White")
	end
end)

DriftEvent.OnServerEvent:Connect(function(player, car, ltrail, rtrail, lsmoke, rsmoke, drifting, toggle)
	if car == Car then
		if toggle then
			ltrail.Enabled = true
			rtrail.Enabled = true
			lsmoke.Enabled = true
			rsmoke.Enabled = true
			drifting.Value = true
			DriftSound:Play()
			WheelFriction.Value = 1
		else
			ltrail.Enabled = false
			rtrail.Enabled = false
			lsmoke.Enabled = false
			rsmoke.Enabled = false
			drifting.Value = false
			DriftSound:Stop()
			WheelFriction.Value = 5
		end
	end
end)


BoostEvent.OnServerEvent:Connect(function(player, car, lboost, rboost, toggle)
	if car == Car then
		if toggle then
			lboost.Enabled = true
			rboost.Enabled = true
			BoostSound:Play()
		else
			lboost.Enabled = false
			rboost.Enabled = false
			BoostSound:Stop()
		end
	end
end)


HornEvent.OnServerEvent:Connect(function(player, car, toggle)
	if car == Car then
		if toggle then
			HornSound:Play()
		else
			HornSound:Stop()
		end
	end
end)
Chassis:SetNetworkOwner(nil)





local function updateSoundPlaybackSpeed()
	if seat.Occupant and CanDrive then
		if seat.Throttle == 1 and not isTransitioning then
			isTransitioning = true

			local numSteps = transitionTime / 0.1
			local stepValue = (highPlaybackSpeed - lowPlaybackSpeed) / numSteps

			for i = 1, numSteps do
				currentPlaybackSpeed += stepValue
				RunningSound.PlaybackSpeed = currentPlaybackSpeed
				wait(0.1)
			end

			RunningSound.PlaybackSpeed = highPlaybackSpeed

			isTransitioning = false
		elseif seat.Throttle ~= 1 then
			RunningSound.PlaybackSpeed = lowPlaybackSpeed
			currentPlaybackSpeed = lowPlaybackSpeed
		end

		if RunningSound.PlaybackSpeed > 0 then
			if not RunningSound.IsPlaying then
				RunningSound:Play()
			end
		else
			if RunningSound.IsPlaying then
				RunningSound:Stop()
			end
		end
	end
end


seat:GetPropertyChangedSignal("Throttle"):Connect(updateSoundPlaybackSpeed)

local function updateWheelPositions(delta)
	for i, v in pairs(WPos) do
		local carCFrame = Car.Chassis.CFrame
		local rayOrigin = Chassis.CFrame:ToWorldSpace(CFrame.new(v.x, v.y - Config.WheelRadius.Value, v.z)).p
		local rayDirection = -Chassis.CFrame.UpVector * Config.MaxLength.Value
		local rayparams = RaycastParams.new()
		rayparams.FilterDescendantsInstances = {Car}
		local raycast = workspace:Raycast(rayOrigin, rayDirection, rayparams)

		if raycast then

			local LocalVelocity = CFrame.lookAt(Vector3.zero,carCFrame.LookVector,carCFrame.UpVector):ToObjectSpace(CFrame.new(Chassis:GetVelocityAtPosition(raycast.Position)))

			if not WheelRotations[Car] then
				WheelRotations[Car] = {}
				WheelRotations[Car].STEER = 0
				for i,v in pairs(WPos)do WheelRotations[Car][i] = 0.5 end
			end
			WheelRotations[Car][i] += LocalVelocity.z/56

			local weld = Car.Wheels[i].Weld

			local weldInitPos = CFrame.new(v - Vector3.new(0,(rayOrigin - raycast.Position).magnitude,0))
			if string.sub(i,1,1)=='F' then--if front
				
				WheelRotations[Car].STEER = WheelRotations[Car].STEER + (Car["VehicleSeat"].SteerFloat - WheelRotations[Car].STEER)*delta*6
				weld.C0 = weldInitPos * CFrame.new(0,0.8,0) * CFrame.Angles(0,-math.rad(WheelRotations[Car].STEER * Config.SteerAngle.Value),0)
			else
				weld.C0 = weldInitPos * CFrame.new(0,0.8,0)
			end
			if v.x>0 then 
				weld.C0 = weld.C0 * CFrame.Angles(0,math.rad(180),0)
				weld.C0 = weld.C0 * CFrame.Angles(-WheelRotations[Car][i],0,0)
			else
				weld.C0 = weld.C0 * CFrame.Angles(WheelRotations[Car][i],0,0)
			end



		end
	end
end



spawn(function()
	while true do
		local delta = game["Run Service"].Heartbeat:Wait()
		if Chassis:GetNetworkOwner() == nil and CanDrive then
			
			
			for wheelname, origpos in pairs(WPos) do
				local carCFRAME = Chassis.CFrame
				local rayorig = carCFRAME:ToWorldSpace(CFrame.new(origpos)).Position
				local raydirect = -carCFRAME.UpVector * (MaxLength + WRadius)
				local rayParams = RaycastParams.new()
				rayParams.FilterDescendantsInstances = {Car}
				local ray = workspace:Raycast(rayorig, raydirect, rayParams)

				if ray then
					local raydistance = (rayorig - ray.Position).Magnitude
					local SpringLength = math.clamp(raydistance - WRadius, 0, MaxLength)
					local StiffnessForce = Stiffness * (MaxLength - SpringLength)
					local DampForce = Damp * (( SpringLenghtMem[wheelname] - SpringLength) / delta)
					local SuspensionForceVec3 = carCFRAME.UpVector * (StiffnessForce + DampForce)

					local RotationsOnlyWheelDirCFrame = CFrame.lookAt(Vector3.zero, carCFRAME.LookVector, carCFRAME.UpVector)
					local LocalVelo = RotationsOnlyWheelDirCFrame:ToObjectSpace(CFrame.new(Chassis:GetVelocityAtPosition(ray.Position)))

					local XForce = carCFRAME.RightVector * -LocalVelo.X * WheelFriction.Value
					SpringLenghtMem[wheelname] = SpringLength
					Chassis:ApplyImpulseAtPosition(SuspensionForceVec3 + XForce, ray.Position)

				end


			end
		end
updateWheelPositions(delta)
			

		
		end

end)

and yes, i did try make the wheel updating position locally instead, it just made it laggier.
Please do not ask people to write entire scripts or design entire systems for you. If you can’t answer the three questions above, you should probably pick a different category.