Heartbeat causing overall lag on my game?

Hello, I have released a battlegrounds game 2 weeks ago and its averaging a decent amount of players (around 2-3k). The problem is that many people have been reporting high ping issues even in servers of their region, I think I know a solution to fix that but it is risky.

My game has many RunService.Heartbeat functions on server scripts running at the same time, for every character (16 max) and some extra server side code (5 more). That would be more than 20 Heartbeat functions running at the same time.

What I’m thinking is maybe to implement a global BindableEvent that gets fired everytime a Heartbeat passes? This will replicate the Heartbeat function but I am wondering is it’s going to be less permormant (meaning some code will lag by itself) than having 20 Heartbeat functions running at the same time.

As you can see, here is the Rate/s of all the scripts:


“MainScript” represents every player’s “main” script as I told before, and it has a really high rate as you can see.

So, is it viable to use a BindableEvent to replicate the Heartbeat function and will it have the same effect with less lag?

2 Likes

(What I meant with a BindableEvent that replicates the exact same function as Heartbeat)

RunService.Heartbeat:Connect(function(DeltaTime)
BindableEvent:Fire(DeltaTime)
end)

BindableEvent.Event:Connect(function(DeltaTime)
-- do stuff here without lagging the Heartbeat rate, but is it as permorfant as using multiple heartbeats?
end)

Do not make a bindable, it will error for being fired too fast, and will cause more lag. Try to connect multiple items to a single heartbeat connection, if you can try and remove as many connected to heartbeat where possible.

If any that are connected to heartbeat involve a lot of maths calculations and do not really involve Roblox APIs, they might benefit from being compiled natively.

Every loop code that run every frame such as RunService.Heartbeat, RunService.RenderStepped and while task.wait() do should be used very carefully and cause heavy performances issues on the client machine or the server.

A game shouldn’t have that much loops code overall, 3 or 4 loops should be the max, so you may have to review how your scripts work and find a more optimized way to do what you’re attempting to do.

May i know why you need that much loops and what do you do in them?

Really? Will it error for firing too fast? It is just one BindableEvent at the end that will connect to all MainScript’s.

And yes, nothing involves API’s or expensive math calculations.

You’d get an error something along the lines of BindableEvent exceeded maximum re-entry depth. Even if some of those connected functions don’t actually do much maths but are mostly maths, they may still benefit slightly from native compiling.

If you have ongoing, large tasks that are mostly seperate and don’t interact with the rest of your game that much (as in communicate and share resources with other scripts), you might want to look into Parallel Luau.

1 Like

So, every player has some values such as the time they are Attacking, being stunned, ragdolled, and with Heartbeat I lower them down by the deltaTime. Apart from that there are some hitbox checkers if the player is ever dashing forward, etc.

I have heard of :BindToRenderStep(), but I don’t know how using that may help or if it even will.

Thank you for the responses

BindToRenderStep just causes a function to be run every frame, basically. As for these values, are you lowering the value with in a script or an instance value each heartbeat? That’s going to be quite taxing on memory. If these are for things like displaying a cooldown, you might want to use a count-controlled iteration.

1 Like

Yeah, I was also thinking that for that function I may have a NumberValue placed in ServerStorage that updates every Heartbeat, and every MainScript will run NumberValue.Changed and the “DeltaTime” will be the difference between the last value to what it is now, thus reduce all those cooldowns by that amount.

Alright, do you really need to run 20 loops every frame?

Maybe you could just run a single while loop every 0.1s that handle all players at same time instead of the 16 differents loops that run every frame, it should already fix half of your server performance issues.

Also, heartbeat should be used only for physic simulations.

1 Like

Thanks. I’m going to try out Parallel programing.

1 Like

Well that’s my main point, its just that I don’t know how to properly do that. I want to turn the 20 heartbeat loops into a single one but as Koip said, there might be some issues such as BindableEvents not firing correctly, or stuff like that. Id rather have the game lag a little bit but with all the functions and timings working correctly.

Here’s some information that might help:

Parallel Luau works best on large tasks that run often, and that don’t interact with serial-running scripts in your game. Don’t forget, after using an actor, in order to run code under it in parallel, you must call task.desynchronize(), or :ConnectParallel() for connections. Some functions aren’t safe to be called in parallel, you’ll have to use task.synchronize() to make the run in serial, run them, and then switch back to parallel.

You can use a SharedTable to share information between actors, and use Actor:SendMessage(), and Actor:BindToMessage()/Actor:BindToMessageParallel() to run code in the actor based on that.

Parallel Luau | Documentation - Roblox Creator Hub
SharedTable | Documentation - Roblox Creator Hub
Actor | Documentation - Roblox Creator Hub

2 Likes