Skip to content

HTTP Cache

Bifrost includes a built-in HTTP cache inspired by steamcache/lancache. It can cache HTTP responses for game downloads, software updates, and other large file transfers, significantly reducing bandwidth usage on repeated downloads.

The cache system:

  • Intercepts plain HTTP GET requests for configured domains
  • Stores responses in memory and/or disk storage
  • Serves cached content for subsequent requests
  • Supports HTTP Range requests for resumable downloads
  • Includes built-in presets for popular game CDNs
graph LR
Client[Game Client] -->|HTTP GET| Bifrost[Bifrost Proxy]
Bifrost -->|Cache Miss| Origin[Origin CDN]
Origin -->|Response| Bifrost
Bifrost -->|Store| Cache[(Cache Storage)]
Cache -->|Cache Hit| Bifrost
Bifrost -->|Response| Client
cache:
enabled: true
default_ttl: "30d"
max_file_size: "50GB"
storage:
type: memory # memory, disk, or tiered
memory:
max_size: "2GB"
max_entries: 50000
evict_policy: lru
presets:
- steam
- epic

Fast in-memory storage with LRU eviction:

cache:
storage:
type: memory
memory:
max_size: "2GB" # Maximum memory usage
max_entries: 50000 # Maximum number of entries
evict_policy: lru # lru, lfu, or fifo

File-based storage for large cache sizes:

cache:
storage:
type: disk
disk:
path: "/var/cache/bifrost"
max_size: "500GB"
cleanup_interval: "1h"

Combines memory and disk storage. Small files go to memory for fast access, large files go to disk:

cache:
storage:
type: tiered
tiered:
memory_threshold: "10MB" # Files <= 10MB go to memory
memory:
max_size: "2GB"
max_entries: 50000
evict_policy: lru
disk:
path: "/var/cache/bifrost"
max_size: "500GB"
cleanup_interval: "1h"
FieldTypeDefaultDescription
cache.enabledboolfalseEnable/disable caching
cache.default_ttlduration30dDefault time-to-live for cached entries
cache.max_file_sizesize50GBMaximum size of a single cached file
cache.storage.typestringtieredStorage type: memory, disk, or tiered

Bifrost includes pre-configured presets for popular game CDNs and software update services:

PresetDescriptionDomains
steamSteam game downloads*.steamcontent.com, content*.steampowered.com
originEA Origin/EA Apporigin-a.akamaihd.net, *.cdn.ea.com
epicEpic Games Store*.epicgames.com, epicgames-download1.akamaized.net
battlenetBlizzard Battle.net*.blizzard.com, *.battle.net
windowsWindows Update*.windowsupdate.com, *.download.microsoft.com
playstationPlayStation Network*.playstation.net, *.dl.playstation.net
xboxXbox Live*.xboxlive.com, assets*.xboxlive.com
nintendoNintendo eShop*.nintendo.net, *.cdn.nintendo.net
ubisoftUbisoft Connect*.ubi.com, *.ubisoft.com
riotLeague of Legends, Valorant*.riotgames.com, lol.dyn.riotcdn.net
applemacOS/iOS updatesswcdn.apple.com, updates.cdn-apple.com
googleGoogle Play, Androiddl.google.com, *.gvt1.com
linuxLinux package reposarchive.ubuntu.com, *.debian.org
cache:
enabled: true
presets:
- steam
- origin
- epic
- battlenet
- windows

Create custom caching rules for any domain:

cache:
rules:
# Cache a custom CDN
- name: my-cdn
domains:
- "cdn.example.com"
- "*.mycdn.net"
enabled: true
ttl: "7d"
priority: 50
ignore_query: true
content_types:
- "application/octet-stream"
- "application/zip"
# General HTTP caching (respects Cache-Control)
- name: general-http
domains:
- "*"
enabled: false # Disabled by default
ttl: "1d"
priority: 1
respect_cache_control: true
FieldTypeDefaultDescription
namestringrequiredUnique rule identifier
domains[]stringrequiredDomain patterns to match
enabledbooltrueEnable/disable this rule
ttlduration30dTime-to-live for cached entries
priorityint0Higher priority rules are evaluated first
ignore_queryboolfalseIgnore query string in cache key
content_types[]string[]Only cache specific content types (empty = all)
respect_cache_controlboolfalseHonor Cache-Control headers from origin
methods[]string["GET"]HTTP methods to cache
max_sizesize0Maximum file size to cache (0 = unlimited)

