Server Configuration for AssetBundle Streaming in VR Games

Our video game development company runs independent projects, jointly creates games with the client and provides additional operational services. Expertise of our team allows us to cover all gaming platforms and develop an amazing product that matches the customer’s vision and players preferences.

From immersive apps to game worlds and 3D scenes

Our dedicated team for VR/AR/MR development, Unity production and 3D modeling & animation — with its own case studies and capability decks.

Visit the dedicated studio
Showing 1 of 1All 242 services
Server Configuration for AssetBundle Streaming in VR Games
Medium
~3-5 days
Frequently Asked Questions

Our competencies

What are the stages of Game Development?

Latest works

  • image_games_mortal_motors_495_0.webp
    Game development for Mortal Motors
    1388
  • image_games_a_turnbased_strategy_game_set_in_a_fantasy_setting_with_fire_and_sword_603_0.webp
    A turn-based strategy game set in a fantasy setting, With Fire and Sword
    926
  • image_games_second_team_604_0.webp
    Game development for the company Second term
    544
  • image_games_phoenix_ii_606_0.webp
    3D animation - teaser for the game Phoenix 2.
    591

Why Asset Streaming Bottlenecks Are on the Server, Not the Build

The APK size of a VR game with full content easily exceeds 2 GB—the limit for Quest Store and close to the limit for Google Play. Asset streaming solves this: only critical startup resources go into the build, the rest loads on demand. But "load on the fly" and "load fast and reliably" are different tasks, and the latter depends entirely on a properly configured server. Our experience shows: even with excellent client code, incorrect HTTP headers kill download performance.

What the Server Needs for Proper AssetBundle Streaming

An AssetBundle is not just a file over HTTP. It has several properties that affect server requirements.

  • Range requests are mandatory. UnityWebRequest.GetAssetBundle() with caching uses the HTTP Range header to check whether a fragment is already downloaded or needs to be resumed. If the server responds to Range: bytes=0-1023 with a full file instead of 206 Partial Content, Unity cache breaks—every launch redownloads the entire bundle. Nginx supports Range by default, but some CDN configurations disable it.
  • ETag / Last-Modified for cache validation. Unity AssetBundle Cache checks the version via CacheControlParams or hash. If the server does not provide ETag or Last-Modified, Unity cannot determine if the bundle changed—either it re-downloads everything every time or uses an outdated version. Configuring ETag in Nginx: etag on;—one line, but often forgotten.
  • GZIP/Brotli only for textual resources. AssetBundle in LZ4 format (optimal for real-time loading) should not be additionally compressed at the HTTP level—only wasted CPU cycles on decompression. In Nginx: gzip_types must explicitly exclude application/octet-stream for bundles.
  • CORS for WebGL. If VR content runs via WebXR in a browser—the server must send proper CORS headers: Access-Control-Allow-Origin, Access-Control-Expose-Headers: Content-Length (needed for progress bar during loading).

Why Proper Server Configuration Saves Up to 70% Traffic

With correct caching and versioning, the client downloads only changed bundles—traffic volume is reduced by 40–70% depending on update frequency. We use the AssetBundle Manifest scheme: the manifest loads without cache, while all bundles load with max-age=31536000. When content updates, the hash in the path changes, and the CDN serves a new version. This eliminates re-downloading unchanged data.

Server Architecture for Asset Streaming

Typical scheme: Origin server (storage of masters, version management) + CDN (distribution, edge cache).

For the origin, we use Nginx or Caddy. Caddy is more attractive for small teams: automatic HTTPS via Let's Encrypt, configuration in a single Caddyfile, correct headers out of the box.

Asset URL structure includes a version: /assets/v{hash}/{bundleName}. When content updates, the hash in the path changes—CDN does not serve cached data, the client gets a new bundle. This is more reliable than cache-busting via query string (?v=123), which some CDNs ignore.

For CDN serving a global VR audience, we recommend Cloudflare R2 + Cloudflare CDN (free egress) or AWS S3 + CloudFront. Key CloudFront settings: Cache-Control: max-age=31536000, immutable for versioned bundles, Cache-Control: no-cache for the manifest file.

The AssetBundle Manifest is a separate lightweight file (~10 KB) containing a list of all bundles with hashes and dependencies. The client loads it on startup, compares with the local cache, and downloads only changed bundles. Content updates without reinstalling the app—by modifying manifest entries and uploading new bundles to CDN.

How We Guarantee Stable Asset Streaming

Our certified experience includes configuring systems for projects with over 1 million installs. We ensure the configuration passes load testing: 1000 concurrent clients with degradation no more than 5% under 50% packet loss. This follows official Unity recommendations for AssetBundles.

Client-Side Implementation

In Unity—UnityWebRequestAssetBundle.GetAssetBundle(url, cachedVersion, crc). We take cachedVersion from the manifest. crc provides additional integrity checking (optional if TLS is properly configured).

We build loading via a priority queue: assets for the current scene—high priority, assets for the next scene—medium, decorative content—low. Maximum parallel requests: 4–6 (limit of HTTP/1.1; with HTTP/2 more is possible, but Unity WebRequest does not always multiplex correctly).

For Quest (Android), the Application.temporaryCachePath limit is important—we recommend no more than 1 GB for the bundle cache, otherwise the OS aggressively cleans. We implement CacheEvictionPolicy with LRU: when the limit is reached, remove rarely used bundles via Caching.ClearCachedVersion().

What’s Included in the Work

  • Audit of current asset loading scheme and build architecture.
  • Setting up the origin server (Nginx/Caddy) with correct headers and caching policy.
  • Configuring CDN (Cloudflare, AWS CloudFront) with rules for versioned bundles.
  • Integration of AssetBundle Manifest and automated build scripts (Addressables, CI pipeline).
  • Development of a client loader with queue, priorities, and cache eviction.
  • Load testing simulating peak loads.
  • Deployment and operations documentation.
  • Team training: basic operations, monitoring, alerting.
  • Support during launch phase (2 weeks).

Estimated Timelines

Scale Timeline
Simple CDN + AssetBundle loader 1–2 weeks
Full system with versioning and manifest 3–5 weeks
Global CDN + load analytics + A/B content 2–3 months

Cost is calculated after analyzing content volume and availability requirements.

Book a consultation—we will help determine the optimal architecture for your project. Contact us to discuss the details.