diff --git a/command.h b/command.h
index 4595ffb31e..a007c175c7 100644
--- a/command.h
+++ b/command.h
@@ -196,6 +196,7 @@ enum event_command
    CMD_EVENT_OSK_TOGGLE,
    CMD_EVENT_RECORDING_TOGGLE,
    CMD_EVENT_STREAMING_TOGGLE,
+   CMD_EVENT_RUNAHEAD_TOGGLE,
    CMD_EVENT_AI_SERVICE_TOGGLE,
    CMD_EVENT_BSV_RECORDING_TOGGLE,
    CMD_EVENT_SHADER_NEXT,
diff --git a/config.def.keybinds.h b/config.def.keybinds.h
index e71d1b5095..cc7798ab38 100644
--- a/config.def.keybinds.h
+++ b/config.def.keybinds.h
@@ -563,6 +563,13 @@ static const struct retro_keybind retro_keybinds_1[] = {
       RARCH_STREAMING_TOGGLE, NO_BTN, NO_BTN, 0,
       true
    },
+   {
+      NULL, NULL,
+      AXIS_NONE, AXIS_NONE, AXIS_NONE,
+      MENU_ENUM_LABEL_VALUE_INPUT_META_RUNAHEAD_TOGGLE, RETROK_UNKNOWN,
+      RARCH_RUNAHEAD_TOGGLE, NO_BTN, NO_BTN, 0,
+      true
+   },
    {
       NULL, NULL,
       AXIS_NONE, AXIS_NONE, AXIS_NONE,
@@ -1110,6 +1117,13 @@ static const struct retro_keybind retro_keybinds_1[] = {
       RARCH_STREAMING_TOGGLE, NO_BTN, NO_BTN, 0,
       true
    },
+   {
+      NULL, NULL,
+      AXIS_NONE, AXIS_NONE, AXIS_NONE,
+      MENU_ENUM_LABEL_VALUE_INPUT_META_RUNAHEAD_TOGGLE, RETROK_UNKNOWN,
+      RARCH_RUNAHEAD_TOGGLE, NO_BTN, NO_BTN, 0,
+      true
+   },
    {
       NULL, NULL,
       AXIS_NONE, AXIS_NONE, AXIS_NONE,
@@ -1667,6 +1681,13 @@ static const struct retro_keybind retro_keybinds_1[] = {
       RARCH_STREAMING_TOGGLE, NO_BTN, NO_BTN, 0,
       true
    },
+   {
+      NULL, NULL,
+      AXIS_NONE, AXIS_NONE, AXIS_NONE,
+      MENU_ENUM_LABEL_VALUE_INPUT_META_RUNAHEAD_TOGGLE, RETROK_UNKNOWN,
+      RARCH_RUNAHEAD_TOGGLE, NO_BTN, NO_BTN, 0,
+      true
+   },
    {
       NULL, NULL,
       AXIS_NONE, AXIS_NONE, AXIS_NONE,
diff --git a/input/input_defines.h b/input/input_defines.h
index 8146a24ece..93b855736d 100644
--- a/input/input_defines.h
+++ b/input/input_defines.h
@@ -117,6 +117,7 @@ enum
 
    RARCH_RECORDING_TOGGLE,
    RARCH_STREAMING_TOGGLE,
+   RARCH_RUNAHEAD_TOGGLE,
 
    RARCH_AI_SERVICE,
 
diff --git a/intl/msg_hash_us.c b/intl/msg_hash_us.c
index e27ca3d981..3515faf91d 100644
--- a/intl/msg_hash_us.c
+++ b/intl/msg_hash_us.c
@@ -225,6 +225,10 @@ int msg_hash_get_help_us_enum(enum msg_hash_enums msg, char *s, size_t len)
              snprintf(s, len,
                    "Toggle between recording and not.");
              break;
+          case RARCH_RUNAHEAD_TOGGLE:
+             snprintf(s, len,
+                   "Toggles Run-Ahead mode on/off.");
+             break;
           default:
              if (string_is_empty(s))
                 strlcpy(s, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NO_INFORMATION_AVAILABLE), len);
diff --git a/intl/msg_hash_us.h b/intl/msg_hash_us.h
index 03678e8a82..d6224fd80a 100644
--- a/intl/msg_hash_us.h
+++ b/intl/msg_hash_us.h
@@ -2555,6 +2555,14 @@ MSG_HASH(
    MENU_ENUM_SUBLABEL_INPUT_META_STREAMING_TOGGLE,
    "Starts/stops streaming of the current session to an online video platform."
    )
+MSG_HASH(
+   MENU_ENUM_LABEL_VALUE_INPUT_META_RUNAHEAD_TOGGLE,
+   "Run-Ahead (Toggle)"
+   )
+MSG_HASH(
+   MENU_ENUM_SUBLABEL_INPUT_META_RUNAHEAD_TOGGLE,
+   "Switches Run-Ahead on/off."
+   )
 MSG_HASH(
    MENU_ENUM_LABEL_VALUE_INPUT_META_AI_SERVICE,
    "AI Service"
@@ -11266,6 +11274,18 @@ MSG_HASH(
    MSG_CORE_REMAP_FILE_LOADED,
    "Core remap file loaded."
    )
+MSG_HASH(
+   MSG_RUNAHEAD_ENABLED,
+   "Run-Ahead enabled. Latency frames removed: %u."
+   )
+MSG_HASH(
+   MSG_RUNAHEAD_ENABLED_WITH_SECOND_INSTANCE,
+   "Run-Ahead enabled with Secondary Instance. Latency frames removed: %u."
+   )
+MSG_HASH(
+   MSG_RUNAHEAD_DISABLED,
+   "Run-Ahead disabled."
+   )
 MSG_HASH(
    MSG_RUNAHEAD_CORE_DOES_NOT_SUPPORT_SAVESTATES,
    "Run-Ahead has been disabled because this core does not support save states."
diff --git a/menu/cbs/menu_cbs_sublabel.c b/menu/cbs/menu_cbs_sublabel.c
index 7e0d9f78bf..e8a0b9c864 100644
--- a/menu/cbs/menu_cbs_sublabel.c
+++ b/menu/cbs/menu_cbs_sublabel.c
@@ -269,6 +269,7 @@ DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_input_meta_game_focus_toggle,     ME
 DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_input_meta_ui_companion_toggle,   MENU_ENUM_SUBLABEL_INPUT_META_UI_COMPANION_TOGGLE)
 DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_input_meta_recording_toggle,      MENU_ENUM_SUBLABEL_INPUT_META_RECORDING_TOGGLE)
 DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_input_meta_streaming_toggle,      MENU_ENUM_SUBLABEL_INPUT_META_STREAMING_TOGGLE)
+DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_input_meta_runahead_toggle,       MENU_ENUM_SUBLABEL_INPUT_META_RUNAHEAD_TOGGLE)
 DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_input_meta_ai_service,            MENU_ENUM_SUBLABEL_INPUT_META_AI_SERVICE)
 DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_input_meta_menu_toggle,           MENU_ENUM_SUBLABEL_INPUT_META_MENU_TOGGLE)
 DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_input_hotkey_block_delay,         MENU_ENUM_SUBLABEL_INPUT_HOTKEY_BLOCK_DELAY)
