Cloudflare Favicon Optimization Guide

Master favicon delivery through Cloudflare CDN: cache rules, Page Rules, Workers, purging, edge caching, compression, and global performance optimization.

Cloudflare Benefits for Favicons

Faster Delivery
Edge caching worldwide

DDoS Protection
Secure favicon delivery

Reduced Load
Less origin requests

Auto Minify
Optimized delivery

Basic Cloudflare Setup

Enable Cloudflare for Your Site

Step 1: Add Site to Cloudflare

  1. Sign up at cloudflare.com
  2. Click "Add Site" and enter your domain
  3. Choose Free or Pro plan
  4. Update nameservers at your domain registrar
  5. Wait for DNS propagation (usually 5-30 minutes)

Step 2: Verify Favicon Proxying

Ensure favicon is proxied through Cloudflare (orange cloud icon):

  • Go to DNS tab
  • Verify root domain (@) or www is proxied (orange cloud)
  • Favicon will be served through Cloudflare's edge network
Verification: Check HTTP headers for cf-ray and cf-cache-status to confirm Cloudflare is active.

Cache Rules Configuration

Optimize Favicon Caching

Default Cloudflare Caching

By default, Cloudflare caches static files including:

  • .ico files (favicons)
  • .png, .jpg, .svg images
  • Default cache TTL: 4 hours

Create Custom Cache Rule (Recommended)

Navigate to: Caching ? Cache Rules ? Create Rule

Rule Name: Favicon Long Cache

When incoming requests match:

  • Field: URI Path
  • Operator: contains
  • Value: favicon

OR

  • Field: File Extension
  • Operator: equals
  • Value: ico

Then:

  • Setting: Edge Cache TTL
  • Value: 1 year (31536000 seconds)
  • Setting: Browser Cache TTL
  • Value: 1 year

Multiple File Types Rule

When incoming requests match:
  File Extension equals "ico"
  OR File Extension equals "png" AND URI Path contains "favicon"
  OR URI Path contains "apple-touch-icon"
  OR URI Path contains "android-chrome"

Then:
  Cache Level: Standard
  Edge Cache TTL: 1 year
  Browser Cache TTL: 1 year
Note: Cache Rules are available on Free plan. Page Rules (legacy) require Pro+ plan for custom cache TTL.

Page Rules (Legacy Method)

Alternative Cache Configuration

Create Page Rule for Favicons

Navigate to: Rules ? Page Rules ? Create Page Rule

If the URL matches:

*yourdomain.com/*favicon*

Then the settings are:

  • Cache Level: Cache Everything
  • Edge Cache TTL: 1 year
  • Browser Cache TTL: 1 year

Example Page Rules

URL Pattern Settings Purpose
*example.com/favicon.ico Cache Everything, 1 year TTL Main favicon
*example.com/*favicon* Cache Everything, 1 year TTL All favicon variants
*example.com/*.ico Cache Everything, 1 year TTL All ICO files
Limitation: Free plan includes 3 Page Rules. Pro plan offers 20. Consider using Cache Rules instead (unlimited on all plans).

Cache Purging & Updates

Clear Cached Favicons

When to Purge Cache

  • After uploading new favicon
  • When favicon not updating for users
  • After rebranding or logo change
  • Testing new favicon versions

Method 1: Purge by URL (Recommended)

Navigate to: Caching ? Configuration ? Purge Cache ? Custom Purge

Enter URLs to purge:

https://yourdomain.com/favicon.ico
https://yourdomain.com/favicon-16x16.png
https://yourdomain.com/favicon-32x32.png
https://yourdomain.com/apple-touch-icon.png

Method 2: Purge Everything

Navigate to: Caching ? Configuration ? Purge Cache ? Purge Everything

Warning: This purges ALL cached files, not just favicons. May temporarily increase origin server load.

Method 3: API Purge (Automated)

curl -X POST "https://api.cloudflare.com/client/v4/zones/{zone_id}/purge_cache" \
  -H "Authorization: Bearer {api_token}" \
  -H "Content-Type: application/json" \
  --data '{
    "files": [
      "https://yourdomain.com/favicon.ico",
      "https://yourdomain.com/favicon-16x16.png",
      "https://yourdomain.com/favicon-32x32.png",
      "https://yourdomain.com/favicon-96x96.png",
      "https://yourdomain.com/favicon-512x512.png"
    ]
  }'
Tip: Use URL purge for favicons only, preserving cache for other assets.

Compression & Optimization

Enable Cloudflare Optimizations

Enable Brotli Compression

Navigate to: Speed ? Optimization ? Content Optimization

  • Enable Brotli compression (better than GZIP)
  • Applies to SVG favicons and web manifests
  • ICO files typically don't benefit from compression

Auto Minify

Navigate to: Speed ? Optimization ? Auto Minify

  • Enable SVG minification (if using SVG favicons)
  • Reduces file size by removing whitespace and comments

Polish (Pro Plan+)

Navigate to: Speed ? Optimization ? Polish

  • Lossy: Compresses PNG favicons (may reduce quality)
  • Lossless: Compresses without quality loss
  • Automatic WebP conversion for supported browsers
Consideration: Polish may alter favicon appearance. Test thoroughly before enabling for icon files.

Cloudflare Workers for Favicons

Advanced: Serve Favicon from Worker

Why Use Workers?

  • Serve favicon from edge without origin request
  • Dynamic favicon based on subdomain or path
  • A/B testing different favicons
  • Redirect old favicon paths

Example: Serve Cached Favicon

addEventListener('fetch', event => {
  event.respondWith(handleRequest(event.request))
})

async function handleRequest(request) {
  const url = new URL(request.url)
  
  // Intercept favicon requests
  if (url.pathname === '/favicon.ico') {
    // Check cache first
    const cache = caches.default
    let response = await cache.match(request)
    
    if (!response) {
      // Fetch from origin if not cached
      response = await fetch(request)
      
      // Clone and cache for 1 year
      const cacheResponse = response.clone()
      const headers = new Headers(cacheResponse.headers)
      headers.set('Cache-Control', 'public, max-age=31536000')
      
      const cachedResponse = new Response(cacheResponse.body, {
        status: cacheResponse.status,
        statusText: cacheResponse.statusText,
        headers: headers
      })
      
      event.waitUntil(cache.put(request, cachedResponse))
    }
    
    return response
  }
  
  // Pass through other requests
  return fetch(request)
}

Example: Dynamic Favicon by Subdomain

addEventListener('fetch', event => {
  event.respondWith(handleRequest(event.request))
})

async function handleRequest(request) {
  const url = new URL(request.url)
  
  if (url.pathname === '/favicon.ico') {
    // Get subdomain
    const hostname = url.hostname
    const subdomain = hostname.split('.')[0]
    
    // Serve different favicon per subdomain
    const faviconMap = {
      'app': 'https://cdn.example.com/app-favicon.ico',
      'blog': 'https://cdn.example.com/blog-favicon.ico',
      'shop': 'https://cdn.example.com/shop-favicon.ico'
    }
    
    const faviconUrl = faviconMap[subdomain] || '/favicon.ico'
    
    return fetch(faviconUrl, {
      cf: {
        cacheTtl: 31536000,
        cacheEverything: true
      }
    })
  }
  
  return fetch(request)
}

Monitor Favicon Performance

Cloudflare Analytics

Check Cache Performance

Navigate to: Analytics & Logs ? Traffic

  • Cached Requests: Should be high for favicons
  • Uncached Requests: First request or after purge
  • Bandwidth Saved: Reduced origin load

HTTP Status Codes

cf-cache-status Meaning Action
HIT Served from Cloudflare cache ? Perfect
MISS Not in cache, fetched from origin Normal for first request
EXPIRED Cache expired, revalidating Increase TTL
BYPASS Not cacheable (no-cache header) Fix origin headers
DYNAMIC Treated as dynamic content Add Cache Rule

Check Headers with curl

curl -I https://yoursite.com/favicon.ico

# Look for these headers:
# cf-cache-status: HIT
# cf-ray: 7a1b2c3d4e5f6g7h-ORD
# cache-control: public, max-age=31536000
# age: 12345

Cloudflare Favicon Best Practices

? Recommendations

  • Use Cache Rules (not Page Rules) for better control
  • Set Edge Cache TTL to 1 year for favicons
  • Enable Brotli compression for SVG files
  • Purge by URL when updating favicon
  • Monitor cf-cache-status header
  • Enable orange cloud (proxy) for domain
  • Use Workers for advanced favicon logic
  • Test cache after purge to verify updates

? Common Mistakes

  • Not enabling proxy (gray cloud icon)
  • Setting Cache TTL too short (<1 day)
  • Using "Purge Everything" for small updates
  • Forgetting to purge after favicon update
  • Not checking cf-cache-status header
  • Blocking favicon in WAF rules
  • Not testing across different edge locations
  • Ignoring origin server cache headers

Troubleshooting

Solutions:
  • Create Cache Rule to force caching
  • Check origin server doesn't send Cache-Control: no-cache
  • Verify .ico extension is in default cacheable list
  • Enable "Cache Everything" in Page Rule or Cache Rule
  • Check WAF rules aren't blocking caching

Fixes:
  • Purge specific favicon URLs from Cloudflare cache
  • Wait 5-10 minutes for purge to propagate globally
  • Clear browser cache (Ctrl+Shift+R)
  • Test with curl -I to see cache headers
  • Verify origin file was actually updated
  • Add version query string: ?v=2

Causes & Solutions:
  • Origin server is offline ? check server status
  • Firewall blocking Cloudflare IPs ? whitelist Cloudflare
  • Incorrect DNS A record ? verify points to origin IP
  • SSL/TLS mismatch ? check SSL mode (Full or Flexible)

Generate CDN-Optimized Favicons

Create favicon packages ready for Cloudflare edge caching

Generate Favicons

Related Articles

An unhandled error has occurred. Reload 🗙