This is a XY problem since your real issue is the time synchronization issue. Why did you end up with that?
I would say, the problem is not only bruteforce (you additionally detect TOTP bruteforcing, right?), but also reuse. You want a small enough value to prevent repeats. Watching you log in would allow me to do that during the next 15 minutes, although it could be argued that 30 seconds might have been enough. You probably don't want to make it even smaller than those 30 seconds, since you need some time for people to manually retype them, plus all the time synchronization issues that might arise.
I would favor the second option, but what confuses me is how you need both past and future timeslots (note: 15 + 1 + 29 = 45, not 30). The RFC already mentions, and it is recommended that you do, adapt the calculation to each device drift. This should (a) allow you to avoid many of these errors and (b) if you know that 1 minute ago, the user provided the code for "2 minutes ago" (as seen from the server clock), you only check codes after that, i.e. you shouldn't allow a code from 5 minutes ago since they showed their clock is already ahead of that.
And obviously, it is paramount that all your verifier servers have their timedate correctly kept synchronized (NTP). :)