@@ -1693,6 +1694,9 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs,
             case RARCH_STREAMING_TOGGLE:
                BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_input_meta_streaming_toggle);
                return 0;
+            case RARCH_RUNAHEAD_TOGGLE:
+               BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_input_meta_runahead_toggle);
+               return 0;
             case RARCH_AI_SERVICE:
                BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_input_meta_ai_service);
                return 0;
diff --git a/msg_hash.h b/msg_hash.h
index a16105c685..3de8901e33 100644
--- a/msg_hash.h
+++ b/msg_hash.h
@@ -459,6 +459,9 @@ enum msg_hash_enums
    MSG_GAME_REMAP_FILE_LOADED,
    MSG_DIRECTORY_REMAP_FILE_LOADED,
    MSG_CORE_REMAP_FILE_LOADED,
+   MSG_RUNAHEAD_ENABLED,
+   MSG_RUNAHEAD_ENABLED_WITH_SECOND_INSTANCE,
+   MSG_RUNAHEAD_DISABLED,
    MSG_RUNAHEAD_CORE_DOES_NOT_SUPPORT_SAVESTATES,
    MSG_RUNAHEAD_FAILED_TO_SAVE_STATE,
    MSG_RUNAHEAD_FAILED_TO_LOAD_STATE,
@@ -851,6 +854,7 @@ enum msg_hash_enums
    MENU_ENUM_LABEL_VALUE_INPUT_META_UI_COMPANION_TOGGLE,
    MENU_ENUM_LABEL_VALUE_INPUT_META_RECORDING_TOGGLE,
    MENU_ENUM_LABEL_VALUE_INPUT_META_STREAMING_TOGGLE,
+   MENU_ENUM_LABEL_VALUE_INPUT_META_RUNAHEAD_TOGGLE,
    MENU_ENUM_LABEL_VALUE_INPUT_META_AI_SERVICE,
    MENU_ENUM_LABEL_VALUE_INPUT_META_MENU_TOGGLE,
 
@@ -903,6 +907,7 @@ enum msg_hash_enums
    MENU_ENUM_SUBLABEL_INPUT_META_UI_COMPANION_TOGGLE,
    MENU_ENUM_SUBLABEL_INPUT_META_RECORDING_TOGGLE,
    MENU_ENUM_SUBLABEL_INPUT_META_STREAMING_TOGGLE,
+   MENU_ENUM_SUBLABEL_INPUT_META_RUNAHEAD_TOGGLE,
    MENU_ENUM_SUBLABEL_INPUT_META_AI_SERVICE,
    MENU_ENUM_SUBLABEL_INPUT_META_MENU_TOGGLE,
 
