The server side buffer shouldn't really be an arbitrary amount like 3 ticks - it should just be whatever is necessary to ensure that jitter doesn't mean you ‘miss’ an update. Under good network conditions and a system where clients send some information redundantly (to make up for potential packet loss or delay) you might not even need a whole tick for that. But it's best to measure with some real-world tests.
Similarly, the client-side interpolation buffer shouldn't need to be an arbitrary 100ms - it just needs to be long enough that you almost always have enough data to interpolate between, again with jitter taken into account. e.g. If you send at 30Hz, the client only needs a 33.4ms buffer in perfect network conditions to be sure of having 2 states to interpolate between. You don't have perfect conditions so 33.4 is too short. But a buffer of 100ms is preparing for at least 3 updates being lost or late, which is arguably too much. If you're losing that many packets, you're probably in bad network conditions and are going to lose the 4th one as well, so you're accepting a lot of latency for little real gain.
I'd probably start by dialing that back to 50ms, as well as ensuring you have a robust strategy for extrapolation when there isn't enough data, and a robust strategy for recovering from an extrapolated position to a ‘correctly-interpolated’ position (snapping instantly is fine in the short term). And, again, doing some real-world measurements to ssee whether this value needs adjusting. It can be adjusted at runtime on a per-player basis, as well.
It's worth noting that, in your original example, the player doesn't actually see the game state 300ms in the past. They see it 150ms in the past - 50ms of latency plus 100ms of buffer. Even if another player's information took an extra 150ms to get processed by the server, that information is not strictly ‘the game state’ until the server has processed it. Until then, it's merely that other player's prediction.
Typical human reaction times are well over 150ms and the buffers mentioned above can usually be reduced somewhat so it's not necessarily a problem, especially when lag compensation is used to resolve interactions. Racing games are a bit of an outlier as you don't want every player to see a world state that puts them in the lead, only to be disappointed at the finish line! So games like that will usually do more extrapolation to try and guess where the other entities will be. I've worked on games where different objects had different buffer lengths, depending on how acceptable extrapolation was for that object.