VRChat Avatar Optimization Checklist
Use the SDK Builder and VRChat's Avatar Stats to identify which measurements lower the avatar's Performance Rank. Optimize the reported problem instead of treating triangle count as the only cost.
VRChat recommends aiming for a Good rank; Medium is also acceptable. Performance Rank is a static assessment of avatar properties, so it is a useful screening tool rather than a complete runtime profiler.
Record the current stats, change one major cost, then rebuild and compare the result.
- Open the avatar in the SDK Builder and record every stat lowering its rank.
- Fix mesh Read/Write, texture memory, material slots, and renderer counts first.
- Review PhysBones, contacts, constraints, particles, cloth, lights, and audio.
- Build separate mobile assets or per-platform overrides when needed.
- Upload and confirm the shipped stats inside VRChat.
On Android and iOS, the default Minimum Displayed Performance Rank is Medium. Poor and Very Poor avatars are hidden by default, and Very Poor mobile avatars cannot avoid all component restrictions through Show Avatar.
Record the Baseline
Open VRChat SDK > Show Control Panel, select Builder, and find the avatar's performance information.
Record:
- overall Performance Rank
- triangles and bounds
- texture memory
- skinned and basic mesh counts
- material slots
- PhysBone components, affected transforms, colliders, and collision checks
- contacts
- constraint count and dependency depth
- animators and bones
- lights, particles, trails, cloth, physics components, and audio sources
- download and uncompressed size after a build
After upload, VRChat's Avatar Stats screen shows the rank contribution of individual measurements and the original versus performance-filtered result.
Performance Rank, Size, and Runtime Removal
These are separate systems:
| System | What it measures | Result |
|---|---|---|
| Performance Rank | Static counts such as triangles, texture memory, renderers, material slots, dynamics, constraints, and effects | Can affect whether the avatar or individual components are shown. |
| Avatar size limits | Compressed download size and uncompressed asset-bundle size | Upload is prevented when a platform limit is exceeded. |
| Mobile component limits | Hard limits for PhysBones, contacts, and constraints | Limited components are removed when the cap is exceeded. |
| Mobile unsupported components | Components that do not run on mobile avatars | The components are disabled on Android and Quest. |
Build & Test does not enforce avatar size limits. A local test can therefore succeed even when the later upload is rejected for size.
Current Upload Size Limits
| Platform | Maximum download size | Maximum uncompressed size |
|---|---|---|
| Android | 10 MB | 40 MB |
| PC | 200 MB | 500 MB |
The SDK reports these values during publishing and shows the resulting sizes after a build. Download size and texture memory are not interchangeable: a compact downloaded bundle can still expand into substantial texture memory.
Fix Rank-Breaking Conditions First
Before reducing visual detail, check two rules that can invalidate the measurement:
- All GameObjects and components count toward Performance Rank, including disabled objects.
- If Mesh Read/Write is disabled on any avatar mesh, the SDK reports the triangle stat as unavailable, assigns a Very Poor rank, and requires the problem to be fixed before upload.
Delete unused outfit objects and test systems instead of merely disabling them when they no longer belong in the avatar.
Optimize Textures and Materials
Texture memory and material slots are separate ranked measurements.
For textures:
- reduce Max Size in Unity's texture import settings where the visual difference is acceptable
- use fewer texture files
- remove unused maps
- combine compatible maps when the shader supports packed channels
- use appropriate texture compression
- check the texture-memory result after the import settings are applied
For materials:
- remove unused material slots from meshes
- reuse a material where surfaces genuinely share the same shader and maps
- atlas compatible surfaces when that reduces both texture and material cost
- remember that repeated slots still count even when they reference the same material
- include particle, trail, and line-renderer material slots in the total
Reduce Renderer and Mesh Cost
VRChat's optimization guidance recommends no more than one Skinned Mesh Renderer and three static Mesh Renderers where the avatar design permits it.
Review:
- separate clothing and accessory skinned meshes
- hidden or duplicate body geometry
- unused mesh variants
- static props that can share a mesh
- submeshes created by excess material slots
- blend shapes that are never used
Merging meshes can reduce renderer count, but confirm that required blend shapes, bones, materials, and outfit toggles still work after the change.
Review Dynamics and Constraints
Performance Rank counts PhysBones, affected transforms, colliders, collision checks, contacts, constraint count, and constraint depth independently.
Check:
- whether each PhysBone chain is still visible and necessary
- how many transforms each PhysBone affects
- whether colliders overlap multiple chains unnecessarily
- whether contact receivers need to be networked or can use local filtering
- whether long constraint dependency chains can be simplified
- whether Unity constraints can be replaced with VRChat Constraints
VRChat recommends VRChat Constraints over Unity Constraints for avatars. Unity constraints are automatically converted at runtime, but the VRChat components are designed for the avatar system.
Review Effects and Extra Components
Inspect every:
- Particle System
- Trail Renderer
- Line Renderer
- Light
- Cloth component
- Audio Source
- physics collider and Rigidbody
- additional Animator
The rank considers component counts and, for particles, settings such as active particle totals, mesh-particle triangles, trails, and collision. Remove an effect that is no longer used rather than leaving it disabled in the hierarchy.
Mobile Performance Targets
The official mobile ranking table covers Android and iOS devices, including phones, tablets, and Meta Quest. The core thresholds below show why a separate mobile version is usually required.
| Measurement | Good rank maximum | Medium rank maximum | Hard mobile cap |
|---|---|---|---|
| Triangles | 10,000 | 15,000 | Not a component cap |
| Texture memory | 18 MB | 25 MB | Not a component cap |
| Skinned Meshes | 1 | 2 | Not a component cap |
| Material Slots | 1 | 2 | Not a component cap |
| PhysBone components | 4 | 6 | 8 |
| PhysBone affected transforms | 16 | 32 | 64 |
| PhysBone colliders | 4 | 8 | 16 |
| PhysBone collision checks | 16 | 32 | 64 |
| Contacts | 4 | 8 | 16 |
| Constraints | 60 | 120 | 150 |
| Constraint depth | 15 | 35 | 50 |
If a mobile avatar exceeds a hard PhysBone, contact, or constraint cap, VRChat removes all limited components in that category even when a user chooses Show Avatar.
Consult the complete official Performance Ranks table before publishing because it also covers bounds, basic meshes, animators, bones, particles, trails, line renderers, and raycasts.
Mobile Shaders and Unsupported Components
Android and Quest avatars can use only the avatar shaders included with the current SDK under VRChat/Mobile.
The following avatar components are disabled on Android and Quest:
- Dynamic Bones
- Cloth
- avatar Cameras
- Lights
- post-processing
- Audio Sources
- Rigidbodies, physics Colliders, and Joints
- Unity Constraints
- custom FinalIK components
Particle Systems are supported only within strict limits. Use VRChat Constraints instead of Unity Constraints and PhysBones instead of Dynamic Bones.
VRChat's iOS documentation directs creators to the same mobile optimization and limitation guidance. Validate iOS builds separately through the SDK because platform setup and testing differ.
Impostors Are Supplementary
VRChat automatically generates impostors for uploaded avatars, including cases where a Windows-only avatar needs a representation on Quest. Avatar owners can also request generation or regeneration from the avatar's page on the VRChat website.
An impostor improves fallback representation, but it does not make the original avatar cross-platform or remove the need for an optimized mobile build.
Optimization Problems
The SDK reports Mesh Read/Write Disabled.
Select every mesh used by the avatar and enable Read/Write in its import settings. VRChat cannot calculate the triangle count otherwise, assigns a Very Poor rank, and requires the issue to be corrected before upload.
The download is small but texture memory is high.
Download size measures the compressed asset bundle, while texture memory estimates the textures after loading. Reduce texture dimensions, unused maps, and unnecessary texture files, then rebuild and compare the texture-memory stat.
Disabled outfits still affect the rank.
Disabled GameObjects and components still count. Remove unused outfit objects from the uploaded avatar or create separate avatar variants when those assets are not needed together.
The mobile avatar loses all PhysBones or contacts.
Check the hard mobile component caps, not only the overall rank. Exceeding a cap removes all limited components in that category, even if the user manually shows the avatar.
The PC avatar works but mobile effects disappear.
Check Android Content Limitations. Mobile avatars disable several PC components and restrict shaders and particles, so prepare supported replacements or remove the unsupported feature from the mobile version.
Build and Test succeeds but the upload is rejected for size.
Build and Test does not enforce upload size limits. Reduce the assets contributing to download and uncompressed bundle size, then use the publishing build to check the platform limit again.
Final Measurement Pass
- Reopen the SDK Builder and compare every recorded stat.
- Confirm Mesh Read/Write no longer blocks triangle measurement.
- Verify texture memory, renderer count, and material slots improved.
- Recheck PhysBones, contacts, constraints, and effects.
- Build each supported platform separately.
- Confirm the download and uncompressed sizes remain below the platform limits.
- Test expressions, toggles, dynamics, and viewpoint after mesh or hierarchy changes.
- Upload and inspect the resulting Avatar Stats inside VRChat.
Official References
- VRChat Creation: Avatar Optimization Tips
- VRChat Creation: Performance Ranks
- VRChat Creation: Avatar Size Limits
- VRChat Creation: Android Content Optimization
- VRChat Creation: Android Content Limitations
- VRChat Creation: Avatar Impostors
- VRChat Creation: Per-Platform Avatar Overrides
- VRChat Creation: iOS Platform Guidance