diff --git a/ROADMAP.md b/ROADMAP.md
--- a/ROADMAP.md
+++ b/ROADMAP.md
@@ -745,3 +745,5 @@ Newest first: the date, what moved, and the new overall estimate.
 - **2026-10-18 (renderer, hayro patches 19/35):** A mesh shading (types 4–7) is sampled over its own triangles instead of the whole path: a BricsCAD plan with 310 one-triangle `sh` fills took 2 s per 1024 px tile at every zoom (and hit the 20 s watchdog on a busy machine); now about 70 ms, so zooming into dense topology drawings stays fluid. Estimates unchanged.
 
 - **2026-10-22 (PR #3227 integration):** M11: integrate upstream `80b7d215`; retain partial target-version compatibility and upstream content-boundary and image-size regression coverage. Scope and estimates unchanged.
+- **2026-10-27 (M3, #4908):** Preferences gains "Always show the page size": the current page's size stays up at the bottom-left of the page view instead of only while the pointer is in that corner (same label and unit; off by default; saved with the settings; `set_option`/`--always-show-page-size`).
+
diff --git a/apps/pdfcraft/src/main.rs b/apps/pdfcraft/src/main.rs
--- a/apps/pdfcraft/src/main.rs
+++ b/apps/pdfcraft/src/main.rs
@@ -7,7 +7,7 @@
 //! `--page N  --zoom 150  --layout single|continuous|two-up|two-page  --continuous on|off  --panel comments|bookmarks|pages|fields|layers|attachments|none
 //!  --theme light|dark|system  --language auto|<code>  --mode all|read|edit|convert|sign  --tool <catalogue id>  --left open|closed
 //!  --organize on  --fields on  --dialog properties|shortcuts|about  --palette <query>  --home on
-//!  --cover on|off  --default-layout single|continuous|two-up|two-page  --default-continuous on|off  --default-zoom fit-width|fit-page|<percent>  --always-default-view on|off
+//!  --cover on|off  --default-layout single|continuous|two-up|two-page  --default-continuous on|off  --default-zoom fit-width|fit-page|<percent>  --always-default-view on|off  --always-show-page-size on|off
 //!  --page-gaps on|off  --default-page-gaps on|off
 //!  --combine-view grid|list  --combine-zoom 60..200`
 //!
diff --git a/crates/ui-egui/src/app.rs b/crates/ui-egui/src/app.rs
--- a/crates/ui-egui/src/app.rs
+++ b/crates/ui-egui/src/app.rs
@@ -93,6 +93,7 @@ impl PdfCraftApp {
             reload_changed_files: true,
             show_secured_notice: true,
             always_default_view: false,
+            always_show_page_size: false,
             #[cfg(not(target_arch = "wasm32"))]
             watch: Default::default(),
             #[cfg(not(target_arch = "wasm32"))]
diff --git a/crates/ui-egui/src/app/control.rs b/crates/ui-egui/src/app/control.rs
--- a/crates/ui-egui/src/app/control.rs
+++ b/crates/ui-egui/src/app/control.rs
@@ -193,6 +193,13 @@ impl PdfCraftApp {
                     _ => return Err("always-default-view must be on or off".into()),
                 };
             }
+            ("always-show-page-size", _) => {
+                self.always_show_page_size = match value {
+                    "on" => true,
+                    "off" => false,
+                    _ => return Err("always-show-page-size must be on or off".into()),
+                };
+            }
             ("tools-side", _) => {
                 self.side_panels.tools_side = match value {
                     "left" => side_panels::ToolsSide::Left,
diff --git a/crates/ui-egui/src/app/prefs.rs b/crates/ui-egui/src/app/prefs.rs
--- a/crates/ui-egui/src/app/prefs.rs
+++ b/crates/ui-egui/src/app/prefs.rs
@@ -94,6 +94,7 @@ impl PdfCraftApp {
             "default_layout": canvas::display_token(self.view_defaults.layout, self.view_defaults.continuous),
             "default_zoom": self.view_defaults.zoom_name(),
             "always_default_view": self.always_default_view,
+            "always_show_page_size": self.always_show_page_size,
             "highlight_fields": self.view_defaults.highlight_fields,
             "units": self.units,
             "language": self.language,
@@ -220,6 +221,9 @@ impl PdfCraftApp {
         if let Some(on) = v["always_default_view"].as_bool() {
             self.always_default_view = on;
         }
+        if let Some(on) = v["always_show_page_size"].as_bool() {
+            self.always_show_page_size = on;
+        }
         if let Some(paper) = v
             .get("print_paper")
             .and_then(serde_json::Value::as_str)
diff --git a/crates/ui-egui/src/canvas.rs b/crates/ui-egui/src/canvas.rs
--- a/crates/ui-egui/src/canvas.rs
+++ b/crates/ui-egui/src/canvas.rs
@@ -1251,6 +1251,7 @@ pub fn document_area(app: &mut PdfCraftApp, index: usize, ui: &mut egui::Ui) {
     let prefs = &app.comment_prefs;
     let redact_mark = (app.redact_prefs.hover_fill, app.redact_prefs.opacity);
     let units = app.units;
+    let always_page_size = app.always_show_page_size;
     let allowed = doc.allows_annotation();
     let can_copy = doc.allows_copying();
     let mut copy_selected = false;
@@ -2431,7 +2432,8 @@ pub fn document_area(app: &mut PdfCraftApp, index: usize, ui: &mut egui::Ui) {
         });
     }
     find_bar(view, info.pages.len(), avail, ui, &t);
-    page_size_hint(view, info, units, avail, unobstructed, ui, &t);
+    let page_size = info.pages.get(view.current).map(|p| (p.width, p.height));
+    page_size_hint(page_size, units, always_page_size, avail, unobstructed, ui, &t);
     if tool == QuickTool::EnhanceCamera {
         crate::camera_ui::bar(ui.ctx(), view, avail, &t, can_modify);
     }
diff --git a/crates/ui-egui/src/canvas/bars.rs b/crates/ui-egui/src/canvas/bars.rs
--- a/crates/ui-egui/src/canvas/bars.rs
+++ b/crates/ui-egui/src/canvas/bars.rs
@@ -6,23 +6,26 @@ pub(super) fn in_size_hint_zone(area: Rect, p: Pos2) -> bool {
 }
 
 /// The current page's size, floating at the bottom-left of the document area while the pointer is
-/// in that quadrant, as Acrobat does. Same formatter and unit as Document Properties.
+/// in that quadrant, as Acrobat does, or all the time when `always` is set (#4908). Same
+/// formatter and unit as Document Properties.
 pub(super) fn page_size_hint(
-    view: &DocView,
-    info: &DocInfo,
+    size: Option<(f32, f32)>,
     units: crate::units::Unit,
+    always: bool,
     area: Rect,
     unobstructed: bool,
     ui: &mut egui::Ui,
     t: &Tokens,
 ) {
-    let Some(page) = info.pages.get(view.current) else { return };
-    let inside = unobstructed && ui.input(|i| i.pointer.hover_pos()).is_some_and(|p| in_size_hint_zone(area, p));
-    if !inside {
+    let Some((width, height)) = size else { return };
+    let inside = ui.input(|i| i.pointer.hover_pos()).is_some_and(|p| in_size_hint_zone(area, p));
+    // Under a dialog or the palette the label stays hidden, whatever the preference says.
+    if !unobstructed || !(always || inside) {
         return;
     }
-    let text = units.size(f64::from(page.width), f64::from(page.height));
-    egui::Area::new(egui::Id::unique("page-size-hint"))
+    let text = units.size(f64::from(width), f64::from(height));
+    // One per document view: a side-by-side comparison draws two at once.
+    egui::Area::new(ui.scope_id().with("page-size-hint"))
         .order(egui::Order::Foreground)
         .interactable(false)
         .pivot(egui::Align2::LEFT_BOTTOM)
diff --git a/crates/ui-egui/src/lib.rs b/crates/ui-egui/src/lib.rs
--- a/crates/ui-egui/src/lib.rs
+++ b/crates/ui-egui/src/lib.rs
@@ -344,6 +344,9 @@ pub struct PdfCraftApp {
     /// Preferences: open every document at Default zoom and Default page display, whatever
     /// layout or zoom it asks for (#1618).
     pub always_default_view: bool,
+    /// Preferences: keep the current page's size showing at the bottom-left of the page view,
+    /// not only while the pointer is in that corner (#4908).
+    pub always_show_page_size: bool,
     /// Open documents' files, watched for changes on disk.
     #[cfg(not(target_arch = "wasm32"))]
     pub(crate) watch: file_watch::FileWatch,
diff --git a/crates/ui-egui/src/workflows/js_ui.rs b/crates/ui-egui/src/workflows/js_ui.rs
--- a/crates/ui-egui/src/workflows/js_ui.rs
+++ b/crates/ui-egui/src/workflows/js_ui.rs
@@ -447,6 +447,7 @@ pub(crate) fn preferences_body(ui: &mut egui::Ui, app: &mut PdfCraftApp, t: &Tok
         }
     });
     ui.label(egui::RichText::new(tl!("For page sizes and margins.")).small().color(t.text_muted));
+    ui.add(widgets::checkbox(&mut app.always_show_page_size, tl!("Always show the page size")));
     // The web build has no file paths to reopen.
     #[cfg(not(target_arch = "wasm32"))]
     ui.add(widgets::checkbox(&mut app.reopen_last_session, tl!("Reopen the files that were open when PdfCraft last closed")));
diff --git a/crates/ui-egui/tests/it/compare.rs b/crates/ui-egui/tests/it/compare.rs
--- a/crates/ui-egui/tests/it/compare.rs
+++ b/crates/ui-egui/tests/it/compare.rs
@@ -279,3 +279,14 @@ fn export_to_word_html_and_rtf() {
     }
     assert!(std::fs::read_to_string(dir.join("e.html")).unwrap().contains("Exported words"));
 }
+
+/// #4908: with the page size always on, each half of a side-by-side comparison shows its own label.
+#[test]
+fn each_half_of_a_comparison_shows_its_own_page_size() {
+    let mut h = side_by_side();
+    let labels = |h: &Harness<'static, PdfCraftApp>| h.query_all_by_label_contains(" × ").count();
+    assert_eq!(labels(&h), 0, "off by default, with the pointer away from the corners");
+    h.state_mut().set_option("always-show-page-size", "on").unwrap();
+    h.run_steps(4);
+    assert_eq!(labels(&h), 2, "one label per half");
+}
diff --git a/crates/ui-egui/tests/it/control.rs b/crates/ui-egui/tests/it/control.rs
--- a/crates/ui-egui/tests/it/control.rs
+++ b/crates/ui-egui/tests/it/control.rs
@@ -1971,28 +1971,64 @@ fn click_and_drag_refuse_coordinates_that_overflow_like_move() {
     ok(&mut h, &c, "ui.drag", json!({ "from": [x, y], "to": [x + 10.0, y], "steps": 2 }));
 }
 
+/// How many page-size labels (`612 × 792 pt`) are on screen.
+fn size_labels(h: &Harness<'static, PdfCraftApp>) -> usize {
+    h.query_all_by_label_contains(" × ").count()
+}
+
 #[test]
 fn page_size_shows_while_the_pointer_is_in_the_bottom_left_quadrant() {
     let (mut h, _c) = harness();
     let area = h.state().views[0].viewport_rect();
-    let shown = |h: &Harness<'static, PdfCraftApp>| {
-        let layer = egui::LayerId::new(egui::Order::Foreground, egui::Id::unique("page-size-hint"));
-        h.ctx.memory(|m| m.areas().visible_last_frame(&layer))
-    };
+    let shown = size_labels;
     let away = area.center() + egui::vec2(300.0, -200.0);
     h.event(egui::Event::PointerMoved(away));
     h.run_steps(3);
-    assert!(!shown(&h), "top-right: hidden");
+    assert_eq!(shown(&h), 0, "top-right: hidden");
     h.event(egui::Event::PointerMoved(area.left_bottom() + egui::vec2(80.0, -80.0)));
     h.run_steps(3);
-    assert!(shown(&h), "bottom-left: shown");
+    assert_eq!(shown(&h), 1, "bottom-left: shown");
     if let Ok(dir) = std::env::var("PDFCRAFT_SHOT_DIR") {
         let _gpu = crate::gpu();
         h.render().unwrap().save(format!("{dir}/page-size-hint.png")).unwrap();
     }
     h.event(egui::Event::PointerMoved(away));
     h.run_steps(3);
-    assert!(!shown(&h), "pointer left: hidden again");
+    assert_eq!(shown(&h), 0, "pointer left: hidden again");
+}
+
+/// #4908: with "Always show the page size" on, the label stays up wherever the pointer is.
+#[test]
+fn page_size_stays_up_when_always_show_is_on() {
+    let (mut h, _c) = harness();
+    let area = h.state().views[0].viewport_rect();
+    let shown = size_labels;
+    let away = area.center() + egui::vec2(300.0, -200.0);
+    h.event(egui::Event::PointerMoved(away));
+    h.run_steps(3);
+    assert_eq!(shown(&h), 0, "off by default: hidden away from the corner");
+    h.state_mut().set_option("always-show-page-size", "on").unwrap();
+    h.run_steps(3);
+    assert_eq!(shown(&h), 1, "on: shown with the pointer elsewhere");
+    h.state_mut().set_option("always-show-page-size", "off").unwrap();
+    h.run_steps(3);
+    assert_eq!(shown(&h), 0, "off again: hidden");
+    assert!(h.state_mut().set_option("always-show-page-size", "maybe").is_err());
+}
+
+/// The label stays under a dialog: ticking the preference in an open dialog does not bring it up.
+#[test]
+fn page_size_stays_hidden_under_a_dialog_even_when_always_show_is_on() {
+    let (mut h, _c) = harness();
+    h.state_mut().set_option("dialog", "preferences").unwrap();
+    h.run_steps(4);
+    h.state_mut().set_option("always-show-page-size", "on").unwrap();
+    h.run_steps(4);
+    assert!(h.state().dialog.is_some());
+    assert_eq!(size_labels(&h), 0, "hidden under Preferences");
+    h.state_mut().dialog = None;
+    h.run_steps(4);
+    assert_eq!(size_labels(&h), 1, "back once the dialog is closed");
 }
 
 #[test]
diff --git a/crates/ui-egui/tests/it/preferences_layout.rs b/crates/ui-egui/tests/it/preferences_layout.rs
--- a/crates/ui-egui/tests/it/preferences_layout.rs
+++ b/crates/ui-egui/tests/it/preferences_layout.rs
@@ -96,3 +96,25 @@ fn a_very_tall_window_does_not_leave_a_blank_gap_above_ok() {
     assert!(on_screen(ok, 2600.0) && on_screen(last, 2600.0), "{last:?} {ok:?}");
     assert!(ok.min.y - last.max.y < 120.0, "a gap of {} pt between the last setting and OK", ok.min.y - last.max.y);
 }
+
+/// #4908: the "Always show the page size" checkbox is in Preferences and turns the setting on and off.
+#[test]
+fn the_always_show_page_size_checkbox_sets_the_preference() {
+    // Wide enough that the menu bar shows every menu: its overflow "⋯" has no glyph in a bare test font set.
+    let mut h = Harness::builder().with_size(egui::vec2(1400.0, 900.0)).build_eframe(|_cc| {
+        let mut app = PdfCraftApp::new();
+        app.set_option("language", "en").unwrap();
+        app.set_option("dialog", "preferences").unwrap();
+        app
+    });
+    h.run_steps(6);
+    assert!(!h.state().always_show_page_size);
+    h.get_by_label("Always show the page size").scroll_to_me();
+    h.run_steps(4);
+    h.get_by_label("Always show the page size").click();
+    h.run_steps(3);
+    assert!(h.state().always_show_page_size, "ticked");
+    h.get_by_label("Always show the page size").click();
+    h.run_steps(3);
+    assert!(!h.state().always_show_page_size, "unticked");
+}
diff --git a/crates/ui-egui/tests/it/view.rs b/crates/ui-egui/tests/it/view.rs
--- a/crates/ui-egui/tests/it/view.rs
+++ b/crates/ui-egui/tests/it/view.rs
@@ -2257,3 +2257,18 @@ fn the_pages_panel_tools_are_off_without_page_editing_permission() {
     assert!(h.query_by_label("Delete the selected pages").is_none(), "its menu doesn't open");
     assert_eq!(h.state().session.get(id).unwrap().info.pages.len(), 3);
 }
+
+#[test]
+fn always_show_the_page_size_survives_a_restart() {
+    let mut app = PdfCraftApp::new();
+    assert!(!app.always_show_page_size, "off by default");
+    app.always_show_page_size = true;
+    let mut restarted = PdfCraftApp::new();
+    restarted.restore(&app.persist());
+    assert!(restarted.always_show_page_size, "the choice is kept");
+    restarted.restore(r#"{"always_show_page_size":"bogus"}"#);
+    assert!(restarted.always_show_page_size, "garbage leaves it alone");
+    let mut legacy = PdfCraftApp::new();
+    legacy.restore("{}");
+    assert!(!legacy.always_show_page_size, "a legacy file without the key keeps it off");
+}
diff --git a/parity/acrobat-features.toml b/parity/acrobat-features.toml
--- a/parity/acrobat-features.toml
+++ b/parity/acrobat-features.toml
@@ -1214,8 +1214,8 @@ milestone = "M3"
 status = "shipped"
 commands = []
 tools = []
-evidence = ["crates/ui-egui/tests/it/control.rs::page_size_shows_while_the_pointer_is_in_the_bottom_left_quadrant", "crates/ui-egui/src/canvas/tests.rs::page_size_hint_zone_is_the_bottom_left_quadrant"]
-notes = "While the pointer is in the bottom-left quadrant of the page view, a small label shows the current page's size (after /Rotate and /UserUnit) in the Preferences unit, formatted as in Document Properties (#1855). It never takes clicks and hides when the pointer leaves. Acrobat's trigger is the corner itself and may differ in exact area and wording (not compared with real Acrobat); the size of the current page only, not of the page under the pointer; no headless tool (page sizes are in document info)."
+evidence = ["crates/ui-egui/tests/it/control.rs::page_size_shows_while_the_pointer_is_in_the_bottom_left_quadrant", "crates/ui-egui/src/canvas/tests.rs::page_size_hint_zone_is_the_bottom_left_quadrant", "crates/ui-egui/tests/it/control.rs::page_size_stays_up_when_always_show_is_on", "crates/ui-egui/tests/it/preferences_layout.rs::the_always_show_page_size_checkbox_sets_the_preference", "crates/ui-egui/tests/it/view.rs::always_show_the_page_size_survives_a_restart"]
+notes = "While the pointer is in the bottom-left quadrant of the page view, a small label shows the current page's size (after /Rotate and /UserUnit) in the Preferences unit, formatted as in Document Properties (#1855). It never takes clicks and hides when the pointer leaves. Acrobat's trigger is the corner itself and may differ in exact area and wording (not compared with real Acrobat); the size of the current page only, not of the page under the pointer; no headless tool (page sizes are in document info). Preferences ▸ Documents and view ▸ Always show the page size (and `--always-show-page-size on|off`, `set_option`) keeps the label up whatever the pointer does, in the same unit; it is saved with the settings and off by default (#4908). It is the same label in the same corner, not a separate status bar."
 
 [[feature]]
 id = "view.document-tabs"
