diff --git a/addons/web/static/src/views/fields/domain/domain_field.js b/addons/web/static/src/views/fields/domain/domain_field.js
index 37719cea4c104..3c27a2958ef3a 100644
--- a/addons/web/static/src/views/fields/domain/domain_field.js
+++ b/addons/web/static/src/views/fields/domain/domain_field.js
@@ -25,10 +25,12 @@ export class DomainField extends Component {
         editInDialog: { type: Boolean, optional: true },
         resModel: { type: String, optional: true },
         isFoldable: { type: Boolean, optional: true },
+        countLimit: { type: Number, optional: true },
     };
     static defaultProps = {
         editInDialog: false,
         isFoldable: false,
+        countLimit: 10000,
     };
 
     setup() {
@@ -41,6 +43,7 @@ export class DomainField extends Component {
         this.state = useState({
             isValid: null,
             recordCount: null,
+            hasLimitedCount: null,
             folded: this.props.isFoldable,
             facets: [],
         });
@@ -169,24 +172,32 @@ export class DomainField extends Component {
 
         const domain = this.getEvaluatedDomain(props);
         if (domain.isInvalid) {
-            this.updateState({ isValid: false, recordCount: 0 });
+            this.updateState({ isValid: false, recordCount: 0, hasLimitedCount: false });
             return;
         }
 
         let recordCount;
+        let hasLimitedCount = false;
         const context = this.getContext(props);
+        let limit;
+        if (props.countLimit !== Number.MAX_SAFE_INTEGER) {
+            limit = props.countLimit + 1;
+        }
         try {
-            recordCount = await this.orm.silent.searchCount(resModel, domain, { context });
+            recordCount = await this.orm.silent.searchCount(resModel, domain, { context, limit });
         } catch (error) {
             if (error.data?.name === "builtins.KeyError" && error.data.message === resModel) {
                 // we don't want to support invalid models
                 throw new Error(`Invalid model: ${resModel}`);
             }
-            this.updateState({ isValid: false, recordCount: 0 });
+            this.updateState({ isValid: false, recordCount: 0, hasLimitedCount: false });
             return;
         }
-
-        this.updateState({ isValid: true, recordCount });
+        if (limit && recordCount >= limit) {
+            hasLimitedCount = true;
+            recordCount = props.countLimit;
+        }
+        this.updateState({ isValid: true, recordCount, hasLimitedCount });
     }
 
     onButtonClick() {
@@ -256,6 +267,7 @@ export class DomainField extends Component {
         Object.assign(this.state, {
             isValid: "isValid" in params ? params.isValid : null,
             recordCount: "recordCount" in params ? params.recordCount : null,
+            hasLimitedCount: "hasLimitedCount" in params ? params.hasLimitedCount : null,
         });
     }
 }
@@ -280,6 +292,11 @@ export const domainField = {
             name: "model",
             type: "string",
         },
+        {
+            label: _t("Count Limit"),
+            name: "count_limit",
+            type: "number",
+        },
     ],
     supportedTypes: ["char"],
     isEmpty: () => false,
@@ -288,6 +305,7 @@ export const domainField = {
             editInDialog: options.in_dialog,
             isFoldable: options.foldable,
             resModel: options.model,
+            countLimit: options.count_limit,
             context: dynamicInfo.context,
         };
     },
diff --git a/addons/web/static/src/views/fields/domain/domain_field.xml b/addons/web/static/src/views/fields/domain/domain_field.xml
index 76563237337be..9cba8ea9aaed4 100644
--- a/addons/web/static/src/views/fields/domain/domain_field.xml
+++ b/addons/web/static/src/views/fields/domain/domain_field.xml
@@ -32,7 +32,7 @@
                             </t>
                             <t t-if="state.isValid">
                                 <button class="btn btn-sm btn-link o_domain_show_selection_button" data-tooltip="Show matching records" type="button" t-on-click.stop="onButtonClick">
-                                    <t t-esc="state.recordCount" /> record(s)
+                                    <t t-esc="state.recordCount" /><t t-if="state.hasLimitedCount">+</t> record(s)
                                 </button>
                             </t>
                         </div>
