Why my Varnish hitrate is so low (around 30%)?

228 Views Asked by At

We are running Varnish 6 with Magento 2.4.5 and Nginx, and we have about 1000-1500 pages. The Varnish instance is configured with 2048m, but the majority of pages are not being cached.

We conducted cache warming, and we can clearly see that after 250-300 pages, Varnish no longer serves from the memory (HIT) and starts serving from the backend (MISSES). We looked into varnishstat and there is where we see about 30% of hitrate. But I could not locate the "nuke" counter that seems useful.

Whats the best process to ensure that Varnish has enough capacity? Whats the best process to investigate further why so many pages are not being cached?

1

There are 1 best solutions below

0
Thijs Feryn On

Step 1: check cache storage

As mentioned in https://www.varnish-software.com/developers/tutorials/troubleshooting-varnish/#not-enough-caching-storage, you can run the following varnishstat command to inspect your cache storage:

sudo varnishstat -f "SMA.*.g_*" -1

Here's some example output:

SMA.s0.g_alloc                  40      .   Allocations outstanding
SMA.s0.g_bytes            41445760      .   Bytes outstanding
SMA.s0.g_space            63411840      .   Bytes available
SMA.Transient.g_alloc           23      .   Allocations outstanding
SMA.Transient.g_bytes         7176      .   Bytes outstanding
SMA.Transient.g_space            0      .   Bytes available

The g_bytes & g_space counters will give you the current cache storage usage and available space.

If g_space is too low, it could indicate that objects needed to be nuked to clear space.

If sudo varnishstat -f "MAIN.n_lru_nuked" increases, that also confirms the suspicion.

Step 2: miss or pass?

It is important to figure out whether you're dealing with actual cache misses or cache bypassing.

  • A cache miss happens when a cacheable object is no longer stored in the cache
  • A cache bypass takes places when content is not deemed cacheable

https://www.varnish-software.com/developers/tutorials/troubleshooting-varnish/#varnish-is-not-caching will show you the reasons why a cache bypass may happen.

By running the following command, you'll see some metrics about the total hits, misses, hitpass, hitmiss & passes:

sudo varnishstat -f "MAIN.cache_*" -f "MAIN.s_pass"
  • MAIN.cache_hit is obviously the number of cache hits
  • MAIN.cache_hit_grace is a stale object that still has grace time left and that will be served while an async backend fetch takes place
  • MAIN.cache_hitpass will usually not happen and is triggered by old behavior. It refers to content that is deemed uncacheable after the fetch took place. It results in a pass for the next request.
  • MAIN.cache_hitmiss refers to content that is deemed uncacheable after the fetch took place. It results in a miss for the next request.
  • MAIN.cache_miss refers to missing or expired and out-of-grace content
  • MAIN.s_pass refers to requests that bypass the cache because they were deemed uncacheable at the request side.

Step 3: listing the top cache bypasses

If cache bypasses are the main reason why your hit rate is low, run the following command to list the top URLs that result in a cache pass:

sudo varnishtop -i ReqUrl -q "VCL_call eq 'PASS'"

Step 4: listing the top cache misses

If you assume that the hit rate is low because of actual cache misses, you can run the following command to list the top URLs that cause cache misses:

sudo varnishtop -i ReqUrl -q "VCL_call eq 'MISS'"

Step 5: inspect individual requests

At this point you should know if the majority of your cache misses are true misses or cache bypasses.

  1. If the problem is a cache storage problem, you just add storage
  2. If the problem is that real misses occur, try increasing your TTL
  3. If the problem is cache bypasses, you should run in-depth varnishlog commands for those requests

In case of option 3, you should dig deeper and fully inspect an individual request that came up in your other logs.

As mentioned in https://www.varnish-software.com/developers/tutorials/troubleshooting-varnish/#vsl-commands, you can then run the following command to inspect:

sudo varnishlog -i ReqUrl -i ReqMethod -i ReqProtocol -I ReqHeader:Host \
    -I ReqHeader:Cookie -I ReqHeader:Authorization \ 
    -i VCL_call -i VCL_return \
    -q "ReqUrl eq '/'"

This command assumes that / is the URL of the request you're inspecting. If your looking for another URL, just adjust that value in the -q filter.

If you want more verbosity, just run the following one:

sudo varnishlog -q "ReqUrl eq '/'"

This will output all the tags. But again, be mindful of the URL filter.

Please read https://www.varnish-software.com/developers/tutorials/troubleshooting-varnish/#varnish-is-not-caching to see if the reasons for cache bypasses match the ones listed.

It could also be related to specific VCL code you wrote that is causing this behavior.