I think coroutine is more flexible, while task.spawn() its easier to use at least for me.
The RunService step its great too cause fires faster and it has different moments when it fires, like before rendering, before physics, after etc, and it actually has a stop, just connecting the RunService step, store it into a variable, then use the variable to disconnect it RSconnection:Disconnect()
Honestly I never created a latency reader system before, maybe someone could throw some light into this topic. I would do it by using the RunService step, kinda makes sense to me.
Oh but I forgot, it should be 1 per second, that would require reading delta time inside the RunService.
So… idk which one would be better for that task xD