Measure and Improve VRChat World Performance

Performance work begins with a repeatable test, not a list of assets to delete. Unity's Rendering Statistics, Profiler, and Frame Debugger answer different questions; VRChat's local build tools verify the result in the client and on the target platform.

Run one controlled comparison

Capture a problem viewpoint, change one suspected cost, and repeat the same test.

  1. Record the camera position, active systems, and relevant statistics.
  2. Use the Profiler or Frame Debugger to identify the dominant cost.
  3. Make one change and retest with the same build target and viewpoint.
VRChat note

Editor measurements are useful for comparison, but Unity documents that Play Mode does not reproduce target-device performance accurately. Use VRChat's local Build & Test options for the PC or Android version before judging the finished result.

Define a Repeatable Test

Choose a real location and state in the world:

  • Spawn facing the default direction.
  • A room containing the main interactive systems.
  • A viewpoint with the widest visible area.
  • A platform-specific version of the scene.
  • A multiplayer state when networked systems are part of the problem.

Record:

Test detail Example
Build target PC or Android
Location Named room, spawn, or saved camera position
View direction Exact camera orientation
World state Mirrors, video, particles, animations, or game systems on or off
Client count One local client or a defined multiplayer test
Tool Stats, Profiler, Frame Debugger, or VRChat client

Do not compare two measurements taken with different viewpoints or systems enabled unless that difference is the subject of the test.

Use the Game View Statistics

Enter Play Mode and click Stats in the Game view. Unity's Rendering Statistics overlay provides a fast view of the current camera.

Useful fields include:

Statistic What it helps reveal
FPS / CPU frame time Whether the current Editor frame is changing after an edit
Batches How much rendering work Unity grouped and submitted
SetPass calls Shader-pass and material state changes
Triangles / vertices Geometry submitted for the current view

The exact statistics vary by build target. Treat the overlay as a comparison tool, not as proof of target-device performance, because the Unity Editor contributes its own work.

Use it to answer questions such as:

  • Does looking into one room sharply increase batches?
  • Does disabling one system change SetPass calls?
  • Does occlusion culling reduce submitted geometry from a blocked viewpoint?
  • Does replacing an asset reduce triangles at the intended camera distance?

Capture the Unity Profiler

Open Window > Analysis > Profiler.

Start with only the modules related to the symptom:

Profiler module Investigate
CPU Usage Scripts, physics, animation, rendering preparation, and main-thread spikes
GPU Usage GPU work when the active graphics API and platform support it
Rendering Batches, SetPass calls, triangles, vertices, and renderer activity
Memory Managed, graphics, texture, mesh, and other memory categories
Audio Audio source, voice, DSP, and clip activity

Basic capture procedure

  1. Open the world location being tested.
  2. Open the Profiler.
  3. Select the intended profiling target.
  4. Click Record.
  5. Reproduce the slow state.
  6. Stop recording.
  7. Select a slow frame.
  8. Inspect its hierarchy or timeline before changing the scene.

Unity recommends profiling on the final target platform for accurate timings. Play Mode is appropriate for quick comparisons, but the Editor shares resources with the application and can skew the result.

Avoid enabling Deep Profile for an initial capture. Unity documents that it adds overhead; use it only when the additional script detail is required.

Classify the Dominant Cost

Use the capture to decide which investigation should come next.

Evidence Next investigation
High rendering time or many draw events Materials, shader passes, visible renderers, lighting, transparency
High triangle or vertex count Mesh density, LOD Groups, occlusion culling, camera visibility
Large texture or graphics memory Texture dimensions, format, mipmaps, lightmaps
CPU spikes in scripts Udon update frequency, repeated searches, physics, animation
High SetPass or batch counts Material count, shader variants, submeshes, batching compatibility
Cost appears only on Android Android build, mobile shaders, texture and geometry budgets, device test

Do not optimize a category only because it is easy to edit. Follow the largest measured cost that matches the failing test.

Inspect Draw Events with Frame Debugger

Open Window > Analysis > Frame Debugger.

  1. Enter the camera view that shows the rendering problem.
  2. Open the Frame Debugger.
  3. Set the target to the Editor or a compatible development Player.
  4. Click Enable.
  5. Step through the Event Hierarchy.
  6. Select draw events and inspect their geometry, shader, render target, and related GameObject.

The Frame Debugger freezes and reconstructs one frame event by event. Use it to find:

  • Which renderer created a draw event.
  • Which shader and pass were used.
  • Repeated draws for the same area.
  • Off-screen RenderTexture work.
  • The point where a transparent or effect layer enters the frame.

It explains how the frame is built; it does not replace CPU, GPU, memory, or target-device profiling.

Reduce Rendering Work

Follow the evidence from Rendering Statistics, Profiler, and Frame Debugger.

