Mobile performance is one of the biggest stumbling blocks for indie developers shipping Godot 4 games on Android and iOS. A project that runs smoothly in the editor can stutter badly on a mid-range phone, drain battery in minutes, or crash on older devices — and the root causes are rarely obvious. The Godot Foundation has been closing these gaps steadily: recent versions introduced native Android crash symbols, Perfetto profiler integration, and Vulkan driver workarounds that cut crash rates dramatically across the Android device ecosystem.
Table of Contents
This guide covers the most impactful optimizations you can make right now: picking and configuring the correct Rendering Method (including the per-platform override that most tutorials skip entirely), enabling proper texture compression, cutting draw calls, and profiling on real hardware. Whether you are building a 2D casual game or a 3D action title, these steps will give you a measurable performance improvement and a smoother path through the app stores.
Quick Answer
For most Godot 4 mobile projects: go to Project Settings > Rendering > Renderer > Rendering Method and choose Mobile for modern devices (Vulkan/Metal) or Compatibility for broad hardware support. Enable VRAM compression via Project Settings > Rendering > Textures > VRAM Compression > Import ETC2 ASTC, then reimport your assets. Reduce draw calls with MultiMesh and texture atlases, bake lighting for static geometry, and cap frame rate with Engine.max_fps = 60. Always profile on real Android or iOS hardware — the in-editor profiler reflects desktop GPU performance, not phone performance.
Step 1: Set the Rendering Method — Including the Mobile Override
Godot 4 offers three renderers. You choose between them at Project Settings > Rendering > Renderer > Rendering Method. In the project.godot file this maps to the key rendering/renderer/rendering_method. The three values are forward_plus, mobile, and gl_compatibility — and picking the wrong one is the most common early mistake.
Forward+ (forward_plus) is designed primarily for desktop and is supported on mobile but poorly optimized. It does not account for mobile GPU constraints and will produce poor frame rates and compatibility failures on phones. Do not use it for any mobile export target.
The Mobile renderer (mobile) runs on Vulkan on Android and Metal on iOS. It is optimized for mobile GPU architectures and is the correct choice for 3D games targeting modern devices released from roughly 2018 onward. It supports compute shaders, so GPUParticles work correctly, and it supports most advanced rendering features while staying within mobile hardware limits.
The Compatibility renderer (gl_compatibility) runs on OpenGL ES and reaches the widest range of hardware, including budget and older devices. It is the right pick for 2D games, for web exports, and when you must support older Android phones. The critical trade-off: Compatibility does not support compute shaders. GPUParticles2D and GPUParticles3D silently fail when this renderer is active — no error is logged and no warning is printed; particles simply do not appear.
The feature most developers overlook: Godot 4 supports a per-platform rendering method override through a second project.godot key — rendering/renderer/rendering_method.mobile. Set this to gl_compatibility to export Compatibility builds to mobile while keeping Forward+ or Mobile active for desktop development, without maintaining two separate projects. To access this in the editor, enable Advanced Settings in the Project Settings filter bar and look under Rendering > Renderer.
Choose your renderer before you start building. Switching from Compatibility to Mobile or Forward+ later requires reworking materials, shaders, and sometimes your entire lighting setup. If you are building a 3D mobile game targeting modern hardware, start with the Mobile renderer from day one.
Step 2: Enable VRAM Compression (ETC2 / ASTC)
Uncompressed textures are one of the fastest ways to exceed your memory budget on mobile. Godot 4 supports ETC2 compression for Android and ASTC for iOS, and both formats are enabled through a single setting: Project Settings > Rendering > Textures > VRAM Compression > Import ETC2 ASTC. Once enabled, Godot reimports your textures in the correct compressed format at export time.
A critical gotcha: enabling this setting alone does nothing until you reimport your assets. Delete the hidden .godot/imported folder and let the editor reimport everything, or use the Fix Imports button in the Export dialog. Skipping this step means textures ship uncompressed regardless of the project setting. Use PNG or TGA as your source formats — Godot cannot automatically transcode DDS files into mobile-compatible compressed formats.
For 2D projects using texture atlases, make sure all sprites within a given atlas use the same compression settings. Mixed compression across an atlas forces Godot to break batches, which cancels the draw call savings the atlas was meant to provide.
Step 3: Reduce Draw Calls
Mobile CPUs are significantly slower than desktop CPUs at dispatching many small draw calls. Every extra draw call is CPU time your phone cannot spare. For 2D games, combine sprites that share a texture into a TextureAtlas so Godot can batch them into a single draw call. For 3D games with many identical objects — trees, rocks, coins, enemies — replace individual MeshInstance3D nodes with a MultiMeshInstance3D; this lets the GPU render thousands of instances in one call.
For lighting, prefer per-vertex lighting over per-pixel lighting where the visual difference is acceptable; it is dramatically cheaper on mobile GPUs. Limit the number of active OmniLight3D and SpotLight3D nodes in any scene — each dynamic light that intersects a mesh adds a rendering pass. For scenes with static or mostly static geometry, bake lighting into a LightmapGI node instead of leaving lights fully dynamic. Reserve dynamic shadows only for the player character and a small number of moving objects.
For 3D scenes, enable occlusion culling by placing OccluderInstance3D nodes inside large blocking geometry, and configure Visibility Ranges (HLOD) on detailed meshes so they swap to lower-poly versions at distance. The Mobile renderer does not use a depth prepass, which makes proper occlusion culling especially valuable for keeping per-frame draw calls in check.
Step 4: Cap Frame Rate and Manage Battery
Running uncapped at the device’s maximum refresh rate burns battery and generates heat, which modern phones counter by throttling the CPU and GPU — creating the frame-time spikes that feel like a performance bug but are actually thermal management. Add Engine.max_fps = 60 to your project’s autoload or main scene. For turn-based or puzzle games where motion is infrequent, targeting 30 FPS roughly halves GPU load and extends battery life noticeably.
For touch input, calling Input.set_use_accumulated_input(false) processes each raw touch event individually instead of merging them per frame, reducing input latency for games where tap timing or swipe precision matters. If you implement an adaptive quality system, useful runtime signals include Engine.get_frames_per_second() for FPS, OS.get_static_memory_usage() for memory pressure, and RenderingServer.get_rendering_info(RenderingServer.RENDERING_INFO_TOTAL_DRAW_CALLS_IN_FRAME) for live draw call counts you can display in a debug overlay.
Step 5: Profile on Real Hardware
Never optimize based on in-editor performance numbers alone. The Godot editor runs on your desktop GPU using the Forward+ renderer, which has far more shader cores, memory bandwidth, and compute throughput than any phone. A scene can run at 120 FPS in the editor and drop to 25 FPS on a mid-range Android device running the Compatibility renderer over OpenGL ES.
Test on at least two real devices: one recent flagship to verify feature support, and one mid-range or older device representing your minimum spec. On Android, Godot 4.6 and later integrate directly with Perfetto for system-level tracing; Android GPU Inspector provides per-draw-call GPU timing. On iOS, use Xcode Instruments with the Metal System Trace template. Godot’s built-in Profiler tab in the Debugger panel captures frame time, script execution time, and renderer stats over a USB connection and is a solid first diagnostic pass before reaching for platform-specific tools.
Godot 4.5 added native debug symbol support for Android, which lets you upload symbols to the Google Play Console so crash reports show readable stack traces instead of raw addresses. Enable this in your Android export preset and upload the symbols file alongside each release build.
Common Mistakes and How to Avoid Them
Using Forward+ for mobile exports is the single most common renderer error. It is not a higher-quality version of the Mobile renderer — it is a desktop-focused pipeline that is poorly optimized for mobile GPU architectures and will perform significantly worse on phones than Mobile or Compatibility.
Setting the rendering/renderer/rendering_method.mobile override to gl_compatibility and expecting GPUParticles to work. The Compatibility renderer has no compute shader support, so GPUParticles disappear silently with no error message. Use CPUParticles2D or CPUParticles3D instead, or switch to the Mobile renderer if you need GPU particles.
Enabling ETC2/ASTC compression but forgetting to reimport textures. The project setting registers the intent; reimporting actually compresses the files. Delete the .godot/imported folder after enabling to guarantee a clean reimport.
Profiling in the editor and treating those numbers as representative of phone performance. Always run the final profiling pass on real hardware over a USB debug connection.
godot-4-mobile-optimization FAQs
Where exactly is the ‘Rendering > Renderer > Rendering Method’ setting in Godot 4?
Go to Project > Project Settings, then navigate to Rendering > Renderer > Rendering Method. You may need to toggle on Advanced Settings at the top of the Project Settings window to see all available options. The dropdown offers three choices: Forward+ (designed for desktop; supported on mobile but poorly optimized), Mobile (Vulkan on Android, Metal on iOS, for modern devices), and Compatibility (OpenGL ES, widest hardware support). In the project.godot file this setting appears as rendering/renderer/rendering_method with values forward_plus, mobile, or gl_compatibility.
What does rendering/renderer/rendering_method.mobile do in Godot 4?
This is a per-platform override key in project.godot that lets you set a different rendering method for mobile exports without changing the setting used for desktop builds. For example, you can keep rendering/renderer/rendering_method = forward_plus for desktop development and add rendering/renderer/rendering_method.mobile = gl_compatibility so that Android and iOS exports automatically use the Compatibility renderer. Enable Advanced Settings in the Project Settings filter to expose this override in the editor UI under Rendering > Renderer.
Which Godot 4 renderer should I use for Android and iOS?
Use the Mobile renderer for 3D games targeting modern Android or iOS devices (from roughly 2018 onward). It uses Vulkan on Android and Metal on iOS, supports compute shaders and GPUParticles, and is optimized for mobile GPU architectures. Use the Compatibility renderer for 2D games, budget devices, older Android hardware, or web exports. Avoid Forward+ for mobile — it is designed for desktop and poorly optimized for mobile, producing significantly worse performance on phones than Mobile or Compatibility.
Why do GPUParticles disappear silently on mobile in Godot 4?
GPUParticles2D and GPUParticles3D require compute shaders, which the Compatibility renderer (gl_compatibility) does not support. When your mobile export uses this renderer, particles simply stop rendering — Godot logs no error and prints no warning. Switch to the Mobile renderer to re-enable GPUParticles, or replace them with CPUParticles2D or CPUParticles3D if you need to keep the Compatibility renderer for older device support.
Why does my Godot 4 game run smoothly in the editor but stutter on my phone?
The editor uses your desktop GPU running the Forward+ renderer, which has far more compute power and memory bandwidth than a mobile chip. Profile on real hardware using Perfetto or Android GPU Inspector (Android) or Xcode Instruments (iOS). Common culprits are too many draw calls, uncompressed textures still shipping despite having enabled ETC2/ASTC, too many dynamic lights, or thermal throttling caused by an uncapped frame rate.
How do I enable ETC2 and ASTC texture compression in Godot 4?
Go to Project Settings > Rendering > Textures > VRAM Compression and enable Import ETC2 ASTC. After enabling, delete the .godot/imported folder and reopen the project to force a full reimport, or use the Fix Imports button in the Export dialog. Without reimporting, your textures will still ship uncompressed regardless of the setting. Use PNG or TGA source files — Godot cannot automatically convert DDS textures to mobile-compatible formats.
Get More from godot-4-mobile-optimization
Log the coasters, stadiums, and venues you’ve experienced, rate godot-4-mobile-optimization, and see what your friends thought. Get the ThrillZing app.