diff --git a/src/common/settings.h b/src/common/settings.h
index 6198f2d9fd..bc3298417b 100644
--- a/src/common/settings.h
+++ b/src/common/settings.h
@@ -149,6 +149,7 @@ struct Values {
     Setting<bool> use_nvdec_emulation;
     Setting<bool> accelerate_astc;
     Setting<bool> use_vsync;
+    Setting<bool> disable_fps_limit;
     Setting<bool> use_assembly_shaders;
     Setting<bool> use_asynchronous_shaders;
     Setting<bool> use_fast_gpu_time;
diff --git a/src/core/hle/service/nvflinger/nvflinger.cpp b/src/core/hle/service/nvflinger/nvflinger.cpp
index d1dbc659be..1d810562ff 100644
--- a/src/core/hle/service/nvflinger/nvflinger.cpp
+++ b/src/core/hle/service/nvflinger/nvflinger.cpp
@@ -307,6 +307,9 @@ void NVFlinger::Compose() {
 }
 
 s64 NVFlinger::GetNextTicks() const {
+    if (Settings::values.disable_fps_limit.GetValue()) {
+        return 0;
+    }
     constexpr s64 max_hertz = 120LL;
     return (1000000000 * (1LL << swap_interval)) / max_hertz;
 }
diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp
index 916a227241..24487314ef 100644
--- a/src/yuzu/configuration/config.cpp
+++ b/src/yuzu/configuration/config.cpp
@@ -221,7 +221,7 @@ const std::array<int, Settings::NativeKeyboard::NumKeyboardMods> Config::default
 // This must be in alphabetical order according to action name as it must have the same order as
 // UISetting::values.shortcuts, which is alphabetically ordered.
 // clang-format off
-const std::array<UISettings::Shortcut, 17> Config::default_hotkeys{{
+const std::array<UISettings::Shortcut, 18> Config::default_hotkeys{{
     {QStringLiteral("Capture Screenshot"),       QStringLiteral("Main Window"), {QStringLiteral("Ctrl+P"), Qt::WidgetWithChildrenShortcut}},
     {QStringLiteral("Change Docked Mode"),       QStringLiteral("Main Window"), {QStringLiteral("F10"), Qt::ApplicationShortcut}},
     {QStringLiteral("Continue/Pause Emulation"), QStringLiteral("Main Window"), {QStringLiteral("F4"), Qt::WindowShortcut}},
@@ -236,6 +236,7 @@ const std::array<UISettings::Shortcut, 17> Config::default_hotkeys{{
     {QStringLiteral("Restart Emulation"),        QStringLiteral("Main Window"), {QStringLiteral("F6"), Qt::WindowShortcut}},
     {QStringLiteral("Stop Emulation"),           QStringLiteral("Main Window"), {QStringLiteral("F5"), Qt::WindowShortcut}},
     {QStringLiteral("Toggle Filter Bar"),        QStringLiteral("Main Window"), {QStringLiteral("Ctrl+F"), Qt::WindowShortcut}},
+    {QStringLiteral("Toggle Framerate Limit"),   QStringLiteral("Main Window"), {QStringLiteral("Ctrl+U"), Qt::ApplicationShortcut}},
     {QStringLiteral("Toggle Mouse Panning"),     QStringLiteral("Main Window"), {QStringLiteral("Ctrl+F9"), Qt::ApplicationShortcut}},
     {QStringLiteral("Toggle Speed Limit"),       QStringLiteral("Main Window"), {QStringLiteral("Ctrl+Z"), Qt::ApplicationShortcut}},
     {QStringLiteral("Toggle Status Bar"),        QStringLiteral("Main Window"), {QStringLiteral("Ctrl+S"), Qt::WindowShortcut}},
@@ -811,6 +812,8 @@ void Config::ReadRendererValues() {
                       true);
     ReadSettingGlobal(Settings::values.accelerate_astc, QStringLiteral("accelerate_astc"), true);
     ReadSettingGlobal(Settings::values.use_vsync, QStringLiteral("use_vsync"), true);
+    ReadSettingGlobal(Settings::values.disable_fps_limit, QStringLiteral("disable_fps_limit"),
+                      false);
     ReadSettingGlobal(Settings::values.use_assembly_shaders, QStringLiteral("use_assembly_shaders"),
                       false);
     ReadSettingGlobal(Settings::values.use_asynchronous_shaders,
@@ -1395,6 +1398,8 @@ void Config::SaveRendererValues() {
                        true);
     WriteSettingGlobal(QStringLiteral("accelerate_astc"), Settings::values.accelerate_astc, true);
     WriteSettingGlobal(QStringLiteral("use_vsync"), Settings::values.use_vsync, true);
+    WriteSettingGlobal(QStringLiteral("disable_fps_limit"), Settings::values.disable_fps_limit,
+                       false);
     WriteSettingGlobal(QStringLiteral("use_assembly_shaders"),
                        Settings::values.use_assembly_shaders, false);
     WriteSettingGlobal(QStringLiteral("use_asynchronous_shaders"),
diff --git a/src/yuzu/configuration/config.h b/src/yuzu/configuration/config.h
index ce3355588b..3c1de0ac91 100644
--- a/src/yuzu/configuration/config.h
+++ b/src/yuzu/configuration/config.h
@@ -42,7 +42,7 @@ public:
         default_mouse_buttons;
     static const std::array<int, Settings::NativeKeyboard::NumKeyboardKeys> default_keyboard_keys;
     static const std::array<int, Settings::NativeKeyboard::NumKeyboardMods> default_keyboard_mods;
-    static const std::array<UISettings::Shortcut, 17> default_hotkeys;
+    static const std::array<UISettings::Shortcut, 18> default_hotkeys;
 
 private:
     void Initialize(const std::string& config_name);
diff --git a/src/yuzu/configuration/configure_graphics_advanced.cpp b/src/yuzu/configuration/configure_graphics_advanced.cpp
index 35bf9c6be5..1af87e849f 100644
--- a/src/yuzu/configuration/configure_graphics_advanced.cpp
+++ b/src/yuzu/configuration/configure_graphics_advanced.cpp
@@ -28,6 +28,7 @@ void ConfigureGraphicsAdvanced::SetConfiguration() {
     ui->anisotropic_filtering_combobox->setEnabled(runtime_lock);
 
     ui->use_vsync->setChecked(Settings::values.use_vsync.GetValue());
+    ui->disable_fps_limit->setChecked(Settings::values.disable_fps_limit.GetValue());
     ui->use_assembly_shaders->setChecked(Settings::values.use_assembly_shaders.GetValue());
     ui->use_asynchronous_shaders->setChecked(Settings::values.use_asynchronous_shaders.GetValue());
     ui->use_fast_gpu_time->setChecked(Settings::values.use_fast_gpu_time.GetValue());
@@ -57,6 +58,8 @@ void ConfigureGraphicsAdvanced::ApplyConfiguration() {
     ConfigurationShared::ApplyPerGameSetting(&Settings::values.max_anisotropy,
                                              ui->anisotropic_filtering_combobox);
     ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_vsync, ui->use_vsync, use_vsync);
+    ConfigurationShared::ApplyPerGameSetting(&Settings::values.disable_fps_limit,
+                                             ui->disable_fps_limit, disable_fps_limit);
     ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_assembly_shaders,
                                              ui->use_assembly_shaders, use_assembly_shaders);
     ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_asynchronous_shaders,
@@ -97,6 +100,7 @@ void ConfigureGraphicsAdvanced::SetupPerGameUI() {
     if (Settings::IsConfiguringGlobal()) {
         ui->gpu_accuracy->setEnabled(Settings::values.gpu_accuracy.UsingGlobal());
         ui->use_vsync->setEnabled(Settings::values.use_vsync.UsingGlobal());
+        ui->disable_fps_limit->setEnabled(Settings::values.disable_fps_limit.UsingGlobal());
         ui->use_assembly_shaders->setEnabled(Settings::values.use_assembly_shaders.UsingGlobal());
         ui->use_asynchronous_shaders->setEnabled(
             Settings::values.use_asynchronous_shaders.UsingGlobal());
@@ -108,6 +112,8 @@ void ConfigureGraphicsAdvanced::SetupPerGameUI() {
     }
 
     ConfigurationShared::SetColoredTristate(ui->use_vsync, Settings::values.use_vsync, use_vsync);
+    ConfigurationShared::SetColoredTristate(ui->disable_fps_limit,
+                                            Settings::values.disable_fps_limit, disable_fps_limit);
     ConfigurationShared::SetColoredTristate(
         ui->use_assembly_shaders, Settings::values.use_assembly_shaders, use_assembly_shaders);
     ConfigurationShared::SetColoredTristate(ui->use_asynchronous_shaders,
diff --git a/src/yuzu/configuration/configure_graphics_advanced.h b/src/yuzu/configuration/configure_graphics_advanced.h
index e61b571c7f..c19c348515 100644
--- a/src/yuzu/configuration/configure_graphics_advanced.h
+++ b/src/yuzu/configuration/configure_graphics_advanced.h
@@ -35,6 +35,7 @@ private:
     std::unique_ptr<Ui::ConfigureGraphicsAdvanced> ui;
 
     ConfigurationShared::CheckState use_vsync;
+    ConfigurationShared::CheckState disable_fps_limit;
     ConfigurationShared::CheckState use_assembly_shaders;
     ConfigurationShared::CheckState use_asynchronous_shaders;
     ConfigurationShared::CheckState use_fast_gpu_time;
diff --git a/src/yuzu/configuration/configure_graphics_advanced.ui b/src/yuzu/configuration/configure_graphics_advanced.ui
index 846a30586d..824cb2fb2b 100644
--- a/src/yuzu/configuration/configure_graphics_advanced.ui
+++ b/src/yuzu/configuration/configure_graphics_advanced.ui
@@ -76,6 +76,24 @@
           </property>
          </widget>
         </item>
+        <item>
+         <widget class="QCheckBox" name="disable_fps_limit">
+          <property name="enabled">
+           <bool>true</bool>
+          </property>
+          <property name="toolTip">
+           <string>
+            &lt;html&gt;&lt;head/&gt;&lt;body&gt;
+            &lt;p&gt;Presents guest frames as they become available, disabling the FPS limit in most titles.&lt;/p&gt;
+            &lt;p&gt;NOTE: Will cause instabilities.&lt;/p&gt;
+            &lt;/body&gt;&lt;/html&gt;
+           </string>
+          </property>
+          <property name="text">
+           <string>Disable framerate limit (experimental)</string>
+          </property>
+         </widget>
+        </item>
         <item>
          <widget class="QCheckBox" name="use_assembly_shaders">
           <property name="toolTip">
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp
index be8933c5c1..d4c7d2c0b9 100644
--- a/src/yuzu/main.cpp
+++ b/src/yuzu/main.cpp
@@ -1025,7 +1025,11 @@ void GMainWindow::InitializeHotkeys() {
     connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Mute Audio"), this),
             &QShortcut::activated, this,
             [] { Settings::values.audio_muted = !Settings::values.audio_muted; });
-
+    connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Toggle Framerate Limit"), this),
+            &QShortcut::activated, this, [] {
+                Settings::values.disable_fps_limit.SetValue(
+                    !Settings::values.disable_fps_limit.GetValue());
+            });
     connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Toggle Mouse Panning"), this),
             &QShortcut::activated, this, [&] {
                 Settings::values.mouse_panning = !Settings::values.mouse_panning;
diff --git a/src/yuzu_cmd/config.cpp b/src/yuzu_cmd/config.cpp
index 621b315710..60bf66ec04 100644
--- a/src/yuzu_cmd/config.cpp
+++ b/src/yuzu_cmd/config.cpp
@@ -443,6 +443,8 @@ void Config::ReadValues() {
         sdl2_config->GetBoolean("Renderer", "use_asynchronous_gpu_emulation", true));
     Settings::values.use_vsync.SetValue(
         static_cast<u16>(sdl2_config->GetInteger("Renderer", "use_vsync", 1)));
+    Settings::values.disable_fps_limit.SetValue(
+        sdl2_config->GetBoolean("Renderer", "disable_fps_limit", false));
     Settings::values.use_assembly_shaders.SetValue(
         sdl2_config->GetBoolean("Renderer", "use_assembly_shaders", true));
     Settings::values.use_asynchronous_shaders.SetValue(
diff --git a/src/yuzu_cmd/default_ini.h b/src/yuzu_cmd/default_ini.h
index 37d895ebdd..c960ccf899 100644
--- a/src/yuzu_cmd/default_ini.h
+++ b/src/yuzu_cmd/default_ini.h
@@ -362,6 +362,9 @@ use_debug_asserts =
 use_auto_stub =
 # Enables/Disables the macro JIT compiler
 disable_macro_jit=false
+# Presents guest frames as they become available. Experimental.
+# false: Disabled (default), true: Enabled
+disable_fps_limit=false
 
 [WebService]
 # Whether or not to enable telemetry