Domain patterns support wildcards:

  • example.com - Exact match
  • *.example.com - Matches any subdomain
  • cdn*.example.com - Matches cdn1.example.com, cdn-west.example.com, etc.
  • * - Matches all domains

The cache provides management endpoints:

Terminal window
curl http://localhost:7082/api/v1/cache/stats

Response:

{
"enabled": true,
"hit_rate": 0.85,
"total_requests": 12450,
"cache_hits": 10582,
"cache_misses": 1868,
"memory": {
"entries": 4521,
"size_bytes": 1073741824,
"max_size_bytes": 2147483648
},
"disk": {
"entries": 892,
"size_bytes": 107374182400,
"max_size_bytes": 536870912000
}
}
Terminal window
curl "http://localhost:7082/api/v1/cache/entries?domain=*.steamcontent.com&limit=10"
Terminal window
curl -X DELETE "http://localhost:7082/api/v1/cache/entries?confirm=true"
Terminal window
curl -X DELETE "http://localhost:7082/api/v1/cache/domain/steamcontent.com"
Terminal window
curl http://localhost:7082/api/v1/cache/rules
Terminal window
curl http://localhost:7082/api/v1/cache/presets

The cache exports metrics:

MetricTypeDescription
bifrost_cache_hits_totalcounterTotal cache hits by domain
bifrost_cache_misses_totalcounterTotal cache misses by domain and reason
bifrost_cache_bytes_served_totalcounterBytes served from cache vs origin
bifrost_cache_storage_size_bytesgaugeCurrent storage size by tier
bifrost_cache_storage_entriesgaugeCurrent entry count by tier
bifrost_cache_evictions_totalcounterEvictions by tier and reason
bifrost_cache_operation_duration_secondshistogramCache operation latency

The cache fully supports HTTP Range requests for resumable downloads:

Terminal window
# Resume download from byte 1000
curl -H "Range: bytes=1000-" http://cdn.example.com/file.bin -x http://localhost:7080

The cache will serve partial content (206 Partial Content) from the cached file.

For optimal caching of game downloads:

  1. DNS Override: Configure your router/DNS to redirect CDN domains to your Bifrost server
  2. Or Use as Proxy: Configure game clients to use Bifrost as their HTTP proxy
Use CaseRecommended Storage
Home/Small OfficeMemory (2-8GB) + Disk (100-500GB)
LAN PartyTiered with large disk (1-2TB)
Gaming CafeTiered with SSD (fast) + HDD (capacity)
cache:
storage:
type: tiered
tiered:
memory_threshold: "50MB" # Increase for more memory caching
memory:
max_size: "8GB" # More memory = more cache hits
evict_policy: lru # LRU is generally best
disk:
path: "/var/cache/bifrost"
max_size: "1TB"
cleanup_interval: "6h" # Less frequent cleanup for stability
  1. Verify cache is enabled: curl http://localhost:7082/api/v1/cache/stats
  2. Check if domain matches a preset or rule
  3. Verify traffic is HTTP (not HTTPS) - caching only works for plain HTTP
  4. Check logs for cache hit/miss messages
  • Ensure the correct presets are enabled for your use case
  • Check if CDN domains have changed (some CDNs rotate domains)
  • Verify disk space is available
  • Configure max_size to limit disk usage
  • Reduce cleanup_interval for more frequent cleanup
  • Consider using tiered storage with smaller disk allocation

Complete configuration for caching game downloads at a LAN party:

server:
http:
listen: ":7080"
cache:
enabled: true
default_ttl: "30d"
storage:
type: tiered
tiered:
memory_threshold: "100MB"
memory:
max_size: "8GB"
max_entries: 100000
evict_policy: lru
disk:
path: "/mnt/cache/bifrost"
max_size: "2TB"
cleanup_interval: "12h"
presets:
- steam
- origin
- epic
- battlenet
- riot
metrics:
enabled: true
listen: ":7090"
logging:
level: info
format: json