diff --git a/retroarch.c b/retroarch.c
index 1a861d201f..8829356a8c 100644
--- a/retroarch.c
+++ b/retroarch.c
@@ -2730,6 +2730,7 @@ static const struct input_bind_map input_config_bind_map[RARCH_BIND_LIST_END_NUL
 #endif
       DECLARE_META_BIND(2, recording_toggle,      RARCH_RECORDING_TOGGLE,      MENU_ENUM_LABEL_VALUE_INPUT_META_RECORDING_TOGGLE),
       DECLARE_META_BIND(2, streaming_toggle,      RARCH_STREAMING_TOGGLE,      MENU_ENUM_LABEL_VALUE_INPUT_META_STREAMING_TOGGLE),
+      DECLARE_META_BIND(2, runahead_toggle,       RARCH_RUNAHEAD_TOGGLE,       MENU_ENUM_LABEL_VALUE_INPUT_META_RUNAHEAD_TOGGLE),
       DECLARE_META_BIND(2, ai_service,            RARCH_AI_SERVICE,            MENU_ENUM_LABEL_VALUE_INPUT_META_AI_SERVICE),
 };
 
@@ -12978,6 +12979,7 @@ static const struct cmd_map map[] = {
    { "MENU_TOGGLE",            RARCH_MENU_TOGGLE },
    { "RECORDING_TOGGLE",       RARCH_RECORDING_TOGGLE },
    { "STREAMING_TOGGLE",       RARCH_STREAMING_TOGGLE },
+   { "RUNAHEAD_TOGGLE",        RARCH_RUNAHEAD_TOGGLE },
    { "MENU_UP",                RETRO_DEVICE_ID_JOYPAD_UP },
    { "MENU_DOWN",              RETRO_DEVICE_ID_JOYPAD_DOWN },
    { "MENU_LEFT",              RETRO_DEVICE_ID_JOYPAD_LEFT },
@@ -15989,6 +15991,37 @@ bool command_event(enum event_command cmd, void *data)
             command_event(CMD_EVENT_RECORD_INIT, NULL);
          }
          break;
+      case CMD_EVENT_RUNAHEAD_TOGGLE:
+         settings->bools.run_ahead_enabled = !(settings->bools.run_ahead_enabled);
+
+         char msg[256];
+         msg[0] = '\0';
+
+         if (!settings->bools.run_ahead_enabled)
+         {
+            runloop_msg_queue_push(msg_hash_to_str(MSG_RUNAHEAD_DISABLED),
+            1, 100, false,
+            NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO);
+         }
+         else if (!settings->bools.run_ahead_secondary_instance)
+         {
+            snprintf(msg, sizeof(msg), msg_hash_to_str(MSG_RUNAHEAD_ENABLED),
+            settings->uints.run_ahead_frames);
+
+            runloop_msg_queue_push(
+            msg, 1, 100, false,
+            NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO);
+         }
+         else
+         {
+            snprintf(msg, sizeof(msg), msg_hash_to_str(MSG_RUNAHEAD_ENABLED_WITH_SECOND_INSTANCE),
+            settings->uints.run_ahead_frames);
+
+            runloop_msg_queue_push(
+            msg, 1, 100, false,
+            NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO);
+         }
+         break;
       case CMD_EVENT_RECORDING_TOGGLE:
          if (recording_is_enabled())
             command_event(CMD_EVENT_RECORD_DEINIT, NULL);
@@ -39691,12 +39724,15 @@ static enum runloop_state runloop_check_state(
    /* Check if we have pressed the recording toggle button */
    HOTKEY_CHECK(RARCH_RECORDING_TOGGLE, CMD_EVENT_RECORDING_TOGGLE, true, NULL);
 
-   /* Check if we have pressed the AI Service toggle button */
-   HOTKEY_CHECK(RARCH_AI_SERVICE, CMD_EVENT_AI_SERVICE_TOGGLE, true, NULL);
-
    /* Check if we have pressed the streaming toggle button */
    HOTKEY_CHECK(RARCH_STREAMING_TOGGLE, CMD_EVENT_STREAMING_TOGGLE, true, NULL);
 
+   /* Check if we have pressed the Run-Ahead toggle button */
+   HOTKEY_CHECK(RARCH_RUNAHEAD_TOGGLE, CMD_EVENT_RUNAHEAD_TOGGLE, true, NULL);
+
+   /* Check if we have pressed the AI Service toggle button */
+   HOTKEY_CHECK(RARCH_AI_SERVICE, CMD_EVENT_AI_SERVICE_TOGGLE, true, NULL);
+
    if (BIT256_GET(current_bits, RARCH_VOLUME_UP))
       command_event(CMD_EVENT_VOLUME_UP, NULL);
    else if (BIT256_GET(current_bits, RARCH_VOLUME_DOWN))