> For the complete documentation index, see [llms.txt](https://docs.viverse.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.viverse.com/optimization/optimization-recommendations-and-requirements.md).

# Optimization Recommendations and Requirements

Learn about fundamental optimization metrics and the optimization requirements in VIVERSE.

***

## Quantifying the Characteristics of Good Optimization

{% hint style="info" %}
In [Introduction to Optimizing for the Web](/optimization/readme.md), we discussed the qualitative characteristics of a well-optimized experience: **fast-loading**, **fluid**, **stable**, **responsive**, **legible**, and **scalable**. In this section, we present quantifiable application metrics and scene metrics, and show how these metrics correlate to a well-optimized scene.
{% endhint %}

**Application metrics** are the benchmarks against which we measure optimization, and they are generated by browser and engine profiling tools. **Scene metrics** are the levers that developers use to improve the application metrics. These scene metrics correspond to quantifiable properties from the rendering pipeline described above. **Application metrics** tell us what to optimize, **scene metrics** tell us how to optimize. All of these metrics are moderated by device characteristics and other external factors, which affect the scalability and potential reach of your application.

### Application Metrics to Optimize

{% hint style="info" %}
The ✅, 🟡, and ❌ ratings below are recommendations for a great experience, not review results. A ❌ rating doesn't mean VIVERSE will reject your content. For the thresholds VIVERSE checks during review, see [Optimization Requirements for VIVERSE](#optimization-requirements-for-viverse).
{% endhint %}

<table><thead><tr><th width="199.984375">Metric</th><th width="393.80078125">Description</th><th>Target Values</th></tr></thead><tbody><tr><td><a href="https://developer.android.com/topic/performance/vitals/launch-time#time-initial">Time to initial display</a> (TTID)</td><td>The amount of time (in seconds) that it takes to display the first frame of an application from a cold start. In 3D applications, it is important to show a loading bar as soon as possible. This lets the user know that the app is in a loading state and not frozen.</td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span>: &#x3C; 1.5 s<br><span data-gb-custom-inline data-tag="emoji" data-code="1f7e1">🟡</span>: 1.5 - 4 s<br><span data-gb-custom-inline data-tag="emoji" data-code="274c">❌</span>: > 4 s</td></tr><tr><td><a href="https://developer.android.com/topic/performance/vitals/launch-time#time-full">Time to full display</a> (TTFD)</td><td>The amount of time (in seconds) that it takes for the app to become interactive. For example, this would be the amount of time it takes for the user to gain control of the camera or for clickable UI elements to load. In 3D web applications, it is best to minimize TTFD, as it increases user retention.</td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span>: &#x3C; 10 s<br><span data-gb-custom-inline data-tag="emoji" data-code="1f7e1">🟡</span>: 10 - 30 s<br><span data-gb-custom-inline data-tag="emoji" data-code="274c">❌</span>: > 30 s</td></tr><tr><td><a href="https://web.dev/articles/inp">Interaction to next paint</a> (INP)</td><td>Measures the amount of time (in milliseconds) between a user interaction and the next frame. This tracks the direct scripting overhead of user interactions. This metric is most relevant to interactions that incur asset loading, shader compilation, or extensive data processing, like entering a new area of the world, as these interactions can cause the app to momentarily freeze.</td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span>: &#x3C; 16 ms<br><span data-gb-custom-inline data-tag="emoji" data-code="1f7e1">🟡</span>: 16 - 75 ms<br><span data-gb-custom-inline data-tag="emoji" data-code="274c">❌</span>: > 75 ms</td></tr><tr><td><a href="https://en.wikipedia.org/wiki/Frame_rate">Frame rate, or frames per second</a> (FPS)</td><td>The frequency at which frames are rendered to the screen. Applications with higher FPS appear more fluid, while applications with low FPS can look like a slideshow, making it difficult for the user to control their character.</td><td>Mobile &#x26; Desktop<br><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span>: > 60 fps<br><span data-gb-custom-inline data-tag="emoji" data-code="1f7e1">🟡</span>: 45 - 60 fps<br><span data-gb-custom-inline data-tag="emoji" data-code="274c">❌</span>: &#x3C; 45 fps<br><br>XR:<br><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span>: > 72 fps<br><span data-gb-custom-inline data-tag="emoji" data-code="1f7e1">🟡</span>: 60 - 72 fps<br><span data-gb-custom-inline data-tag="emoji" data-code="274c">❌</span>: &#x3C; 60 fps</td></tr><tr><td><a href="https://www.capframex.com/blog/post/Explanation%20of%20different%20performance%20metrics">5th percentile minimum frame rate</a> (5th %ile FPS)</td><td>High variance in frame time can result in a poor user experience, as this can be perceived as "choppiness" and break immersion. To get a sense of how much choppiness there is an application, we can take the 5th percentile value from <em>n</em> samples of the frame rate. In a stable application, this value will be around 80% of the median FPS.</td><td>Mobile &#x26; Desktop<br><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span>: > 45 fps<br><span data-gb-custom-inline data-tag="emoji" data-code="1f7e1">🟡</span>: 30 - 45 fps<br><span data-gb-custom-inline data-tag="emoji" data-code="274c">❌</span>: &#x3C; 30 fps<br><br>XR:<br><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span>: > 60 fps<br><span data-gb-custom-inline data-tag="emoji" data-code="1f7e1">🟡</span>: 45 - 60 fps<br><span data-gb-custom-inline data-tag="emoji" data-code="274c">❌</span>: &#x3C; 45 fps</td></tr><tr><td><a href="https://en.wikipedia.org/wiki/Image_quality">Image Quality</a></td><td>Indicates how well the real-time rendered scene matches an idealized version of the scene. A heuristic for this metric is the amount of resolution downscaling that is applied to the canvas relative to the screen. This is described more below.</td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span>: 100% scaling<br><span data-gb-custom-inline data-tag="emoji" data-code="1f7e1">🟡</span>: 85 - 100% scaling<br><span data-gb-custom-inline data-tag="emoji" data-code="274c">❌</span>: &#x3C; 85% scaling</td></tr><tr><td>Memory Usage</td><td>Higher memory usage (in megabytes/MB) generally correlates to poorer performance on lower-end devices, which typically have less available system memory (<a href="https://en.wikipedia.org/wiki/Random-access_memory">RAM</a>) and smaller CPU caches. Higher memory usage also correlates to higher <a href="https://en.wikipedia.org/wiki/Garbage_collection_(computer_science)">garbage collection</a> overhead, which can cause the scene to momentarily freeze. If too much memory is used, the browser tab will crash.</td><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span>: &#x3C; 800 MB<br><span data-gb-custom-inline data-tag="emoji" data-code="1f7e1">🟡</span>: 800 - 1600 MB<br><span data-gb-custom-inline data-tag="emoji" data-code="274c">❌</span>: > 1600 MB</td></tr></tbody></table>

### Scene Metrics to Optimize

<table><thead><tr><th width="200.12890625">Metric</th><th>Description</th></tr></thead><tbody><tr><td>Asset sizes</td><td>By decreasing the file size of static assets (models, textures, code), users can improve the loading time of the application (TTID, TTFD) and time spent loading new areas. Asset sizes can be improved by <a href="https://docs.blender.org/manual/en/latest/modeling/modifiers/generate/decimate.html">decimating meshes</a>, <a href="https://developer.chrome.com/docs/lighthouse/performance/uses-responsive-images">reducing texture size</a>, and <a href="https://www.geeksforgeeks.org/javascript/how-to-minify-javascript/">minifying code</a>.</td></tr><tr><td><a href="https://webglfundamentals.org/webgl/lessons/webgl-resizing-the-canvas.html">Framebuffer resolution and scale</a></td><td><p>There are 3 types of resolution that impact image quality: <strong>framebuffer resolution</strong>, <strong>window resolution</strong>, and <strong>device resolution</strong>. The <strong>framebuffer resolution</strong> of an application is the number of pixels that are output into the framebuffer, represented as a (width, height) pair. This is distinct from the <strong>window resolution</strong>, which is the number of <a href="https://developer.mozilla.org/en-US/docs/Glossary/CSS_pixel">CSS pixels</a> displayed to the user. <strong>Framebuffer scale</strong> represents the ratio of framebuffer resolution divided by window resolution, where higher values represent a more legible image. Lowering framebuffer scale can increase FPS at the expense of image quality.</p><p><strong>Device resolution</strong> is the number of <a href="https://developer.mozilla.org/en-US/docs/Glossary/Device_pixel">physical pixels</a> in the screen of the device. On devices with high pixel density, multiple physical pixels will make up a single CSS pixel, resulting in a higher quality image. The ratio of phyiscal pixels to CSS pixels is measured by the <a href="https://developer.mozilla.org/en-US/docs/Web/API/Window/devicePixelRatio">devicePixelRatio</a> API.</p></td></tr><tr><td>Texture resolution</td><td>The resolution of a texture dictates how legible corresponding models, text, and shader effects are in the application. Reducing texture resolution can increase FPS by decreasing image quality. This is distinct from the downloaded texture size, as high-resolution textures can be downsampled at runtime, providing an option for runtime scalability.</td></tr><tr><td><a href="https://toji.dev/webxr-scene-optimization/#reducing-draw-calls">Draw call count</a></td><td>In 3D applications, <a href="/optimization/challenges-and-optimization-strategies.md#reducing-and-batching-draw-calls">draw calls</a> tend to be the primary bottleneck. <a href="https://howik.com/understanding-draw-calls">Draw calls are very CPU intensive</a>, so FPS inversely scales with the number of draw calls in the scene. To reduce draw calls, developers can reuse materials across meshes, merge static meshes, and use instancing to clone meshes.</td></tr><tr><td>Scripting overhead</td><td>The amount of time spent each frame running application logic (in milliseconds). In a 3D experience, some time is spent each frame transforming meshes, responding to user inputs, and updating animations. Developers must optimize this per-frame scripting time to be as small as possible to ensure higher FPS. Intermittent scripting times increases are also a primary contributor to low 5th percentile minimums, as lots of application logic may need to be run when entering a new area or processing a large amount of incoming data.</td></tr><tr><td><a href="https://docs.unity3d.com/6000.0/Documentation/Manual/SL-ShaderPerformance.html">Shader overhead</a></td><td>Time spent in shaders is difficult to measure directly, but it can be inferred from the total amount of time spent on the GPU. To reduce shader time, developers can remove expensive functions (pow, log, sin), use built-in functions, use lower precision variables, and avoid repeated calculations.</td></tr></tbody></table>

### External Factors Affecting Scalability

Application metrics are affected by factors outside of a developer's control. In particular, a developer cannot control the hardware specifications (CPU + GPU + RAM) or internet connection that the experience will run on, making it difficult to optimize the experience for all users. Developers should aim to provide a good experience on the median hardware specs for each platform (mobile, desktop, XR) that their experience supports and adjust asset sizes according to median network bandwidth. A good approximation for this is to target a flagship device that is a few years old, such as an iPhone 12 or Galaxy S20, and to expect around 50 Mbps network bandwidth. VIVERSE review checks a lower floor: the minimum-spec [reference devices](https://docs.viverse.com/indexed-requirements#performance), such as the Samsung Galaxy A16. Optimize for the median device, and make sure your content still meets the indexing floor on the minimum-spec device.

{% tabs %}
{% tab title="Device Class" %}
3D capable devices are typically split into 3 categories: Mobile (Android and iOS tablets and phones), Desktop (laptop and desktop computers), and recently XR (augmented and virtual reality headsets). Desktops are the most powerful, and can render experiences at higher fidelity than mobile devices and XR headsets. If you plan to support multiple platforms, expect to optimize code and assets for each platform.
{% endtab %}

{% tab title="CPU" %}
A [CPU's](https://en.wikipedia.org/wiki/Central_processing_unit) speed is determined by three main factors: **clock speed**, core **count**, and **cache size**. Clock speed determines how fast an individual function can complete on a CPU, higher clock speeds corresponding to faster execution. Higher cache sizes allow the CPU to access data very quickly, avoiding relatively expensive RAM operations. However, leveraging cache size often relies on careful optimization. Core count determines how much parallelism an application can leverage. A program can theoretically cut scripting time proportionally to the number of cores, but this requires additional optimization with Web Workers or WebAssembly. Increasing CPU speed allows for more complex scripting and higher draw call counts. Loading times also tend to increase, as assets are processed more quickly once they are downloaded.
{% endtab %}

{% tab title="GPU" %}
A [GPU's](https://en.wikipedia.org/wiki/Graphics_processing_unit) speed is determined by memory size (**VRAM**), **GPU clock speed**, and **core count**. For GPUs, core count and memory size are more important than clock speed, as GPUs have to perform many operations in parallel. Having more cores and more memory allow GPUs to process larger textures and more vertices with higher precision. Increased clock speeds typically decrease the amount of time spent in shaders, though this is typically only a bottleneck with very expensive shaders.
{% endtab %}

{% tab title="RAM" %}
The amount of system memory, or [RAM](https://en.wikipedia.org/wiki/Random-access_memory), that a user's device has will limit the types of experience that they are able to run. RAM is used to keep active program data readily available, so more complex experiences will require more RAM. Typical mobile devices will have 1GB - 8GB of RAM, which is enough to run smaller experiences with good performance. Desktop and laptop computers typically have 8GB - 32GB of RAM, which is enough to run medium experiences. The highest-quality experiences require 16+ GB of available RAM.
{% endtab %}

{% tab title="Network" %}
A user's network speed is out of a developer's control. If a user does has less than 1 MB/s internet speed, they will have trouble accessing 3D experiences in a reasonable time. Nevertheless, developers should tune asset sizes such that users with a *wide* range of internet speeds can access their experience. Developers can also take use of progressive loading to download assets throughout the experience runtime.
{% endtab %}
{% endtabs %}

### Correlating Qualitative Characteristics to Metrics

<table><thead><tr><th width="176.875" valign="top">Characteristic</th><th valign="top">Application Metrics</th><th valign="top">Scene Metrics</th><th valign="top">External Factors</th></tr></thead><tbody><tr><td valign="top">Fast Loading</td><td valign="top"><ul><li>TTID</li><li>TTFD</li><li>INP</li></ul></td><td valign="top"><ul><li>Asset Sizes</li></ul></td><td valign="top"><ul><li>Network Speed</li><li>CPU Clock Speed</li></ul></td></tr><tr><td valign="top">Fluid</td><td valign="top"><ul><li>FPS</li></ul></td><td valign="top"><ul><li>Draw Call Count</li><li>Framebuffer Resolution</li><li>Scripting Overhead</li><li>Shader Overhead</li><li>Texture Resolution</li></ul></td><td valign="top"><ul><li>CPU Clock Speed</li><li>GPU VRAM</li><li>GPU Clock Speed</li></ul></td></tr><tr><td valign="top">Stable</td><td valign="top"><ul><li>5th Percentile Frame Rate</li><li>Memory Usage</li></ul></td><td valign="top"><ul><li>95th percentile shader overhead</li><li>95th percentile scripting overhead</li><li>95th percentile draw call count</li></ul></td><td valign="top"><ul><li>RAM</li><li>CPU Clock Speed</li><li>GPU VRAM</li><li>GPU Clock Speed</li></ul></td></tr><tr><td valign="top">Responsive</td><td valign="top"><ul><li>Interaction to Next Paint (INP)</li></ul></td><td valign="top"><ul><li>Maximum scripting overhead</li><li>Maximum shader overhead</li><li>Maximum draw call count</li></ul></td><td valign="top"><ul><li>CPU Clock Speed</li></ul></td></tr><tr><td valign="top">Legible</td><td valign="top"><ul><li>Image Quality</li></ul></td><td valign="top"><ul><li>Texture resolution</li><li>Framebuffer scaling</li></ul></td><td valign="top"><ul><li>Screen Resolution</li><li>Screen Size</li></ul></td></tr><tr><td valign="top">Scalable</td><td valign="top"><ul><li>For scalability, validate all application metrics on each device class you plan to support (mobile, XR, desktop)</li></ul></td><td valign="top"><ul><li>Texture resolution may need to be tuned for each device</li><li>Draw call count may need to be tuned for each device</li></ul></td><td valign="top"><ul><li>Device Classes Supported</li></ul></td></tr></tbody></table>

***

## Optimization Requirements for VIVERSE

VIVERSE reviews performance at two levels. Indexed content must meet a minimum floor before it appears in basic discovery, and curated content must meet a higher bar. For how review works, see [How content review works on VIVERSE](https://docs.viverse.com/content-review).

Reviewers measure these metrics on the [reference devices](https://docs.viverse.com/indexed-requirements#performance) for each device type you declare in VIVERSE Studio, with a cold cache on a 50 Mbps connection.

| Metric                         | Device type        | Indexed (required)                           | Curated (required for consideration)         |
| ------------------------------ | ------------------ | -------------------------------------------- | -------------------------------------------- |
| Average frame rate             | Desktop and mobile | At least 24 FPS                              | At least 45 FPS                              |
| Average frame rate             | XR (Meta Quest 3)  | At least 60 FPS                              | At least 72 FPS                              |
| 5th percentile frame rate      | Desktop and mobile | Not checked                                  | At least 30 FPS                              |
| 5th percentile frame rate      | XR (Meta Quest 3)  | Not checked                                  | At least 45 FPS                              |
| Time to full display (TTFD)    | All                | 30 seconds or less                           | 15 seconds or less                           |
| Time to initial display (TTID) | All                | A loading indicator appears within 3 seconds | A loading indicator appears within 3 seconds |

Indexed review measures the minimum-spec device for each device type. Curated review measures every reference device for each device type you declare.

{% hint style="warning" %}
**Keep memory usage under 1600 MB.** Memory isn't a review threshold, but above this level browser tabs often crash, especially on iOS. A crash is a P0 issue, which fails review.
{% endhint %}

### Use the recommendations to go beyond the requirements

The review thresholds are minimums. The ✅ targets in [Application Metrics to Optimize](#application-metrics-to-optimize), such as 60 FPS on desktop and mobile and a TTFD under 10 seconds, are what a great experience feels like. Curation reviewers also judge how fluid, stable, and responsive your content feels, so aim for the recommended targets where you can.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.viverse.com/optimization/optimization-recommendations-and-requirements.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
