Shader Cache Explained – Fix First-Launch Stutter in Citra MMJ
Performance

Shader Cache Explained – Fix First-Launch Stutter in Citra MMJ

Why Citra MMJ stutters when you first launch a game and exactly how to manage the shader cache to reduce it.

J
by Jamie Lee

If you have ever launched a game in Citra MMJ and experienced jarring stutters during the first few minutes of gameplay — even on a high-end phone — you have encountered shader compilation stutter. This guide explains why it happens and what you can do about it.

What Is a Shader?

A shader is a small GPU program that tells the graphics card how to render specific visual elements — lighting, shadows, character textures, particle effects. Modern games use thousands of unique shaders. Every time the GPU encounters a new one, it must compile it from intermediate code into machine code for your specific GPU.

On the original 3DS hardware, shaders were compiled at game startup or during level loads. On an emulator, the situation is different.

Why Shaders Cause Stutter on Emulators

Citra MMJ translates 3DS shader code into GPU-compatible programs at runtime — the moment a new visual element appears on screen. This compilation takes a measurable amount of time, typically 10–50 milliseconds per shader.

When many new shaders appear simultaneously (during a cutscene, entering a new area, or spawning enemies), the GPU pipeline stalls while it catches up. This manifests as the characteristic “stutter” — a brief freeze followed by normal play resuming.

How the Shader Cache Helps

After a shader is compiled for the first time, Citra MMJ saves the result to a shader cache on your device’s storage. The next time that same shader is needed, it loads from disk instead of recompiling — which takes microseconds rather than milliseconds.

This is why sessions improve significantly after your first 15–30 minutes of play: your cache is warming up. Subsequent play sessions are smoother because the cache carries over.

Asynchronous Shader Compilation

The most important setting for managing stutter is Asynchronous Shader Compilation (often labeled “Async Shaders”). With this enabled:

  • New shader compilation happens on a background thread
  • Gameplay continues without freezing while the shader compiles
  • A brief visual glitch (missing texture or wrong color) may appear, but it resolves in one frame

Always enable Async Shaders. The minor visual glitches are far less disruptive than the hard freezes caused by synchronous compilation.

When to Clear the Shader Cache

Clearing the cache forces a full recompile on your next session. Only do this if:

  • You updated Citra MMJ to a new major build (compiled format may have changed)
  • You switched from Vulkan to OpenGL or vice versa (caches are API-specific)
  • You experience persistent graphical corruption that started after an update
  • The emulator recommends it after a version upgrade

Do not clear the cache routinely. Every clear means another 15–30 minute warm-up session.

Where Is the Cache Stored?

On most Android installations, the shader cache lives in:

/Android/data/org.citra.citra_emu.mmj/files/shaders/

You can browse this with a file manager that has storage access. The cache folder grows over time — typically 50–200 MB for a well-played game library. This is normal.

Tips for a Faster Cache Warm-Up

  1. Play for 30 minutes in areas with diverse visual content (open worlds, varied enemy encounters) to populate the cache faster
  2. Do not force-stop the app during shader compilation — let the emulator save cleanly
  3. Keep storage free — a nearly-full device may fail to write new cache entries silently

With async compilation enabled and a warm cache, most 3DS games run without perceptible stutter within a few sessions.