# 6. Quest Performance Budgets
Part of [[Profiling and Optimization]]. Previous: [[5. Profile Analyzer and Related Tools]]. Next: [[7. Profiling Pitfalls]].
> [!note] Verification status
> Numbers and tool names in this part come from Meta's official **Testing and performance analysis** page (https://developers.meta.com/horizon/documentation/unity/unity-perf/), last updated **2024-10-30**, fetched 2026-11-10, and from the Quest Performance VRC it links. They are **guidelines, not guarantees**. Meta states that draw-call and triangle ranges vary with simulation load, graphics API, and pipeline state. Always re-check the live VRC before a store submission. VR work in this vault targets **Unity 6.3 LTS (6000.3.27f2+)** ([[0.Choosing a Unity Version]]). This part was **not** run on a headset.
## 6.1 Frame time is the budget
Interactive Quest applications must hold a **minimum of 72 FPS**. That is about **13.9 ms** per frame, for **both eyes**, including your CPU work, the GPU, and compositor / TimeWarp reality. Media applications may aim at 60 FPS (Meta's page). Missing the frame rate does not just "look like 60": the compositor will reuse or reproject frames, and players feel it as judder or comfort problems.
A 13.9 ms budget is small. A 2 ms GC hitch is a missed frame. Profile on the headset, with CPU/GPU levels locked, as Meta recommends.
Related: [[5.Quest 2 Performance and Rendering]], [[3.Quest 2 Project and Build Setup]], [[4.Quest 2 Testing and Deployment]].
## 6.2 Draw calls (Meta's example ranges)
From Meta's table (examples; "your results may vary"):
| Platform | Busy simulation | Medium simulation | Light simulation |
|---|---|---|---|
| Quest 1 | 50-150 | 150-250 | 200-400 |
| **Quest 2, Quest Pro** | **80-200** | **200-300** | **400-600** |
| Quest 3, Quest 3S | 200-300 | 400-600 | 700-1000 |
- **Busy** — lots of simulation, VoIP, networking, animation/skinning of other players or many NPCs (social, multiplayer shooters).
- **Medium** — most apps; medium worlds, fewer characters.
- **Light** — few pipeline state changes (escape rooms, puzzles, many class projects).
"Draw calls" here are constrained by pipeline state changes, main-thread work that delays the render thread, and the graphics API (Vulkan vs GLES). Meta's long-standing advice: share and instance meshes, use a small set of shaders, prefer Vulkan. For Unity 6 / URP, also see Entities Graphics' Vulkan requirement on Android if you are on DOTS ([[7. DOTS Profiling Quest and When Not to Use]]).
## 6.3 Triangles (Meta's example ranges)
| Platform | Triangle count (guideline) |
|---|---|
| Quest 1 | 350k-500k |
| **Quest 2, Quest Pro** | **750k-1m** |
| Quest 3, Quest 3S | 1.3m-1.8m |
These are fluid. Large triangles that span many tiles cost more on a tile-based GPU. Vertex attribute layout and precision matter (Meta discusses splitting position/skinning from other attributes, and using half-precision where you can). Treat 750k-1m on Quest 2 as a planning envelope, then measure.
## 6.4 Fill rate, overdraw, and post-processing
Meta's ecosystem guidance (and the VRC) repeatedly punishes:
- Overlapping alpha
- Dense particles
- Full-screen post-processing
- High MSAA combined with heavy shading
Use Scene view Overdraw, the Frame Debugger (part 4), and OVR Metrics. If you keep post-processing on Quest, keep the stack short — the Post-Processing tutorial later in this queue discusses which URP volume effects are even plausible on a headset.
## 6.5 Tools on the headset
- **Unity Profiler** attached to a Development Build (USB or Wi-Fi). Lock clocks before comparing.
- **Frame Debugger** attached to the Player, for the draw list.
- **OVR Metrics Tool** — official Meta app: frame rate, heat, CPU/GPU throttling, torn and stale frames. Report mode after a session, or a performance HUD overlay. This is often the first tool that shows *stale frames* clearly.
- **RenderDoc** (and Meta's documentation around it) for a true device GPU capture when Unity's GPU module is not enough.
- Unity's **Built-in Profiler** logcat path exists; Meta still mentions it. For class, OVR Metrics + the Unity Profiler are enough.
`Gfx.WaitForPresent` showing up often means the render pipeline is stalled — Meta's page points you at the Frame Debugger as the start of that investigation.
## 6.6 A Quest walk-through checklist
Use this as a lab sheet for the "courtyard walk" verb:
- [ ] 72 FPS in OVR Metrics, walking the test path, no menus
- [ ] Stale frame count is near zero on that path
- [ ] Draw calls sit in the Meta range that matches the project's simulation load
- [ ] Triangle count is in the Quest 2 envelope, or you have a documented reason and a measured frame time
- [ ] Overdraw is not a heat map in the playable frustum
- [ ] No GC spike on the path (Incremental GC on, allocations hunted)
- [ ] Memory snapshot after the walk is inside a budget you wrote down for Quest 2
- [ ] Quality / URP asset for Android is a Quest-specific asset, not the Editor desktop asset
- [ ] GPU/CPU levels locked while comparing two builds
If the walk fails, change one thing (shadows, MSAA, a particle, a post-process, a unique material) and measure again.
## Official docs
- Meta testing and performance analysis: https://developers.meta.com/horizon/documentation/unity/unity-perf/
- Quest Performance VRC 1: https://developers.meta.com/resources/vrc-quest-performance-1/
- OVR Metrics Tool (linked from that page): https://developers.meta.com/horizon/documentation/unity/ts-ovrmetricstool
- [[5.Quest 2 Performance and Rendering]]