diff --git a/vendor/magento/module-analytics/ReportXml/ReportProvider.php b/vendor/magento/module-analytics/ReportXml/ReportProvider.php
index 05b2f8b4465..82b7c37628c 100644
--- a/vendor/magento/module-analytics/ReportXml/ReportProvider.php
+++ b/vendor/magento/module-analytics/ReportXml/ReportProvider.php
@@ -6,7 +6,7 @@
 
 namespace Magento\Analytics\ReportXml;
 
-use Magento\Framework\Api\SearchCriteria;
+use PDO;
 
 /**
  * Providers for reports data
@@ -48,6 +48,16 @@ class ReportProvider implements BatchReportProviderInterface
      */
     private $dataSelect;
 
+    /**
+     * @var int|null Last cursor value for cursor-based pagination
+     */
+    private ?int $lastCursor = null;
+
+    /**
+     * @var string|null Cursor column name for cursor-based pagination
+     */
+    private ?string $cursorColumn = null;
+
     /**
      * ReportProvider constructor.
      *
@@ -98,15 +108,64 @@ class ReportProvider implements BatchReportProviderInterface
     {
         if (!$this->dataSelect || $this->dataSelect->getConfig()['name'] !== $name) {
             $this->dataSelect = $this->queryFactory->create($name);
+            $this->lastCursor = null;
             $this->currentPosition = 0;
+            $this->countTotal = 0;
             $this->connection = $this->connectionFactory->getConnection($this->dataSelect->getConnectionName());
-            $this->countTotal = $this->connection->fetchOne($this->dataSelect->getSelectCountSql());
+            $this->cursorColumn = $this->getCursorColumn();
+            if (!$this->cursorColumn) {
+                $this->countTotal = $this->connection->fetchOne($this->dataSelect->getSelectCountSql());
+            }
+        }
+        if (!$this->cursorColumn) {
+            return $this->getBatchReportWithOffset();
         }
 
-        if ($this->currentPosition >= $this->countTotal) {
+        $select = clone $this->dataSelect->getSelect();
+        $cursorValue = $this->lastCursor ?? 0;
+        $select->where(sprintf('%s > ?', $this->cursorColumn), $cursorValue);
+        $select->order(sprintf('%s ASC', $this->cursorColumn));
+        $select->limit(self::BATCH_SIZE);
+        $statement = $this->connection->query($select);
+        $rows = $statement->fetchAll(PDO::FETCH_ASSOC);
+        if (empty($rows)) {
             return $this->iteratorFactory->create(new \ArrayIterator([]), $this->getIteratorName($this->dataSelect));
         }
+        $lastRow = $rows[count($rows) - 1];
+        $this->lastCursor = $lastRow[$this->cursorColumn] ?? null;
+        return $this->iteratorFactory->create(new \ArrayIterator($rows), $this->getIteratorName($this->dataSelect));
+    }
+
+    /**
+     * Detect cursor column based on the source table's primary key
+     *
+     * @return string|null Returns the primary key column name, or null if not found
+     */
+    private function getCursorColumn(): ?string
+    {
+        $config = $this->dataSelect->getConfig();
+        $tableName = $config['source']['name'] ?? null;
+        $analyticTables = ["customer_entity", "sales_order", "sales_order_address", "quote", "catalog_product_entity"];
+        if ($tableName) {
+            if (in_array($tableName, $analyticTables)) {
+                return "entity_id";
+            } elseif ($tableName == "sales_order_item") {
+                return "item_id";
+            }
+        }
+        return null;
+    }
 
+    /**
+     * Fallback to offset-based pagination when cursor column cannot be detected
+     *
+     * @return \IteratorIterator
+     */
+    private function getBatchReportWithOffset(): \IteratorIterator
+    {
+        if ($this->currentPosition >= $this->countTotal) {
+            return $this->iteratorFactory->create(new \ArrayIterator([]), $this->getIteratorName($this->dataSelect));
+        }
         $statement = $this->connection->query(
             $this->dataSelect->getSelect()->limit(self::BATCH_SIZE, $this->currentPosition)
         );