Materials and shader passes

VRChat's Android optimization guide says additional materials create submeshes and draw-call cost. Review:

  • Unnecessary material slots on a mesh.
  • Near-duplicate materials that can share one configuration.
  • Shaders with passes or effects not required by the asset.
  • Transparent materials covering large portions of the view.
  • Repeated materials that could use GPU instancing where compatible.

Do not combine every world mesh into one object. VRChat specifically warns that overly aggressive merging can interfere with batching and occlusion culling.

Geometry and visibility

When geometry submitted by a camera is the problem:

Textures and memory

Inspect the texture import settings rather than relying only on source-file dimensions:

  • Max Size
  • Platform override
  • Compression format and quality
  • Mip Maps
  • Alpha channel
  • Read/Write state when not required

VRChat's Android guide recommends keeping textures small and generally aiming for 1024 × 1024 maximum. It also notes that Crunch affects download size rather than the in-memory texture size.

Lighting

For Android worlds, VRChat recommends baked lighting, light probes, and low lightmap resolution while treating real-time lights as expensive.

Measure before and after:

  • Replacing a real-time light with baked lighting.
  • Reducing overlapping light influence.
  • Lowering unnecessary shadow settings.
  • Reducing lightmap size or resolution.

Keep a representative material and moving object in the lighting test so the bake and probes can be checked together.

Android World Checks

PC and Android versions need separate measurements and assets where necessary.

VRChat's current Android optimization guidance includes:

Area Official guidance
Compressed world size Android worlds cannot exceed 100 MB after build-time compression.
World geometry Budget approximately 250,000 triangles for the world in total.
Textures Aim for 1024 × 1024 maximum and use efficient atlases.
Materials Minimize material count without merging the world so aggressively that culling becomes ineffective.
Lighting Bake lighting, use light probes, and keep lightmap resolution low.
Occlusion Bake occlusion culling so blocked content can be excluded from rendering.
Transparency Avoid it where possible because alpha fill rate is costly on mobile GPUs.

These are platform-specific limits and recommendations, not substitutes for device testing.

VRChat's SDK can send a local world build to a configured Android device through Build and Test. Use that workflow to verify:

  • Frame behavior on the device.
  • Loading and memory behavior.
  • Mobile shader output.
  • Touchscreen and camera experience when mobile phones are supported.
  • Differences between the PC and Android scene variants.

Test the VRChat Client Build

VRChat's world SDK provides local test commands including:

  • Build & Test Your World
  • Build & Reload Your World
  • Test Your Last Build
  • Reload Your Last Build

Use the client build to repeat the same locations captured in the Editor. When multiplayer logic is part of the test, the SDK can launch multiple local clients.

VRChat's Community Labs guidance recommends testing in VR and identifies spawn as a specific performance checkpoint, with a target of at least 45 FPS for a single VR user there.

Change One Variable

Use a small experiment log:

Capture Change Result Keep?
A Baseline at the saved viewpoint Recorded statistics and frame —
B One material, light, mesh, texture, or script change Same test repeated Yes or no

If several systems change together, the result cannot show which edit mattered.

After accepting a change:

  1. Save the updated baseline.
  2. Check a second viewpoint for regressions.
  3. Test the matching VRChat build.
  4. Repeat for the next measured cost.

Troubleshooting

The Editor FPS changes every time I test.

Keep the Game view resolution, camera, active Editor windows, and world state consistent. Use the Editor for relative comparisons, then validate the accepted change in the target VRChat build.

The Profiler shows too much information.

Keep only the modules related to the symptom, reproduce one short test, stop recording, and select the slow frame. Begin with CPU Usage, Rendering, or Memory rather than enabling every module.

Deep Profile makes the world much slower.

Disable it for the baseline capture. Unity documents that Deep Profiling adds overhead, so use it only when ordinary script markers do not provide enough detail.

Batches remain high after combining meshes.

Use the Frame Debugger to inspect the actual draw events and their material or shader passes. Mesh merging does not remove material submeshes, and aggressive merging can prevent useful occlusion culling.

The Android build performs differently from Play Mode.

This is expected because the Editor and target device use different resources and platform settings. Profile or test the Android build on its target device and use Play Mode only for quick comparisons.

The world is fast when empty but slow with players.

Reproduce the real world state with the intended client count and networked systems. Use multiple local clients when appropriate, and separate world rendering, script, networking, and avatar-related observations.

I cannot tell which optimization helped.

Return to the saved baseline, apply one change, and rerun the same viewpoint and build target. Keep a short capture table so every accepted edit has a measurable result.

Continue Learning

Official References

Next Step

Capture one slow viewpoint, then apply the relevant visibility workflow with Bake and Test Occlusion Culling in Unity 2022.3.

Related Navigation