Enable retries for requests to the XM Cloud Experience Edge GraphQL endpoint
The Experience Edge GraphQL endpoint in XM Cloud is rate-limited, meaning there is a limit on the number of requests that can be made within a specific time frame (currently 80 requests/second). When building or deploying a large Next.js application with static generation (SSG) enabled, you might hit the limitation, and the build process will fail. At build time, the Next.js application sends requests to the endpoint through multiple services.
To successfully generate the production code for a large website, you can enable retries for the GraphQL client in your Next.js application and apply retry strategies.
Retry strategies are available in JSS version 20.3 and subsequent patches for version 20 and in version 21.6.3 and later.
This walkthrough describes how to:
-
Set the number of retries.
-
Use the default retry strategy.
-
Create a custom strategy (optional).
Set the number of retries
Next.js JSS applications use the GRAPH_QL_SERVICE_RETRIES
environment variable to set the number of GraphQL request retries for all services using the GraphQL endpoint (Layout, Dictionary, and Error Page services). By default, the value of this environment variable is 0.
You can configure a specific number of retries globally or per service.
To enable request retries globally:
-
Update the value of the
GRAPH_QL_SERVICE_RETRIES
environment variable to a positive integer.NoteIf you define custom environment variables, such as
GRAPH_QL_LAYOUT_SERVICE_RETRIES
, you must remember to add the variables to XM Cloud, your deployment service, pipelines, and so on.For additional information on working with environment variables in XM Cloud, refer to:
If you need to specify a different number of retries for each service, you can change the value of the service's retries
option or define custom environment variables for each service.
Depending on which approach you prefer, replace the existing retries
value with a hard-coded positive integer or the environment variable name in the following files:
-
For the Layout Service, in the
src/lib/layout-service-factory.ts
file. -
For the Dictionary Service, in the
src/lib/dictionary-service-factory.ts
file. -
For the Error Page Service, in the
src/pages/404.tsx
andsrc/pages/500.tsx
files.
Use the default retry strategy
After you enable retries by setting the number of retries to a positive integer, the application uses a default retry strategy to handle the following response status codes with an exponential back-off/delay factor of 2:
-
429 - too many requests.
-
502 - 504 - server errors.
-
520 - 524 - Edge-specific errors.
The list of error codes and the back-off factor are configurable. The strategy uses internally the retries you configured for that particular service.
To configure the default retry strategy:
-
In your service factory file, for example,
/src/lib/dictionary-service-factory.ts
, import theDefaultRetryStrategy
class:RequestResponseimport { DefaultRetryStrategy } from '@sitecore-jss/sitecore-jss-nextjs';
-
Override the default retry strategy configuration if present or add it to the GraphQL service options, specifying the error codes you want to handle and the delay factor. For example:
RequestResponseretries: (process.env.GRAPH_QL_SERVICE_RETRIES && parseInt(process.env.GRAPH_QL_SERVICE_RETRIES, 10)) || 0, retryStrategy: new DefaultRetryStrategy({statusCodes: [502, 503], factor: 3})
Create a custom strategy (optional)
If you want to customize the retry strategy beyond error codes and delay factor, you can implement your own retry strategy class based on the RetryStrategy
interface.
The interface defines a strategy for retrying GraphQL requests based on errors and attempts. It defines two methods as follows:
-
shouldRetry
- determines whether a request should be retried based on the error and attempt count. It returns a Boolean value. It requires the following parameters:Parameter
Description
error
The error of the
ClientError
type received from the GraphQL request.retries
The number of retries configured.
attempt
The current attempt number.
-
getDelay
- calculates the delay (in milliseconds) before the next retry based on the given error and attempt count. It returns the delay for the next retry in milliseconds. It requires the following parameters:Parameter
Description
error
The error of the
ClientError
type received from the GraphQL request.attempt
The current attempt number.
The ClientError
type is provided by the graphql-request
package and re-exported by JSS framework packages. If your application is based on versions of JSS earlier than 21, install the package to import the type.
To create a custom retry strategy:
-
In your service factory file, for example,
/src/lib/dictionary-service-factory.ts
, import theRetryStrategy
interface:RequestResponseimport { RetryStrategy, ClientError, } from '@sitecore-jss/sitecore-jss-nextjs';
-
Declare a new constant of the
RetryStrategy
type and implement theshouldRetry
andgetDelay
methods required by the interface. For example:RequestResponseconst customRetryStrategy: RetryStrategy = { shouldRetry: (clientError: ClientError, retries: number, attempt: number): boolean => true, // Replace this with your own implementation getDelay: (clientError: ClientError, attempt: number): number => 1000, // Replace this with your own implementation };
-
Add your custom retry strategy to the GraphQL service options. For example:
RequestResponsenew GraphQLDictionaryService({ siteName, clientFactory, retries: (process.env.GRAPH_QL_SERVICE_RETRIES && parseInt(process.env.GRAPH_QL_SERVICE_RETRIES, 10)) || 0, retryStrategy: customRetryStrategy })