So you want to use RunService.Heartbeat in Roblox

Most beginners just slap something into Heartbeat and move on, and it works fine until it doesn't. I spent three weeks debugging a movement system that stuttered on high-ping clients before I actually understood what the event does under the hood. Let me save you that time. Heartbeat is a RunService event that fires once per frame after the physics step has already completed. That order matters more than people realize. Most games use RenderStepped for visual interpolation because it fires after the renderer updates, but physics-based logic belongs in Heartbeat. If you put player input or collision responses in RenderStepped, you'll notice the client predicting ahead of the server and everything looks slightly off. I learned that the hard way on a racing game I made where cars would occasionally tunnel through walls on slow connections. Switching the vehicle movement from RenderStepped to Heartbeat fixed the tunneling because the physics step was now running first every frame.

Understanding Roblox Heartbeat in practice

Here is what the basic setup looks like, stripped of whatever tutorial boilerplate you have probably seen a hundred times. Connection template: local RunService = game:GetService("RunService")
RunService.Heartbeat:Connect(function(dt)
  -- dt is the time since the last frame in seconds
end)

The dt parameter is not always consistent. On a good machine it will be close to 0.016 for sixty FPS, but if the client drops to thirty frames or the server stutters, dt can jump to 0.03 or higher. That is why you multiply movement values by dt instead of adding flat amounts. A common mistake I see all the time is code that adds 10 units per frame regardless of delta time, which makes movement speed depend entirely on framerate. That is wrong and it shows. I ran into a specific problem a while back where Heartbeat was firing but player movement felt sluggish on lower-end devices. The issue was not the connection itself. The script was inside a LocalScript that was also running a heavy loop that created parts every frame, and the server was sending too many updates. I isolated the movement logic into its own LocalScript, disabled the part creation entirely, and used TweenService for the visual effects instead of manual frame updates. Movement became smooth again. If your game is doing anything heavy each frame, separating concerns is usually the fix, not optimizing the Heartbeat callback itself. Another thing nobody mentions is that Heartbeat does not run while the game is paused. If you are using it for a countdown timer or a UI animation and the game state pauses, that code simply stops. You need to account for that, especially in menu-heavy games where the experience frequently enters and exits pause states. I built a loading screen timer once that skipped forward unpredictably because I did not check whether the game was paused. The fix was straightforward: wrap the logic in a check for RunService:IsStudio() and handle the pause state explicitly in your manager script.

Get the Full Details

THE DOC IS IN! 🩺 Roblox Heartbeat Hospital 🏥 - YouTube
THE DOC IS IN! 🩺 Roblox Heartbeat Hospital 🏥 - YouTube

When to use Heartbeat versus other events

Use Heartbeat for physics-adjacent logic that should happen after simulation steps. Use RenderStepped when you need to match the visual frame exactly, like camera smoothing or particle alignment. Use Stepped when your logic must run before physics calculates collisions. Mixing these up is the most common cause of jitter I have seen in community projects. For simple projects, you might not need any of this. A basic obby or menu game runs fine with a SpawnLocation and some ClickDetectors. Heartbeat becomes relevant when you start building custom movement systems, vehicle controllers, or anything that needs frame-accurate timing. If your game is just players clicking buttons and spawning parts, you can probably skip it entirely and save yourself the debugging effort. If you want a reference implementation, there are several open-source movement frameworks on the Roblox Developer Hub that use Heartbeat correctly. The Roblox documentation page for RunService has a complete example under the Heartbeat section, and it is more useful than most of the third-party tutorials floating around. Start with that before downloading anything from random places.