SharePoint / Guide 9
BLOB cache: why and how
Serve images, scripts, styles and video from web server disk instead of SQL, and let browsers cache them.
The BLOB cache is one of the cheapest performance wins in SharePoint Server, and one of the most often left switched off. It's a disk-based cache on each web server that keeps copies of static files (images, style sheets, scripts, video) so they don't have to be read from the SQL content database on every request.
It applies to SharePoint Server 2010, 2013, 2016, 2019 and Subscription Edition. It isn't available in SharePoint Foundation, and it doesn't exist in SharePoint Online (see the last section for the equivalent).
What it does
Without the BLOB cache, every image, .css and .js file on a page is a separate trip from the web server to SQL Server to fetch the file from the content database. A single intranet home page can easily make 30 to 60 of these requests.
With the BLOB cache on, the first request for a file reads it from SQL and saves a copy on the web server's local disk. Every later request is served straight from that disk. The cache also:
- Sends browser caching headers (
Cache-Controlwith amax-age), so users' browsers stop asking for the same logo and style sheet on every page. - Supports byte-range requests for video and audio, so users can jump around in a video without downloading it from the start.
- Still checks SharePoint permissions before serving a file, so it doesn't bypass security.
Benefits
- Less load on SQL Server. Static files are often the majority of requests on a portal. Taking them off SQL frees it for the queries that actually need it.
- Faster pages. Local disk is faster than a network round trip to SQL, and browser caching removes many requests entirely on repeat visits.
- Better scaling. Each web server you add brings its own cache, so adding web servers scales static content without adding SQL load.
- Smoother video. Byte-range support makes embedded video usable without a separate media server.
When it's worth it
It helps most on:
- Intranet portals and publishing sites with images, branding, and custom CSS/JS
- Anonymous internet-facing sites built on SharePoint
- Any site where users watch video stored in SharePoint libraries
It helps less on team sites where most traffic is opening and saving Office documents, because those file types aren't cached by default and shouldn't be. There's rarely a reason not to turn it on, though: it's cheap, and it only affects the file types you list.
Plan before you enable it
- Pick a dedicated drive. Put the cache on a data drive such as
D:\BlobCache, not the system drive. If the cache fills the drive, it shouldn't take the operating system down with it. - Size it.
maxSizeis in GB and applies per web application on each server. The default of 10 GB is fine for most portals. Make sure the drive has room for the cache of every web application you enable, plus headroom. - Choose how long browsers keep files.
max-ageis in seconds. 86400 (24 hours) is a sensible default. Longer values mean fewer requests but slower pickup of changed files (see "Common problems" below). - Enable it on every web server. Every server that serves user traffic needs the same setting, or users get different performance depending on which server the load balancer picks.
- Exclude the folder from antivirus scanning. Microsoft recommends excluding SharePoint's cache folders; real-time scanning of the BLOB cache slows every cached request.
The web.config setting
The BLOB cache is controlled by one element in each web application's web.config:
<BlobCache location="C:\BlobCache\15"
path="\.(gif|jpg|jpeg|jpe|jfif|bmp|dib|tif|tiff|themedbmp|themedcss|themedgif|themedjpg|themedpng|ico|png|wdp|hdp|css|js|asf|avi|flv|m4v|mov|mp3|mp4|mpeg|mpg|rm|rmvb|wma|wmv|ogg|ogv|oga|webm|xap)$"
maxSize="10"
enabled="false" />
| Attribute | What it means |
|---|---|
enabled |
true turns the cache on. It's false by default. |
location |
Folder on each web server where cached files are stored. |
path |
A regular expression listing the file extensions to cache. |
maxSize |
Maximum cache size in GB, per web application, per server. |
max-age |
Optional. Seconds that browsers may keep a file before asking again. |
You can add extensions to path, such as svg, woff and woff2 for modern branding. Don't add Office document types (docx, xlsx and so on); they're edited constantly and are better served directly.
Option 1: enable it with PowerShell (recommended)
Editing web.config by hand on every server is where BLOB cache setups go wrong: one server gets missed, a typo breaks a site, or a new server joins the farm without the setting. The better way is SPWebConfigModification, which stores the change in the farm configuration and writes it to web.config on every web server, including servers you add later, and for every zone of the web application.
Set-SPBlobCache.ps1 wraps this up:
# See the current setting on this server (read-only)
.\Set-SPBlobCache.ps1 -WebApplication https://sharepoint.ravindran.in
# Turn it on for every server in the farm
.\Set-SPBlobCache.ps1 -WebApplication https://sharepoint.ravindran.in -Enable -Location D:\BlobCache -MaxSizeGB 10 -MaxAgeSeconds 86400 -WhatIf
.\Set-SPBlobCache.ps1 -WebApplication https://sharepoint.ravindran.in -Enable -Location D:\BlobCache -MaxSizeGB 10 -MaxAgeSeconds 86400
The core of what it does:
$wa = Get-SPWebApplication https://sharepoint.ravindran.in
$mod = New-Object Microsoft.SharePoint.Administration.SPWebConfigModification
$mod.Path = 'configuration/SharePoint/BlobCache'
$mod.Name = 'enabled'
$mod.Value = 'true'
$mod.Owner = 'BlobCacheSettings'
$mod.Type = [Microsoft.SharePoint.Administration.SPWebConfigModification+SPWebConfigModificationType]::EnsureAttribute
$wa.WebConfigModifications.Add($mod)
$wa.Update()
$wa.Parent.ApplyWebConfigModifications()
The change is pushed by a timer job, so give it a minute. The SharePoint Timer Service must be running on every server. Changing web.config recycles the web application's application pool, so users may see one slow page load; do it outside peak hours.
Option 2: edit web.config by hand
If you can't use PowerShell, repeat these steps on every web server, for every zone of the web application:
- In IIS Manager, right-click the web application's site and choose Explore to find its folder (usually under
C:\inetpub\wwwroot\wss\VirtualDirectories\). - Make a copy of
web.configfirst. - Open
web.configin a text editor and find the<BlobCacheelement. - Set
location,maxSizeandenabled="true", and optionally addmax-age="86400". - Save. IIS recycles the application pool automatically.
Keep in mind that a manual edit can be overwritten when SharePoint reapplies its own web.config changes, and a new server won't have it. That's why option 1 is preferred.
Check that it's working
- Cache status: run
.\Set-SPBlobCache.ps1 -WebApplication <url>on each web server. It reads that server'sweb.configfor every zone and shows the cache folder size. - The cache folder: browse a few pages with images, then look in the cache location. Folders and files appear as the cache fills.
- Browser caching: open the browser developer tools (F12), go to the Network tab, reload a page and click an image. The response should include a
Cache-Controlheader whosemax-agematches your setting. From PowerShell:
powershell
(Invoke-WebRequest -Uri 'https://sharepoint.ravindran.in/SiteAssets/logo.png' -UseDefaultCredentials).Headers['Cache-Control']
- Performance counters: Performance Monitor has a SharePoint Disk-Based Cache category, with counters for the cache hit ratio and cache compactions. A good hit ratio means it's working. Frequent compactions mean the cache is too small, so increase
maxSize.
Flush the cache
If cached files are stale or corrupt, flush the cache for a web application on all its servers:
.\Set-SPBlobCache.ps1 -WebApplication https://sharepoint.ravindran.in -Flush
Which runs:
[void][System.Reflection.Assembly]::LoadWithPartialName('Microsoft.SharePoint.Publishing')
[Microsoft.SharePoint.Publishing.PublishingCache]::FlushBlobCache((Get-SPWebApplication https://sharepoint.ravindran.in))
Common problems
| Symptom | Likely cause | Fix |
|---|---|---|
| Updated image or CSS still shows the old version | Browsers are honouring max-age |
Wait for it to expire, or give updated branding files a new name (for example logo-v2.png). Lower max-age if files change often. |
| Old file still served to everyone | Stale cache entry | Flush the cache |
| Cache folder stays empty | Not enabled on this server, or the app pool account can't write to the folder | Check with -Status on that server; give the app pool account (or WSS_WPG) Modify rights on the folder |
| Some files never cache | Extension not in path, or the file is a draft |
Add the extension; only published (major) versions are cached |
| Drive fills up | maxSize too large for the drive, or several web applications share it |
Lower maxSize, or move the cache to a bigger drive |
| Performance varies by server | Cache enabled on some servers only | Use SPWebConfigModification (option 1) so every server matches |
The SharePoint Online equivalent
SharePoint Online has no BLOB cache setting; Microsoft runs the servers. The equivalent is the Microsoft 365 content delivery network (CDN), which serves static assets such as images, scripts and style sheets from locations close to your users. You turn it on with the SPO module, for example:
Set-SPOTenantCdnEnabled -CdnType Public -Enable $true
Get-SPOTenantCdnOrigins -CdnType Public
Check Microsoft's current CDN documentation before enabling it, and think carefully about what goes into a public CDN origin: anything in it can be fetched without signing in.