How to Reduce Input Lag with Run-Ahead
Configure RetroArch run-ahead from measured internal game lag, validate core serialization and performance, and keep a reversible per-game profile.
RetroArch run-ahead can reduce lag produced inside an emulated game’s logic. It does not remove controller, operating-system, display-processing, pixel-response, or network delay. It works by advancing emulation, presenting the later result, and restoring or synchronizing state behind the scenes.
That process depends on fast, accurate core serialization and spare host performance. Measure the game’s internal lag, begin with one frame, and prove stability before saving any override.
Step 1: establish a clean latency baseline
Update RetroArch and the selected core through their trusted distribution channel, then record frontend version, core name/version, content hash, video driver, refresh mode, controller connection, and display game-mode setting. Disable shaders and experimental latency features for the baseline.
Confirm stable audio and frame pacing for several minutes. A system already missing its frame budget cannot safely add speculative emulation work. Run-ahead is not a repair for Bluetooth interference, a television’s image processing, an incorrect refresh rate, or a core running below full speed.
Step 2: preserve configuration and native saves
Quit RetroArch and back up retroarch.cfg, existing override files, core options, remaps, and native in-game saves. Save states are useful for a short test but should not be the only copy of progress because their format can change with core versions.
Return to the same title through its normal playlist and core association. Do not test several cores, drivers, and run-ahead settings simultaneously; the result would not identify which change helped or failed.
Step 3: verify core serialization behavior
Run-ahead relies on save-state serialization. Create a state in a safe test scene, advance through gameplay and audio, reload it, and check video, audio, inputs, timers, storage, and any peripheral state. Repeat after a clean RetroArch restart.
A successful notification is not sufficient if loading produces buzzing, desynchronization, missing memory-card writes, or random behavior. Some cores cannot serialize all hardware state reliably; if so, leave run-ahead disabled or follow that core’s current official recommendation.
Step 4: measure internal game lag
The official Libretro procedure is more reliable than guessing. In a repeatable scene, pause emulation, hold a simple direction or button, and advance one frame at a time until the visible response begins. The number of advances minus one is the candidate internal lag.
Repeat several times and test more than one action. Games can poll controls at different points, and animations can delay visible feedback after the logic already accepted input. Use the lowest repeatable internal-lag value; run-ahead cannot legitimately remove delay that belongs to the intended game response.
Step 5: enable one frame first
With content loaded, open Quick Menu → Latency or the corresponding Settings → Latency page and enable Run-Ahead to Reduce Latency. Set Number of Frames to Run-Ahead to 1.
Resume the same scene and look for rollback-like jumps, duplicated or missing audio, flicker, unstable timing, and save behavior. Restart content and repeat. If one frame is unstable, disable the feature; adding more frames cannot make an unreliable serialization path trustworthy.
Step 6: choose single or second-instance mode from core evidence
In single-instance mode, RetroArch repeatedly saves and loads the active core’s in-memory state. It can be efficient, but a core that does not restore audio or other state cleanly may expose artifacts.
Second-instance mode keeps a primary core for audio/state and a secondary core for ahead video. Libretro documents it as a workaround for some state-load limitations, but it costs additional memory and CPU and is not universally the best path. For example, current official core pages can recommend single-instance behavior for one core and second-instance behavior for another.
Test the mode documented for the exact core. Do not generalize one arcade core’s recommendation to every emulator.
Step 7: increase frames only to the measured value
Raise the setting one frame at a time, never beyond the lowest defensible measurement. Repeat the identical scene after each increment. If input causes a visible stutter or rollback, Libretro’s run-ahead guide identifies an excessive frame count as a likely cause.
More is not automatically better. Removing two frames from a game with one frame of internal lag means showing a speculative state the original logic could not yet have produced consistently.
Step 8: verify performance under real load
Test demanding scenes, transitions, transparency, large audio changes, and save access—not only an empty first level. Watch frame-time consistency and audio underruns as well as the nominal FPS counter. A displayed 60 FPS can hide uneven pacing.
Compare run-ahead off/on using the same content, scene, controller, driver, and display. If the host loses synchronization, first reduce run-ahead frames or disable second instance. Do not hide insufficient headroom by enabling unrelated speed hacks or overclocking emulated hardware.
Step 9: avoid stacking latency features blindly
Preemptive frames, frame delay, automatic frame delay, hard GPU synchronization, waitable swapchains, and run-ahead address different parts of the pipeline and have different platform support. The official optimal-VSync guide warns that these options can prevent smooth synchronization when set too aggressively.
Establish run-ahead independently. Add one other documented feature only after saving the previous result and rerunning the performance test. Do not enable run-ahead and preemptive frames together unless current documentation for the core/frontend explicitly supports that combination.
Step 10: test feature interactions
Verify rewind, netplay, achievements mode, recording, cheats, disc control, and save states only if the profile will use them. These features can also depend on serialization or alter execution. Current Libretro core documentation notes possible rewind/run-ahead conflicts for some cores, so “both enabled” is not a universal guarantee.
Respect RetroAchievements Hardcore restrictions and the selected client’s enforcement. Never patch a core or manipulate memory/state merely to retain competitive credit with an incompatible feature.
Step 11: save the narrowest override
Internal lag can differ by game, so a game override is safest when the measured value is title-specific:
Quick Menu → Overrides → Save Game Overrides
Use a core override only after testing representative games and confirming they share the setting. Restart RetroArch, launch the target, a second game in the same core, and an unrelated core. Confirm that only the intended scope inherits run-ahead.
Step 12: build an evidence-based acceptance record
Record baseline and final frame count, measurement method, mode, core/frontend versions, content hash, host/display/controller path, native-save test, interaction tests, and rollback file. If possible, use a high-frame-rate camera or a hardware latency tool for before/after evidence; subjective feel alone cannot isolate the pipeline stage.
The profile is ready when the measured frame count survives restart, frame pacing and audio remain clean in worst-case scenes, native saves are intact, unrelated games are unchanged, and disabling the one override restores the baseline.
Related:
Sources: