Realistically, you shouldn’t use while wait in the first place. If there are event-based methods for your specific system then you should look to use those instead. Polling should be the absolute last option you look to for resolving a problem, not the first.
Additionally, RunService signals are not expensive… they’re signals. You can connect to these signals to allow something to happen every time that point in a frame is reached. What’s really expensive when you use RunService signals is what kind of code you’re running in them.
-
RenderStepped should never be used except for modifying computationally inexpensive properties such as CFrame or transparency or for things that should be set before the frame renders. You will scarcely need things to update before a frame renders.
-
Stepped should only be used in cases where you need a higher run priority (e.g. animations, tweening) or for continuous systems that should be modified before physics simulation occurs.
-
Heartbeat for everything else. Good for all cases.
For the example in the OP, there are already four native ways to check for Humanoid deaths:
- Humanoid.Died (canonical)
- Humanoid.HealthChanged
- Humanoid:GetPropertyChangedSignal(“Health”)
- Humanoid.Changed (checking for Health as the passed argument)
There’s no reason why you should be polling to check if the Humanoid dies. It’s not a good example to use because it doesn’t help show why your module is helpful, given that there are better ways to do what you’re suggesting. You should instead come up with an example where polling is necessary to accomplish your system and where event-based solutions, whether natively or handcrafted, do not work. An example is fetching data from a website that is subject to change during a session’s run.