Konabos

Resolving Performance Issues with Sitecore SXA Headless and Dictionary Items

Kamruz Jaman - Solution Architect

24 Jul 2025

Share on social media

We were recently brought in to investigate a project experiencing significant performance issues. The website was periodically unresponsive, leading to timeouts for users. This had been an ongoing problem that had persisted since their transition to Sitecore JSS/Headless.

The setup was fairly typical: Sitecore XM 10.3.1 using Headless SXA/JSS with a Next.js frontend, hosted entirely in Azure App Services within the customer's own tenant. They were not using platforms like Vercel or Netlify, though Solr was managed via SearchStax.

Initial Observations

The client's team had done some early triage, ruling out high traffic spikes and basic infrastructure faults. Their environments were generously provisioned and several services (including App Services and SearchStax) had even been scaled up in an effort to mitigate the issues. While this bought temporary relief, the root cause remained unknown.

Digging Deeper

With the fundamentals ruled out, such as App Service plans, SQL capacity, network performance, cache configurations, we turned our attention to SearchStax. Alerts revealed frequent indexing errors and unusually high query volume - high CPU usage and very high System Average Loads (the metric our plan was based on), due to unusually high call volumes.

Graph showing high usage of SearchStax Solr instance due to performance issues

(Note the scale on the y-axis)

The codebase itself was clean, with no suspicious custom logic hammering the indexes. However, SearchStax logs told a different story: over 25,000 Solr queries in a single hour, with roughly 75% of them nearly identical:

1q=(((_path:(*095bf4e6eff24eadbdf53d9f8f94d852*) AND _language:(“fr”)) AND _templates:(*6d1cd89719364a3aa511289a94c2a7b1*)) AND _path:(*0de95ae441ab4d019eb067441b7c2450*)) AND _val_:__boost&start=120&rows=10
2
3q=(((_path:(*095bf4e6eff24eadbdf53d9f8f94d852*) AND _language:(“fr”)) AND _templates:(*6d1cd89719364a3aa511289a94c2a7b1*)) AND _path:(*0de95ae441ab4d019eb067441b7c2450*)) AND _val_:__boost&start=130&rows=10

Running the query manually revealed it returned 632 dictionary items.

Support Ticket… and a Dead End

Given the fact that this was such a standard implementation of Sitecore SXA Headless, I figured it was worth raising a Sitecore Support ticket, in the hope it was a known issue with a simple fix.

After much back and forth, including creating support packages and memory dumps, we were told that the high volume of Solr requests was simply proportional to the number of site requests. They suggested workarounds like adding additional caching or adding revalidate to fetch requests.

The site was already using Next.js with a revalidate timeout of 300 seconds. Unfortunately, the suggested workarounds involved significant customization to the out-of-the-box SXA Headless components and patterns. We didn't believe the issue stemmed from any custom code, but rather from how the Headless SXA module itself was designed.

Sadly, this support route didn’t get us any closer to a resolution…

In continuing to analyse the Solr traffic, I had missed the fact the calls were largely the same, the only difference being the rows parameter, which was incrementing by 10 - i.e. each query was only requesting 10 items.

The key issue? Only 10 items were being fetched per request, requiring 64 separate calls per language to retrieve the full list. Multiply that by the site traffic and languages, and you’ve got a self-inflicted DDoS on your Solr instance 😬

I must say a big thank you to the SearchStax Support team though - they were very helpful in diagnosing the issue and extremely helpful in fielding some of my silly questions and theories, as well as been very supportive and understanding to the client whilst the issues continued.

The Fix

After tracing through the dictionary-service-factory.ts in the JSS codebase (link), we found the culprit. 

The default pageSize was set to return just 10 items, which was surprisingly low and somewhat optimistic in my opinion.

We updated the factory like this, to return 500 items per call and set the cache timeout to 15 minutes:

1export class DictionaryServiceFactory {
2  create(siteName: string): DictionaryService {
3    return process.env.FETCH_WITH === constants.FETCH_WITH.GRAPHQL
4      ? new GraphQLDictionaryService({
5          endpoint: config.graphQLEndpoint,
6          apiKey: config.sitecoreApiKey,
7          siteName,
8          pageSize: 500,        // Increase the page size of the results
9          cacheEnabled: true,       // Cache the results
10          cacheTimeout: 900         // Set the cache timeout to 15 minutes
11        })
12      : new RestDictionaryService({
13          apiHost: config.sitecoreApiHost,
14          apiKey: config.sitecoreApiKey,
15          siteName,
16        });
17  }
18}

Interestingly, the siteQuery fetch type already defaulted to 500, but this was only for XM Cloud... I'm guessing they may have already encountered similar issues?

In theory, by default the calls are cached with a timeout of 60 seconds. That doesn't match up with what we were seeing in the initial logs, so we set it explicitly to 15 minutes and enabled to true.

The Results

After deploying the fix, the impact was immediate and dramatic. Solr call volume dropped for this one specific query from peaks of 18,000+ per hour to just 16:

2 languages × 2 queries (500 + 132) × 4 times/hour = 16 total queries/hour

We could have increased the cache timeout even further, given that  items rarely change, but with usage that low we did not feel further optimization was unnecessary at this time.

Graph showing usage of SearchStax Solr instance after performance issues are fixed

We later learned fellow Sitecore MVP Gert Gullentops had run into the same issue, so this clearly isn’t an isolated case.

Since the change, the system has remained stable for months, with normal CPU/memory usage and no abnormal load on SearchStax.

Key Takeaway

If you're using dictionary items with Sitecore Headless SXA and notice performance degradation, check the default page size in the dictionary service factory and leverage caching appropriately. You might be unknowingly hammering your own search infrastructure.

Hitting performance issues on your own site? Need a second pair of eyes from some of the most experienced Sitecore veterans and MVPs available? Get in touch, we're always happy to have a discussion and help.

Sign up to our newsletter

Share on social media

Kamruz Jaman

Kamruz Jaman

Kamruz is a 11-time Sitecore MVP who has worked with the Sitecore platform for more than a decade and has over 20 years of development and architecture experience using the Microsoft technology stack. Kamruz is heavily involved in the Sitecore Community and has spoken at various User Groups and Conferences. As one of the managing partners of Konabos Inc, Kamruz will work closely with clients to ensure projects are successfully delivered to a high standard.


Subscribe to newsletter