diff --git a/Cargo.lock b/Cargo.lock
index be93056fcb32..0c85eaa68a91 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -4219,9 +4219,9 @@ checksum = "14247bb57be4f377dfb94c72830b8ce8fc6beac03cf4bf7b9732eadd414123fc"
 
 [[package]]
 name = "wgpu"
-version = "0.19.0"
+version = "0.19.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d0b71d2ded29e2161db50ab731d6cb42c037bd7ab94864a98fa66ff36b4721a8"
+checksum = "0bfe9a310dcf2e6b85f00c46059aaeaf4184caa8e29a1ecd4b7a704c3482332d"
 dependencies = [
  "arrayvec",
  "cfg-if",
diff --git a/Cargo.toml b/Cargo.toml
index 9fa472ba6792..67f0806ed813 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -53,7 +53,7 @@ glow = "0.13"
 puffin = "0.18"
 raw-window-handle = "0.6.0"
 thiserror = "1.0.37"
-wgpu = { version = "0.19", features = [
+wgpu = { version = "0.19.1", features = [
     # Make the renderer `Sync` even on wasm32, because it makes the code simpler:
     "fragile-send-sync-non-atomic-wasm",
 ] }
diff --git a/crates/egui-wgpu/src/lib.rs b/crates/egui-wgpu/src/lib.rs
index 6a43598da866..66caf2616c07 100644
--- a/crates/egui-wgpu/src/lib.rs
+++ b/crates/egui-wgpu/src/lib.rs
@@ -228,6 +228,15 @@ pub struct WgpuConfiguration {
     /// Present mode used for the primary surface.
     pub present_mode: wgpu::PresentMode,
 
+    /// Desired maximum number of frames that the presentation engine should queue in advance.
+    ///
+    /// Use `1` for low-latency, and `2` for high-throughput.
+    ///
+    /// See [`wgpu::SurfaceConfiguration::desired_maximum_frame_latency`] for details.
+    ///
+    /// `None` = `wgpu` default.
+    pub desired_maximum_frame_latency: Option<u32>,
+
     /// Power preference for the adapter.
     pub power_preference: wgpu::PowerPreference,
 
@@ -237,10 +246,22 @@ pub struct WgpuConfiguration {
 
 impl std::fmt::Debug for WgpuConfiguration {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        let Self {
+            supported_backends,
+            device_descriptor: _,
+            present_mode,
+            desired_maximum_frame_latency,
+            power_preference,
+            on_surface_error: _,
+        } = self;
         f.debug_struct("WgpuConfiguration")
-            .field("supported_backends", &self.supported_backends)
-            .field("present_mode", &self.present_mode)
-            .field("power_preference", &self.power_preference)
+            .field("supported_backends", &supported_backends)
+            .field("present_mode", &present_mode)
+            .field(
+                "desired_maximum_frame_latency",
+                &desired_maximum_frame_latency,
+            )
+            .field("power_preference", &power_preference)
             .finish_non_exhaustive()
     }
 }
@@ -274,6 +295,8 @@ impl Default for WgpuConfiguration {
 
             present_mode: wgpu::PresentMode::AutoVsync,
 
+            desired_maximum_frame_latency: None,
+
             power_preference: wgpu::util::power_preference_from_env()
                 .unwrap_or(wgpu::PowerPreference::HighPerformance),
 
diff --git a/crates/egui-wgpu/src/winit.rs b/crates/egui-wgpu/src/winit.rs
index 15460686205a..ca292212a152 100644
--- a/crates/egui-wgpu/src/winit.rs
+++ b/crates/egui-wgpu/src/winit.rs
@@ -142,7 +142,7 @@ impl Painter {
     fn configure_surface(
         surface_state: &SurfaceState,
         render_state: &RenderState,
-        present_mode: wgpu::PresentMode,
+        config: &WgpuConfiguration,
     ) {
         crate::profile_function!();
 
@@ -155,21 +155,25 @@ impl Painter {
         let width = surface_state.width;
         let height = surface_state.height;
 
-        surface_state.surface.configure(
-            &render_state.device,
-            &wgpu::SurfaceConfiguration {
-                // TODO(emilk): expose `desired_maximum_frame_latency` to eframe users
-                usage,
-                format: render_state.target_format,
-                present_mode,
-                alpha_mode: surface_state.alpha_mode,
-                view_formats: vec![render_state.target_format],
-                ..surface_state
-                    .surface
-                    .get_default_config(&render_state.adapter, width, height)
-                    .expect("The surface isn't supported by this adapter")
-            },
-        );
+        let mut surf_config = wgpu::SurfaceConfiguration {
+            usage,
+            format: render_state.target_format,
+            present_mode: config.present_mode,
+            alpha_mode: surface_state.alpha_mode,
+            view_formats: vec![render_state.target_format],
+            ..surface_state
+                .surface
+                .get_default_config(&render_state.adapter, width, height)
+                .expect("The surface isn't supported by this adapter")
+        };
+
+        if let Some(desired_maximum_frame_latency) = config.desired_maximum_frame_latency {
+            surf_config.desired_maximum_frame_latency = desired_maximum_frame_latency;
+        }
+
+        surface_state
+            .surface
+            .configure(&render_state.device, &surf_config);
     }
 
     /// Updates (or clears) the [`winit::window::Window`] associated with the [`Painter`]
@@ -328,7 +332,7 @@ impl Painter {
         surface_state.width = width;
         surface_state.height = height;
 
-        Self::configure_surface(surface_state, render_state, self.configuration.present_mode);
+        Self::configure_surface(surface_state, render_state, &self.configuration);
 
         if let Some(depth_format) = self.depth_format {
             self.depth_texture_view.insert(
@@ -525,11 +529,7 @@ impl Painter {
             Ok(frame) => frame,
             Err(err) => match (*self.configuration.on_surface_error)(err) {
                 SurfaceErrorAction::RecreateSurface => {
-                    Self::configure_surface(
-                        surface_state,
-                        render_state,
-                        self.configuration.present_mode,
-                    );
+                    Self::configure_surface(surface_state, render_state, &self.configuration);
                     return None;
                 }
                 SurfaceErrorAction::SkipFrame => {