Search code examples
asp.netcachingiisiis-8.5

IIS won't cache large (76MB) file


I can't seem to get IIS on Windows 2012 R2 to cache a large .exe file. That is, when I constantly request the file I see the file being read constantly in in Resource Monitor, and running

netsh http show cachestate

does not show the file cached.

I think I've configured the system to cache .exe files for the folder in the kernel and to not have a max file size. The total cache size limit is 0, which I understand will make the system use up to half of all memory. The server has 6 GB of RAM, with lots of it free.

That is, in the Output Cache settings for the root of the web server:

  • Maximum cached response size (in bytes) = 0 (also reflected in applicationHost.config's maxResponseSize value)
  • Cache size limit (in MB) is not checked (also in applicationHost.config maxCacheSize = 0)
  • Enable cache and Enable kernel cache are checked (both set to true in applicationHost.config

I'm serving the file from a virtual folder configured to be a 4.0 ASP.NET application. 4.6.2 is installed. The virtual folder points to a UNC share that is on the same system. (I know I could point to the local file system; I'm simulating hosting files that are on another system.)

The web.config file:

<?xml version="1.0" encoding="utf-8"?>
  <configuration>
  <system.webServer>
    <handlers>
      <clear />
      <add name="StaticFile" path="*" verb="*" modules="StaticFileModule,DefaultDocumentModule,DirectoryListingModule" resourceType="Either" requireAccess="Read" />
    </handlers>
    <caching>
      <profiles>
        <add extension=".txt" policy="CacheUntilChange" kernelCachePolicy="CacheUntilChange" />
        <add extension=".exe" policy="CacheUntilChange" kernelCachePolicy="CacheUntilChange" />
      </profiles>
    </caching>
  </system.webServer>
</configuration>

It will cache small .txt and .exe files (about 20 bytes each).

What am I missing that's preventing IIS from caching the large file?


Solution

  • As per the registry(UriMaxUriBytes ) which controls size of file which can be cached on the kernel is 16 MB.Also there are many scenarios in which http.sys will not cache the content.Please check this KB article instances-in-which-http-sys-does-not-cache-content

    To get it working - create the following DWORD values under the following registry key:

    HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\HTTP\Parameters

    • UriMaxUriBytes -UriMaxUriBytes 262144 (bytes) 4096(4k) – 16777216(16MB) bytes Any response that is greater than this value is not cached in the kernel response cache. 1 3

    • UriScavengerPeriod -Determines the frequency of the cache scavenger. Any response or fragment that has not been accessed in the number of seconds equal to UriScavengerPeriod is flushed.

    You can also tweak UriMaxCacheMegabyteCount (specifies the maximum memory that is available to the kernel-mode cache.) which is by default zero for http.sys to decide but you can give a high value

    so you can

    1. set HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\HTTP\Parameters\UriMaxUriBytes to 16777216
    2. check from non UNC directory where a file less than 16 MB
    3. No authentication for this request or No dynamic compression enabled for this mime type

    more details can be found on this msdn and server performance tuning

    Hope this helps!