Hello everyone, I could really use some help if you could spare some of your time.
During testing my game had average data ping problems, and I found out it was because of me sending a huge quest table through to update their quest avaliablity depending on levels etc and so I split the table into different chunks, hoping to lessen the load, and it did. This improved lag spikes.
However, the AVG ISR Pkt/s, is constantly high which is causing high ping and I don’t know exactly what that’s caused by. Could someone tell me what it probably is? Maybe memory leaks, I’m not entirely sure, I need some advice!
I would be grateful for any information, thank you!
Splitting the table into chunks is why your spikes went away, and it’s also why the sustained packet rate went up. Those two numbers measure different things: payload size per send, versus how many sends happen per second. One FireClient with a 40 KB quest table is one packet — a big one, which is what a spike looks like. The same table in 20 chunks is 20 packets. You traded a spike for a floor.
So before you go looking for a memory leak, check the rate first. It’s easy to separate:
local Stats = game:GetService("Stats")
game:GetService("RunService").Heartbeat:Connect(function()
print(Stats.DataSendKbps, Stats.DataReceiveKbps)
end)
If throughput is low but the packet count is high, it’s call frequency, not data volume, and chunking made it worse rather than better.
The thing that points at a specific culprit: does the rate stay high when the players are standing still and nobody has opened the quest menu? If it does, something is firing on a timer or a Heartbeat rather than on player action — and that’s a much smaller set of code to search than “the whole game”. A while true do ... task.wait() end loop that re-sends state every frame or every second is the usual answer, and it survives code review easily because each individual send is tiny.
Two things I’d change in the quest system specifically:
Send deltas, not the table. The client already knows the quest list after the first sync. Level-ups only change availability for a handful of quests, so send the ones that changed. That’s usually a 100x reduction in both size and frequency, and it removes the reason to chunk at all.
If you must send the whole thing, send it once, unchunked, and rate-limit it. A single 40 KB send on join costs you one spike at a moment the player is already loading, which is the cheapest possible time to pay for it.
Also worth checking: FireAllClients inside a loop over Players:GetPlayers() is the same call as FireAllClients once, except N times over. And Attribute or property writes on replicated instances generate traffic too, so a script updating an Attribute every frame shows up here and won’t appear anywhere in your remote code.
On the memory-leak question — that’s a separate measurement and it won’t show up in packet rate. Stats:GetTotalMemoryUsageMb() sampled over ten minutes of idle play tells you whether you have one; a flat line means you don’t, and you can stop worrying about it and go back to the send rate.
ISR is incoming server replication. It is a category for all engine level replication, e.g. creating a part on the server will temporarily spike ISR as the server has to tell clients the part now exists.
It is pretty high under the server authoritive model if you happen to be using that. With server auth the server has to replicate every physics tick all simulated parts so the client can check if it needs to rollback. This is a known issue and roblox is working on lowering it.
If you are client authoritative the server is repeatedly doing something that is replicating to the client. I can’t tell you what that is, I will say though parenting instances to the camera on the server makes them not replicate so if you need to do whatever is causing the ISR but don’t want to replicate it that’s a fix.
Finally test in live servers if you aren’t already. When I test my game in studio it spikes between 0 kb/s receive and like 75. On real servers it is consistent around 10 kb/s. Studio isn’t accurate at all for networking unfortunately