Problem with gun firerate syncing between client and server

Hello, I am using this script on the client:

while MouseHeld do
	shotsFired += 1
	print('Fired', shotsFired)
	Events.Shoot:FireServer(Tool,shotsFired)
	task.wait(cooldown)
end

And this script on the server that I tried to iterations of and both sometimes fail,
Iteration 1:

local lastFired = {}
local cooldown = .1

Players.PlayerAdded:Connect(function(Player)
	lastFired[Player] = false
end)

Events.Shoot.OnServerEvent:Connect(function(Player, Tool, shotsFired)
	if lastFired[Player] == false then
		lastFired[Player] = true
		print(shotsFired)
		task.wait(cooldown - RunService.Heartbeat:Wait())
		lastFired[Player] = false
	end
end)

Iteration 2:

Players.PlayerAdded:Connect(function(Player)
	lastFired[Player] = 0
end)

Events.Shoot.OnServerEvent:Connect(function(Player, Tool, shotsFired)
	if os.clock() - lastFired[Player] > cooldown then
		print(shotsFired)
		lastFired[Player] = os.clock()
	end
end)

Both of which create the same output, sometimes in desync between server and client (visible when the client prints twice before the server manages)
Iteration 1 Output:

Iteration 2 Output:

I know it should be possible because games do it, right?..