Repository navigation
SharePoint Search API returns inaccurate and inconsistent results count across pages (TotalRows) #11029
Description
Target SharePoint environment
SharePoint Online
What SharePoint development model, framework, SDK or API is this about?
SharePoint REST API
Developer environment
No response
What browser(s) / client(s) have you tested
- 💥 Internet Explorer
- 💥 Microsoft Edge
- 💥 Google Chrome
- 💥 FireFox
- 💥 Safari
- mobile (iOS/iPadOS)
- mobile (Android)
- not applicable
- other (enter in the "Additional environment details" area below)
Additional environment details
- SharePoint Online
- Custom SPFx web part
- SPFx version: 1.23
- Search endpoint: /_api/search/postquery
- Results are displayed using paging with 10 results per page
- The issue occurs on multiple pages, multiple sites and on multiple tenants
- First observed: late august
Describe the bug / error
We are observing significantly inaccurate and inconsistent values for PrimaryQueryResult.RelevantResults.TotalRows when using the SharePoint Search REST API (/_api/search/postquery) and paging through the results using StartRow.
The same search query is executed for each page. The query parameters remain unchanged except for StartRow.
With StartRow = 0, returned TotalRows = 200
With StartRow = 10, returned TotalRows = 400
With StartRow = 20, returned TotalRows = 400
With StartRow = 30, returned TotalRows = 500
As we navigate further through the result set, the reported TotalRows progressively changes and eventually becomes much closer to the actual size of the result set (5,359 items)
The values are also observed to change when the same request is repeated over time.
We understand that TotalRows may be an estimate and therefore do not expect the value to always be exact. However, we would expect the estimate to remain reasonably stable when navigating through pages of the same query and provide a reasonable approximation of the result set size.
We also observe a similar issue when querying graph search (https://graph.microsoft.com/v1.0/search/query)
In that case the hitsContainers.total is wrong
Steps to reproduce
-
Execute a SharePoint Search REST API POST request against
/_api/search/postquery
Use a query matching a relatively large result set and request 10 results:
RowLimit: 10
StartRow: 0
Read:TotalRows -
Execute exactly the same search query with:
StartRow: 10
TotalRowschanges -
Repeat with:
StartRow: 20
TotalRowschanges -
Continue paging through the same query. The reported
TotalRowsprogressively changes and becomes much closer to the actual result-set size
The search criteria and other request parameters remain unchanged throughout these requests; only StartRow changes.
Expected behavior
We understand that TotalRows can be an estimated rather than exact value. However, for the same query we would expect TotalRows to provide a reasonably representative estimate of the result-set size and to remain reasonably stable when navigating between consecutive pages.
For a result set containing thousands of items, an initial estimate of only 200 items is too inaccurate to be useful for pagination.
Changing only StartRow should also not cause the estimated total to increase dramatically as progressively more pages are requested.
Ideally, TotalRows should either provide a reasonably stable approximation of the total result count across pages or
provide a documented mechanism that clients can use to obtain a sufficiently accurate count for implementing pagination.
Activity
Ashlesha-MSFT commentedon Sep 17, 2026
Hello Julien Aubert (@JulienVLC)
Thank you for bringing this issue to our attention. We will look into it and get back to you shortly.
jhholm commentedon Sep 17, 2026
Could be a related issue what I'm currently experiencing. I'm not seeing the TotalRows fluctuating, but I'm getting an HTTP 500 error after increasing the StartRow to e.g. 30 or 40, and using RowLimit 10. TotalRows keeps constant at around 200 items and the query should be quite lightweight. So far I am able to reproduce this on a single tenant with PnP Modern Search.
Ashlesha-MSFT commentedon Sep 18, 2026
Hi Julien Aubert (@JulienVLC),
We performed some initial investigation and attempted to reproduce the reported behavior in a SharePoint Online test environment.
As part of the testing, we:
In our environment, we were not able to reproduce the reported fluctuation in TotalRows. The value remained constant at 1 for the query we tested.
Could you please provide some additional context from the affected environment, particularly:
This additional information will help us compare the request and search configuration with our test scenario. Once we have the additional details, we can continue the investigation and, if appropriate, engage the engineering team with the relevant repro information.
hstuermann commentedon Sep 21, 2026
I can reproduce this (or a corresponding) problem with the SPO search. The TotalRows will change when I change the RowLimit in the query.
E.g. I searched for FileType:pdf and I got with row limit = 10 1600 TotalRows, with row limit = 20 its 1760 TotalRows, with a row limit = 200 I am getting 5280 TotalRows. Putting it to 500 its even more. This is not really the expected output for TotalRows. I am sure that this was working a while ago.
Did the same test with ContentTypeId:0x0101* (which are aspx pages in SitePages lib). Its (for RowLimit => TotalRows) 5 => 1600, 50 => 3200, 500 => 9760. And that are the exact same numbers for the pdf query from above.
And I know from other tenants that there are similar problems.
JulienVLC commentedon Sep 21, 2026
Hi Ashlesha-MSFT
I did another test with a dataset containing 2020 documents
First page:
/_api/search/postquerypayload page1.json
Results:
Second page:
payload page2.json
Results:
To be noted: the Total value returned seems to be somehow related to the original paging size: if I set
RowLimitit to 24, I initially get 480 results, then 980, etc.GuillermoBas commentedon Sep 21, 2026
Same issue here affecting most of our tenants. TotalRows just went mad and feeling just random depending on the page you are.
Indhupm commentedon Sep 22, 2026
Same issue here. My search results are returning just from one list. The results count returned in json is double than what is actually in the list. The list doesn't have multiple value fields, no version history.
Ashlesha-MSFT commentedon Sep 28, 2026
Thank you for the additional repro details and for confirming that the behavior is reproducible across multiple tenants.
Based on the additional examples, particularly the dependency of TotalRows on RowLimit and StartRow, we will engage the SharePoint Search engineering team to investigate this behavior further.
We’ll share an update here once we have more information from the engineering team.
Thank you for your patience and for providing the detailed repro information.
wobba commentedon Sep 29, 2026
As the total returned is an estimate, this is "by design".
hstuermann commentedon Sep 29, 2026
I am pretty sure this was working by a very different design the last 15years. Now its pretty much useless. Not on all tenants, but on my daily used tenants its already the new "by design".
Maybe it was always estimation by design, but searching with a row limit of 10 resulting in 1600 total rows and searching with a row limit of 500 resulting in 9760 total rows is a kinda bad estimation. And I never had this wild big differences. It was always pretty accurate.
GuillermoBas commentedon Sep 29, 2026
Everyone knows that based on your amazing blogs on the matter from the last 10-15 years Mikael Svenson (@wobba) . But the way that estimate works changed dramatically over the last few weeks and the change is propagating fast a cross all tenants. Would you be able to elaborate any further on this? Is this change in the way total rows work intended? If so any official documentation we can refer to to justify changes in our own software based on the way it used to work?
kasperbolarsen commentedon Sep 30, 2026
I have to disagree, if the "estimate" is a function of PageSize" then it is no longer an estimate, just a value with no relevance anymore.
wobba commentedon Oct 4, 2026
hstuermann you are right that things worked differently before, where before is a number of years ago as tech evolve.
Not saying it's a good thing or a bad thing, but it is working "by design".
However, my personal opinion is that the count estimate has been unreliable for at least the past 4-5 years. This is also why pagination 1,2,3,4 was removed from default search experience and we only show next/previous since building a pagination based on the number was unreliable.
Afaik there has never been any official documentation on the count.
If you are able to test. Can you add this refiners to your API query?
Size(discretize=manual/0/1000000000,deephits=100000), and see if the number changes, or if the number you get back on the refiner is different from the TotalRows? You may want to play with cutoff parameter as well https://learn.microsoft.com/en-us/sharepoint/dev/general-development/query-refinement-in-sharepoint#table-1-list-of-parameters-for-refiners.API's are mainly tuned for user experiences, where TotalRows may or may not be a good indicator to show in the UX for the total volume. If you rely on the number for a governance job or similar, that is a different scenario, and not what the search API's are tuned for.
hstuermann commentedon Oct 4, 2026
Mikael Svenson (@wobba) So I do not have access to the most tenants at the moment. But I tested on one tenant:
(had to test on the console since I am on my private device)
So the results for TotalRows are looking kinda "stable" again (at least better then last week). I could not reproduce the reported behavior from above. Need to check that tomorrow for the other tenants at work. The refinement results are all the same for the three calls with different row limits. But I am not sure what it means.
hstuermann commentedon Oct 5, 2026
Mikael Svenson (@wobba) So reporting back with results from another tenant. Refiner results:
But the TotalRows value is still a value which depends on the RowLimit value.
Querying for the SitePages ContentType with only changing the RowLimit
RowLimit: 10 => TotalRows: 1600 (Query: ContentTypeId:0x0101*)
RowLimit: 20 => TotalRows: 1760 (Query: ContentTypeId:0x0101*)
RowLimit: 50 => TotalRows: 2400 (Query: ContentTypeId:0x0101*)
RowLimit: 100 => TotalRows: 3520 (Query: ContentTypeId:0x0101*)
RowLimit: 500 => TotalRows: 9760 (Query: ContentTypeId:0x0101*)
Changing the query results in the same estimated results...
RowLimit: 10 => TotalRows: 1600 (Query: FileType:pdf)
RowLimit: 20 => TotalRows: 1760 (Query: FileType:pdf)
RowLimit: 50 => TotalRows: 2400 (Query: FileType:pdf)
RowLimit: 100 => TotalRows: 3520 (Query: FileType:pdf)
RowLimit: 500 => TotalRows: 9760 (Query: FileType:pdf)
JulienVLC commentedon Oct 5, 2026
Hi Mikael Svenson (Mikael Svenson (@wobba))
In my case, adding the refiner
Size(discretize=manual/0/1000000000,deephits=100000)does not change the TotalRows returned (200 on the first page). There is definitely something wrong there.However, the RefinementCount is close to the real total number (2020 instead of 2022). I have to do more test, but a proper workaround on our end would be to use the sum of RefinementCount as a good indicator for the total count.
wobba commentedon Oct 8, 2026
May be easier to test using the Graph Search API in e.g Graph Explorer. I did some tests like below, and validate against reported item counts in the SharePoint site contents page, and I find the refinement value closest to the truth, while total is over-estimating.
I'd be interested in some qualitative tests. Not just that the totalrows has changed. Is it now closer to the truth or farther away, compared to what it was? If you never compared the old number with the item truth it's not possible to assess if the change (still not sure what may have changed) has improved the count or not.
hstuermann it's expected for totalrows to be impacted by rowlimit, as it's an estimation formula. Do you know the actual items in the tenant which should match on either query?
{ "Requests": [ { "entityTypes": [ "listItem","driveItem","site","list","drive" ], "query": { "queryString": "path:https://contoso.sharepoint.com/site/asite" }, "size":1, "aggregations": [ { "field": "Size", "size": 1, "bucketDefinition": { "sortBy": "keyAsNumber", "isDescending": "true", "minimumCount": 0, "ranges": [ { "from": "0" } ] } } ] } ] }wobba commentedon Oct 14, 2026
Can someone verify if the current count is more accurate than it was or not? That it changes is not important. How close is it to the real count of items a query should match.
roberAlb commentedon Oct 14, 2026
Hi Mikael Svenson (@wobba)
I've performed some tests using Microsoft Graph Search API with Size aggregations as suggested in your previous comments.
I selected a SharePoint Online document library and retrieved its actual item count using the SharePoint REST API, independently of Search.
Actual SharePoint library contents:
Total items: 569
Files: 548
Folders: 21
Graph Search Query without isDocument=true
SharePoint ItemCount (folder + files) --> 569
Graph total -->619 Difference from actual +50
Graph Size aggregation -->567 Difference from actual -2
Graph Search Query isDocument=true
SharePoint ItemCount (folders excluded) --> 548
Graph total -->582 Difference from actual +34
Graph Size aggregation -->533 Difference from actual -15
In both tests, the Graph Size aggregation is closer to the SharePoint inventory count than Graph's total.
wobba commentedon Oct 14, 2026
isDocument:trueis not a good query to get all items in a library. It scopes to Office file types + pdf. A path + contentclass query may be better to capture all files+folders (not views).But it means the aggregate helps and may be better to underreport vs overreport. Roberto Ramon (@roberAlb) either way, if you page 10 by 10, then the total would work just fine for either number - and likely adjust as you reach more and more pages.
magarma commentedon Oct 14, 2026
Hi, maybe helps, I've done some tests with Graph explorer...
A list with 49999 list items.... QueryString: "Path:{URL TO THE LIST}"
First page of 10: Total number says 2000
Paging from 230: Total number says 2510
Paging from 240: Total number says 49999
First time:
Second time, without changes... Total number, 2510 ( same items returned, take a look to the one in the screenshot)
Paging from 5000, total 49999
From 5200, total 6840...
Repeating again, 49999
In all of them... the aggregation count matches the 49999.
hstuermann commentedon Oct 14, 2026
Mikael Svenson (@wobba) I try to get some results tomorrow. Maybe our IT is giving me permissions to use graph explorer. Ticket still pending...
If not, I will add some code to a webpart to get the results.
hstuermann commentedon Oct 15, 2026
Mikael Svenson (@wobba) So I finally had some time. First the graph results for my list with 9999 items:
I only changed the path value in your query, so I omit images from the query itself:
Did the same query with the SharePoint Search:
And just to come back to the original topic of the issue here: Total Rows still showing bad/unusable values. And this is something they did not a few weeks ago, since the solution which is using this list was working with TotalRows.