Server thinks I am spamming remote events when I am clearly not

Over the last couple months I had been receiving a lot of people telling me about an issue involving lag spikes. When looking into it it seems whenever an FPS unlocker is used, the entire game is rate limited,. even when remotes are being fired at an extremely slow pace. I have spent way to much time trying to figure out the issue with analyzing data and trying different solutions. Script performance is low, and the rate of remote events firing is less than 5/second out of EVERY remote in the game combined when rate limiting triggers. Additionally when I say rate limiting I mean the game will block ALL request made from the client to the server.

This issue started a few months ago where I use animation event markers to make right/left footstep sounds directly under a foot and fire a remote to the server to allow other players to hear that same sound, this would fire at a rate of about 1-2 per second at its fastest, but it triggered roblox’s rate limiting and continuously say in the server developer console ‘Player “EvilEyeRule” appears to be spamming remote events’ and makes the ping skyrocket until you stop moving. From this I disabled footsteps from replicating to other players all together and it seemed to resolve the issue… until recently. Now whenever anyone walks with an FPS unlocker enabled the lag will skyrocket, despite the remote events not firing. I even disabled EVERY SINGLE remote event in the game from firing and sure enough when I move around, the server will say I am spamming remote events.

This is to the point where the game can barely be played by anyone with an FPS higher than what roblox normally locks it to, especially as I am stumped as no remote events have to be firing, and no remotes are being fired at a rate that can even be considered fast. Script performance and script rates are not anywhere high, memory and networking are unchanged, everything else seems to be fine.

Here is me running around with FPS capped at 60, footstep sound replication disabled, and a remote event updating the direction my torso faces every 0.3 seconds with task.wait() in a while true do statement, the game works perfectly fine with no issue.

Now here is my game running with an uncapped FPS, no footstep sound running, and torsos updating every 0.3 seconds just like before.

As you can see the game will now think I am spamming remote events despite no change being made besides my frame rate

lastly here is me walking around with ABSOLUTELY no remote events being fired, and my FPS being uncapped, as you can see the game continues to think I am spamming remote events

Overall the issue is getting more obscure from what I can see, as now the game will see everyone with an increased FPS rate to be spamming remote events and stop all network connection to roblox until you stop moving, even though no remote event have to be firing now. The higher someones FPS is the more likely it is that the rate limiting will kick in with a low event firing count. I hope to be able to find some fix for this because it’s just painful for me to not be able to find any fix for this issue, and to not even be able to understand what is causing the issue. There is the possibility that this could be a roblox engine bug, but there is no way to tell if it is, nor can I post in that topic.

If you would like to see this problem for yourself you can try playing the game here and see if the issue comes up for you, remember the issue seems to only happen when an FPS unlocker is enabled Weapon_System - Roblox

If it is using RenderStepped it might be causing that issue, since RenderStepped depends on client FPS.

The system is composed of about six different RunService:BindToRenderStep() functions that manage a bunch of different aspects, that could be a possibility of what may happen, however no events fire inside these renderstep functions as they originate and run from user input or from a while do loop

By chance, are you repeating task.wait or renderstepped:Wait()?

the portion of the script runs as follows:

	task.spawn(function()
		while true do
			if Framework.Movement.Character.Waist and Framework.Movement.Character.Neck and Framework.Movement.Character.RShoulder and Framework.Movement.Character.LShoulder then
				local motors = {
					Neck = Framework.Movement.Character.Neck, 
					Waist = Framework.Movement.Character.Waist, 
					RightShoulder = Framework.Movement.Character.RShoulder, 
					LeftShoulder = Framework.Movement.Character.LShoulder
				}
				game.ReplicatedStorage.RemoteEvents.UpdateTorso:FireServer(motors, Framework.Movement.ReplicateAngles)
			end
			task.wait(0.3)
		end
	end)

It gets the Motor6Ds of the specified body parts, as well as a table of the angles those body parts should be set to, and ships them off to the server. This uses task.wait() to increment itself

Ah. I used a similar method for one of my systems, but it will put it in the main loop that handles it on the client and will compare the time with the last time it replicated. Does that solve the problem?

Additionally, you should check if the system is running twice, because that’s often the cause to this problem.

Just tried it with tick() to find the difference from when the event was last fired, it did not seem to change anything. I also tested for it possibly running twice, seems to only be running once as intended.

think you can provide a minimal repro file with all the functions that are firing on renderstepped and just keep the necessary yields and fireservers?

all anyone can do is suggest stuff, I think we both know the renderstepped is the rootcause of the issue but have you been able to figure it out? have you tried .stepped etc. yielding?

One thing that leads me away from the cause being renderstep is that I am able to disable/comment out all :FireServer() methods, and it will still say I am spamming remote events.

It is also kind of hard for me to make a reproduction file as this system has many module scripts that can total into thousands of lines of code and all rely on each other all the time, but I will see what I can do to make one.