How to Build Mobile 3D Performance Budgets
Turn device tiers, frame deadlines, memory limits, network conditions, thermal behavior, and scene measurements into enforceable mobile 3D budgets.
A useful mobile 3D budget is a set of scene constraints derived from a product experience on named devices. It is not “under 100,000 polygons” copied from a forum. Mobile performance depends on visible instances, screen resolution, draw calls, materials, texture memory, animation, shadows, browser overhead, temperature, and what else the page or app is doing.
Build the budget from the bottom up: choose the lowest supported experience, measure a representative worst scene, allocate frame and memory headroom, then turn the allocation into asset-class limits. Revisit it whenever the renderer or target range changes.
Define the supported device tiers#
“Mobile” includes low-cost Android phones, current flagship phones, tablets, integrated-GPU laptops in mobile browsers, and headsets with mobile-class chips. One limit cannot describe all of them.
Create two or three tiers using actual test devices. Record:
- device model and operating-system version;
- browser or engine version;
- physical display and rendering resolution;
- GPU and system-on-chip family where available;
- memory class;
- refresh rate;
- thermal and power mode;
- supported texture and graphics features;
- target experience or fallback.
The lowest tier should be a device the product genuinely supports, not the slowest phone anyone can find. Define fallback behavior below it: poster image, turntable video, simplified viewer, or an explicit compatibility message.
Avoid user-agent-only quality selection. Capability queries, short calibration, persisted preferences, and observed frame stability can refine a tier. Do not run a punishing benchmark every visit or silently raise quality after one misleading fast second.
Begin with the frame deadline#
A 60 Hz target provides approximately 16.67 milliseconds per frame. A 30 Hz target provides 33.33 milliseconds. At 90 Hz, common in XR, only about 11.11 milliseconds are available.
The 3D scene cannot own the whole interval. On a web page, work may include:
- input and interaction logic;
- React or other UI updates;
- layout and paint;
- animation and physics;
- asset streaming callbacks;
- analytics and third-party scripts;
- renderer CPU submission;
- GPU rendering and composition.
Reserve headroom. If the scene consumes 16 ms on a 60 Hz target in a clean test, ordinary UI work will push it over. A team might allocate 10–12 ms to steady 3D rendering and retain the remainder, but the exact split must come from the application.
Use frame-time percentiles. A p95 of 24 ms means at least 5% of measured frames exceed that time, even if the median is 12 ms. Establish both typical and spike gates.
Build a representative worst scene#
Budgets fail when each asset is tested alone. Assemble the heaviest normal situation the user can reach:
- maximum intended visible products or characters;
- typical environment and UI;
- production lights and shadows;
- required transparency and post-processing;
- animation and skinning active;
- maximum normal camera coverage;
- streaming or variant changes that occur during interaction;
- production pixel ratio;
- realistic page scripts and overlays.
“Worst normal” excludes malicious behavior such as opening 200 hidden variants if the product prevents it. It includes edge cases normal users can reach, such as zooming out to show the whole catalog wall or switching products repeatedly.
Create a fixed camera and action path so releases are comparable. Save the scene revision, device state, run duration, and capture method with every result.
Separate CPU, vertex, and fragment limits#
One numeric asset budget cannot solve every bottleneck.
CPU pressure often follows:
- object and node count;
- draw submissions and material state changes;
- JavaScript or script work;
- animation graph and physics complexity;
- culling and hierarchy updates;
- garbage collection and allocation.
Vertex pressure often follows:
- visible rendered vertices across passes;
- skinning and morph targets;
- triangle size and reuse;
- shadow and depth passes;
- vertex shader complexity;
- insufficient LOD.
Fragment pressure often follows:
- rendered pixel count;
- overdraw and transparency;
- material texture samples and branches;
- lighting and shadows;
- full-screen post effects;
- high pixel ratio or multisampling.
Use controlled experiments. Halve render width and height, reducing pixels by 75%; a large improvement points toward fragment cost. Replace materials with a simple opaque shader; improvement implicates shading or overdraw. Replace meshes with low LODs; improvement implicates geometric work. Reduce visible object count; improvement can expose CPU submission or total work.
Create a draw and material budget#
Draw-call capacity varies by renderer, API, device, and state changes, so no universal number is safe. Measure the worst scene and identify the point where CPU frame time loses headroom.
Allocate draws by system:
- environment;
- primary product or character;
- repeated props;
- transparent effects;
- shadows;
- UI rendered inside the 3D context;
- debugging or selection passes;
- reserve for future features.
If a scene budget is 250 main-view submissions on the low tier, a hero asset using 80 consumes 32% before shadows. That makes its many material slots a design issue. If the measured tier easily handles 1,000 compatible draws with headroom, forcing every asset into one atlas may create needless art and memory cost.
Track shader variants as well as material count. Twenty materials sharing three programs behave differently from twenty unique feature combinations that compile and switch independently.
Set geometry budgets at scene and class levels#
Start with visible scene geometry that passes the vertex-control test. Then divide by asset class and maximum instance count.
Example allocation for a measured scene might be:
- hero product: 120,000 triangles at closest LOD;
- four secondary products: 35,000 each = 140,000;
- environment: 180,000 visible;
- effects and UI geometry: 60,000;
- reserve: 100,000;
- total planned visible input: 600,000 triangles in the relevant main pass.
These numbers are illustrative and incomplete. Shadow passes can duplicate work. Rendered vertices matter more directly than source positions. Small triangles can be inefficient. A Mali-class integrated GPU and a flagship Apple GPU may support very different scenes.
Asset limits should include:
- triangles and rendered vertices per LOD;
- maximum instances at each screen-size band;
- material primitives;
- skin and morph cost;
- shadow-caster geometry;
- collision geometry if it affects runtime;
- minimum feature preservation requirements.
Treat exceptions as spending shared headroom. A hero can exceed its class only if the full scene still passes.
Texture and memory budgets#
Encoded downloads do not predict resident memory. A 2048 × 2048 RGBA8 texture with full mips is about 21.3 MiB. Six unique maps approach 128 MiB. Mobile browsers and integrated GPUs share finite system resources with the page, camera, OS, and compositor.
Define:
- maximum initial model bytes;
- maximum optional detail bytes;
- unique texture memory per asset class;
- scene texture memory estimate;
- geometry buffer memory;
- render-target and shadow allowance;
- peak decode and route-transition envelope;
- safety margin.
Use GPU-oriented compressed textures when supported and quality-approved. Still inventory the transcode target. An 8-bit-per-pixel result uses twice the memory of a 4-bit-per-pixel result at the same dimensions.
Limit dimensions by visible use. A 4096 map on a product that never exceeds 700 pixels wastes memory unless a small UV region needs the resolution. Conversely, readable label text in a close configurator may justify 2048 even when broad color would not.
Network and interaction budgets#
Mobile users experience variable throughput and latency. Define a repeatable acquisition profile plus real-user monitoring.
Separate:
- initial page resources;
- viewer application code;
- first recognizable model resources;
- interaction-quality resources;
- optional inspection or AR derivatives;
- decoder payloads on cold cache.
An example product may target 1.5 MB for the first recognizable model and allow another 3 MB after interaction. A different technical viewer may accept a 12 MB explicit load because users require fine inspection. The product promise determines the budget.
Reserve bandwidth priority for core page content. Lazy loading protects the page but makes the viewer wait start later. Preloading helps only when the model is likely to be needed immediately and does not crowd out more important resources.
Measure first recognizable frame and first responsive interaction, not just response completion.
Thermal stability and power#
Mobile chips boost briefly, then reduce frequency as heat and power limits accumulate. A scene passing a 20-second desktop-style benchmark can degrade after 5 minutes.
Run sustained tests:
- begin from a repeatable cool device state;
- set brightness and power mode;
- run the production interaction path continuously;
- record frame percentiles every minute;
- monitor battery and thermal state where tools permit;
- continue for at least 10–20 minutes for heavy experiences;
- repeat in realistic ambient conditions.
If frame time climbs from 14 ms to 25 ms, the initial result is not a stable 60 Hz experience. Lower continuous quality, add dynamic resolution or LOD, reduce shader and transparency work, or choose a 30 Hz policy if the platform and experience allow it.
Avoid oscillating dynamic quality. Use hysteresis and gradual changes. Sudden resolution or LOD shifts are visible and can create more instability.
WebXR requires stricter allocation#
XR adds stereo views, high display resolution, tracking, camera processing for AR, and strict comfort expectations. A phone-based AR viewer competes with live camera capture and compositing. Standalone headsets operate within mobile power envelopes.
Budget against the headset refresh target: 72 Hz gives about 13.89 ms; 90 Hz gives 11.11 ms. Missed frames and irregular pacing can be more uncomfortable than a flat-screen drop.
Test at real-world scale. A one-meter object viewed from 30 centimeters exposes more texture and geometry than the same model in a thumbnail. Transparent surfaces, full-screen effects, and high-frequency normal maps need on-device review.
Provide a non-XR fallback and a lower quality tier. Entering immersive mode should not trigger an uncontrolled simultaneous model, environment, and decoder load.
Turn the budget into gates#
Automate what can be inspected statically:
- total and initial bytes;
- triangles and rendered vertices by primitive;
- material, primitive, and node counts;
- image dimensions and channel use;
- estimated texture and geometry memory;
- animation channels and morph targets;
- extension allowlist;
- LOD presence and ratios;
- bounds and physical dimensions.
Static gates cannot prove frame time. Add a device benchmark suite that loads representative scenes, follows a camera path, captures frame percentiles, and records memory and thermals. Run it on release candidates and after renderer upgrades.
Use warning and failure levels. A 2100-pixel texture against a 2048 guideline may be auto-resized or reviewed; a 16,384 image can fail. A hero exceeding a triangle class may pass with a signed exception tied to scene evidence.
Budget review cadence#
Recalibrate when:
- the supported device floor changes;
- render resolution or antialiasing changes;
- lighting, shadows, or post-processing changes;
- engine or browser versions materially change;
- the page adds heavy third-party work;
- asset style or camera policy changes;
- XR becomes a requirement;
- real-user metrics disagree with lab results.
Do not silently raise asset limits because one new flagship is faster. Keep the floor experience stable or explicitly change support policy.
Common budget failures#
One limit per model. Scene instances and other systems are ignored.
Triangles without vertices or passes. Seams, skinning, and shadows disappear from accounting.
Download bytes used as memory. Decoded textures exceed estimates.
Desktop profiling only. Thermal and integrated-memory behavior are absent.
Average fps acceptance. Spikes and throttling remain hidden.
No reserve. Every new UI or effect breaks the frame deadline.
Budget without automated gates. Limits become documentation no one checks.
Automated gates without visual review. Small but important features are destroyed to meet counters.
Mobile budget checklist#
- Supported tiers name real devices and fallback behavior.
- Frame budgets are expressed in milliseconds with headroom.
- A fixed worst-normal scene and camera path exist.
- CPU, vertex, and fragment controls identify the bottleneck.
- Draws are counted by pass and asset system.
- Geometry limits include vertices, instances, LOD, skinning, and shadows.
- Texture estimates use resident formats and mip levels.
- Initial, interaction, and optional network bytes are separate.
- Peak load memory includes temporary overlap.
- Sustained tests expose thermal degradation.
- Static asset gates and on-device scene gates both run.
- Exceptions spend measured shared headroom and have owners.
Sources and further reading#
- MDN: WebGL best practices
- Chrome Developers: remote debug Android devices
- Android Developers: system tracing
- Apple Developer: Metal performance best practices
- W3C WebXR Device API
Mobile budgets are negotiated allocations backed by device evidence. Start with frame, memory, and interaction requirements; measure the complete scene; then give every asset class limits that preserve both visual purpose and shared headroom.