Using 8 On/Off buttons to control 8 relays

And yet with all functions in loop(), the detect is not missed and you can't seem to get that, only guess at how to screw it up. Fine, ANYONE can do that!

All it takes to miss the transition is to block execution longer than the read period and even then history == 0 and history == 255 are the down and up pictures. Without blocking it is not hard to write void loop() that averages 20 micros. So for 20 loop() cycles, don't check seems likely?

As to all that not catching change detection if you miss it by 500 us, my reply to that: If your code is trying to detect change when it happens, why does it wait so long between checks?

I have older examples that are much closer on the detect and use 2 to 3 ms stability.. those are for close work.

What I have is "close enough, quick enough" that beats waiting 10 or 20 ms flat for only 2 bytes per button. I planned for button boxes from the start with less RAM and fewer service cycles to keep loop() fast and read and service 1 button per loop() and still handle 10x10 faster than wait for it debounce handles even 1.

If you don't like it, don't use it. It still works great with non-blocking code. One day I might update the timing method and then it will use fewer cycles every time.