On the Instance:Destroy() page, it says disconnects all connections and calls Destroy on all children. This function is the correct way to dispose of objects that are no longer required., So your issue seems strange, you can try manually disconnecting all the events though and test to see if it still lags, collect every connection in a table then disconnect them all at the end of a round.
I’m unsure if the problem is actually with the .Touched event itself or just it being mass fired when a lot of players touch a button, so I’ll provide solutions for both cases:
If the problem is with .Touched event being laggy then you could try switching to Region3, since your buttons use Hitbox parts you can use this module to do create a rotated Region3 from a part.
If the problem is with the connection then you could try Magnitude checking, so every RunService.Stepped you can store a table of magnitudes from each player to the current active button, whenever the Touched event is called it will set a variable to true, which will make the next RunService.Stepped loop check if the nearest player to the button is in correct range, activate the button functions and set that variable back to false.
I’m unsure if the last solution will work since I cannot test with 40 players.