The way ASIO works is by double buffering. While the sound card is playing a block of, say, 256 samples, the DAW is busy filling the other block of 256 samples. As long as the time to fill 256 samples is at least slightly less than the time to play 256 samples, you should have perfect playback, because the new block will be ready by the time the sound card needs it. And if it takes LONGER to fill 256 samples, than to play them, then nothing you do will work – you have too much processing, it won’t play in real time.
With 256 samples, and 48 kHz, you will need one buffer every 5.3 milliseconds. Let’s say that you have a pretty heavy mix, that takes 4 milliseconds to generate a single buffer – leaving 1.3 milliseconds of “free time” for each buffer. This will all work swimmingly, in theory.
Now, that’s the theory. On an actual computer, there are always random things that happen. Keyboard drivers might suddenly need to download new firmware, network cards may need to re-train their equalizers, graphics cards lose sync with the monitor, Chrome decides to phone home and ask about updates, and so on, and so forth. Any one of these events may be not that long – let’s say that the graphics driver decides to monopolize your computer for only 2 milliseconds.
Unfortunately, 2 milliseconds is longer time than the 1.3 milliseconds you have available in the example above, so that buffer won’t be produced in time, and you will hear a glitch.
ASIO guard works by adding a queue of buffers in front of the sound card. When the sound card is done with a buffer, it immediately takes another one out of the prepared queue, which only takes a fraction of a millisecond, so as long as the queue is not empty, there won’t be a glitch. If the queue is at least 3 buffers deep (about 16 ms) then this 2 ms delay caused by the graphics card (in this example) woudn’t be a problem, there would be enough “free space” to catch up again, and the sound card would never run behind on available buffers.
The drawback is that the queue adds latency. The buffers need to be produced ahead of time, enough to buffer against those drop-outs.
So, with ASIO guard on, you can generally reduce the size of your buffers a fair bit – the buffers only need to be big enough to compensate for hardware interrupt latency and high-priority thread scheduling to put in a buffer out of the waiting queue. The length of the ASIO guard queue then needs to be long enough to give enough slack based on how heavy your project is, compared to how frequently/long your computer will “do other things.” If you run at 4 ms time to generate a buffer, for a 5.3 ms buffer size, that gives you 1.3 ms of headroom per queued buffer. If the queue is 21.2 ms, that gives you 4 buffers of headroom, or about 4*1.3ms == 5.2 ms of additional glitch that can be assimilated.
But if the project runs at 98% load, then you only have 2% of 5.3 ms, or about 0.1 ms of slop per buffer. To absorb a 2 ms glitch, you’d need (2ms / 0.1ms) == 20 buffers of ASIO guard. So, the higher the interrupt latency in your system, the larger your ASIO buffer size needs to be. Meanwhile, the heavier your project is (in % of full CPU,) the longer the ASIO guard needs to be, with some kind of practical upper limit around 95% CPU load.