How to properly handle refreshing status effects

To give an example of what I mean, the first way I would handle this is like this:

     player:SetAttribute("onFire", true)
     task.delay(3, function()
         player:SetAttribute("onFire", false)

Now the problem with this is if this function runs twice before the task.delay finishes, it will set onFire to false before the second timer is up.

A solution to this I found was to use BoolValues and insert them into the player, then check if they have one of these boolvalues on them. The problem with this method is it fills up the player/character with boolvalues which just feels wrong. Is there a more elegant solution to this problem or is this the best way?