@@ -61,7 +61,7 @@
                         <t t-else="">
                             <t t-if="state.isValid">
                                 <button class="btn btn-sm btn-link o_domain_show_selection_button" type="button" t-on-click.stop="onButtonClick">
-                                    <t t-esc="state.recordCount" /> record(s)
+                                    <t t-esc="state.recordCount" /><t t-if="state.hasLimitedCount">+</t> record(s)
                                 </button>
                             </t>
                             <t t-else="">
diff --git a/addons/web/static/tests/core/domain_field.test.js b/addons/web/static/tests/core/domain_field.test.js
index c5757571abe21..a3f9d4d32df36 100644
--- a/addons/web/static/tests/core/domain_field.test.js
+++ b/addons/web/static/tests/core/domain_field.test.js
@@ -554,6 +554,114 @@ test("domain field: does not wait for the count to render", async function () {
     expect(".o_domain_show_selection_button").toHaveText("2 record(s)");
 });
 
+test("domain field: have a default count limit of 10000", async function () {
+    serverState.debug = true;
+
+    Partner._fields.bar = fields.Char();
+    Partner._records = [
+        {
+            foo: "[]",
+            bar: "product",
+        },
+    ];
+    Partner._views = {
+        form: `
+                <form>
+                    <field name="bar"/>
+                    <field name="foo" widget="domain" options="{'model': 'bar'}"/>
+                </form>`,
+        search: `<search />`,
+    };
+
+    onRpc("search_count", ({ kwargs }) => {
+        expect.step(kwargs.limit);
+        return 99999;
+    });
+
+    await mountWithCleanup(WebClient);
+    await getService("action").doAction({
+        name: "test",
+        res_id: 1,
+        res_model: "partner",
+        type: "ir.actions.act_window",
+        views: [[false, "form"]],
+    });
+    expect.verifySteps([10001]);
+    expect(".o_domain_show_selection_button").toHaveText("10000+ record(s)");
+});
+
+test("domain field: foldable and count limit reached", async function () {
+    serverState.debug = true;
+
+    Partner._fields.bar = fields.Char();
+    Partner._records = [
+        {
+            foo: "[]",
+            bar: "product",
+        },
+    ];
+    Partner._views = {
+        form: `
+                <form>
+                    <field name="bar"/>
+                    <field name="foo" widget="domain" options="{'foldable': true, 'model': 'bar'}"/>
+                </form>`,
+        search: `<search />`,
+    };
+
+    onRpc("search_count", ({ kwargs }) => {
+        expect.step(kwargs.limit);
+        return 99999;
+    });
+
+    await mountWithCleanup(WebClient);
+    await getService("action").doAction({
+        name: "test",
+        res_id: 1,
+        res_model: "partner",
+        type: "ir.actions.act_window",
+        views: [[false, "form"]],
+    });
+    expect.verifySteps([10001]);
+    expect(".o_domain_show_selection_button").toHaveText("10000+ record(s)");
+});
+
+test("domain field: configurable count limit", async function () {
+    serverState.debug = true;
+
+    Partner._fields.bar = fields.Char();
+    Partner._records = [
+        {
+            foo: "[]",
+            bar: "product",
+        },
+    ];
+    Partner._views = {
+        form: `
+                <form>
+                    <field name="bar"/>
+                    <field name="foo" widget="domain" options="{'model': 'bar', 'count_limit': 10}"/>
+                </form>`,
+        search: `<search />`,
+    };
+
+    onRpc("search_count", ({ kwargs }) => {
+        expect.step(kwargs.limit);
+        return 99999;
+    });
+
+    await mountWithCleanup(WebClient);
+    await getService("action").doAction({
+        name: "test",
+        res_id: 1,
+        res_model: "partner",
+        type: "ir.actions.act_window",
+        views: [[false, "form"]],
+    });
+    expect.verifySteps([11]);
+    expect(".o_domain_show_selection_button").toHaveText("10+ record(s)");
+});
+
 test("domain field: edit domain with dynamic content", async function () {
     expect.assertions(3);