WooCommerce Code Reference

WC_Helper_API_Backoff
in package

WC_Helper_API_Backoff Class

Records and enforces a per-request-type backoff window when a WooCommerce.com Helper API endpoint responds with a rate-limit status (HTTP 429), so the site refrains from calling that endpoint again until the limit resets.

The window is taken from the response's Retry-After header (delta seconds) and honored as-is, capped only at a per-type maximum. This covers both the short window of a global rate limit and the longer window of a per-endpoint limit. When the header is absent, a per-type default window is applied instead. Retry-After is used in preference to X-RateLimit-Reset because it is a relative delta and therefore immune to clock skew between the site and WooCommerce.com.

A manual "Refresh" request (the Marketplace refresh button) always bypasses and clears the backoff so the user can force a fresh request at any time.

Table of Contents

REQUEST_TYPE_SUBSCRIPTIONS  = 'subscriptions'
Request type: the WooCommerce.com subscriptions endpoint.
REQUEST_TYPE_UPDATE_CHECK  = 'update-check'
Request type: the WooCommerce.com update-check endpoint.
TRANSIENT_PREFIX  = '_woocommerce_helper_backoff_'
Prefix for the transient that stores a request type's backoff expiry.
clear()  : void
Clear any recorded backoff for a request type.
clear_all()  : void
Clear the recorded backoff for every known request type.
get_retry_after()  : int|null
Seconds remaining in a request type's backoff window.
is_rate_limited()  : bool
Whether a request type is currently within a backoff window.
is_refresh_request()  : bool
Whether the current request is a manual Marketplace refresh.
record_from_response()  : void
Record a backoff window for a request type from a rate-limited response.
get_all_bounds()  : array<string, array{default: int, max: int}>
Backoff bounds per request type, in seconds.
get_bounds()  : array{default: int, max: int}
Backoff bounds for a single request type, in seconds.
get_retry_after_from_headers()  : int|null
Extract the wait, in seconds, from a rate-limited response's `Retry-After` header. Non-positive or missing values are treated as absent.
get_transient_key()  : string
Transient key for a request type's backoff window.

Constants

Methods

clear()

Clear any recorded backoff for a request type.

public static clear(string $request_type) : void
Parameters
$request_type : string

The Helper API request type (e.g. 'update-check').

Return values
void —

clear_all()

Clear the recorded backoff for every known request type.

public static clear_all() : void

Called when the user clicks the Marketplace "Refresh" button so a manual refresh always resets rate-limit backoffs and forces fresh Helper API calls.

Return values
void —

get_retry_after()

Seconds remaining in a request type's backoff window.

public static get_retry_after(string $request_type) : int|null

Lets callers align a user-facing message with the window the site is actually observing, so a rate-limit notice stays visible for exactly as long as requests are being suppressed.

Parameters
$request_type : string

The Helper API request type (e.g. 'update-check').

Tags
since
11.2.0
Return values
int|null — Seconds until the window expires, or null when not rate limited.

is_rate_limited()

Whether a request type is currently within a backoff window.

public static is_rate_limited(string $request_type) : bool

A manual refresh always returns false and clears any recorded backoff, so clicking "Refresh" lets the user force a fresh request at any time.

Parameters
$request_type : string

The Helper API request type (e.g. 'update-check').

Return values
bool — True while the site should refrain from calling the endpoint.

record_from_response()

Record a backoff window for a request type from a rate-limited response.

public static record_from_response(string $request_type, array<string|int, mixed> $response) : void

The wait is taken from the response's rate-limit headers and honored as-is, capped only at the request type's max. This respects both a global rate limit's short Retry-After and a per-endpoint limit's longer window. When no usable header is present (a malformed 429), the per-type default is used so there is always a sensible backoff.

Parameters
$request_type : string

The Helper API request type (e.g. 'update-check').

$response : array<string|int, mixed>

The rate-limited (HTTP 429) response from the Helper API call.

Return values
void —

get_all_bounds()

Backoff bounds per request type, in seconds.

private static get_all_bounds() : array<string, array{default: int, max: int}>

default is the window applied only when the response carries no usable rate-limit header. max is the ceiling that an explicit header value is capped at — a safety net against an unexpectedly distant reset locking the endpoint out. An explicit header shorter than default (e.g. a global rate limit's brief Retry-After) is honored as-is, not floored.

Return values
array<string, array{default: int, max: int}> —

get_bounds()

Backoff bounds for a single request type, in seconds.

private static get_bounds(string $request_type) : array{default: int, max: int}

Unknown request types fall back to a conservative default.

Parameters
$request_type : string

The Helper API request type (e.g. 'update-check').

Return values
array{default: int, max: int} —

get_retry_after_from_headers()

Extract the wait, in seconds, from a rate-limited response's `Retry-After` header. Non-positive or missing values are treated as absent.

private static get_retry_after_from_headers(array<string|int, mixed> $response) : int|null
Parameters
$response : array<string|int, mixed>

The rate-limited (HTTP 429) response from the Helper API call.

Return values
int|null — Seconds to wait, or null when the header is absent/invalid.

get_transient_key()

Transient key for a request type's backoff window.

private static get_transient_key(string $request_type) : string
Parameters
$request_type : string

The Helper API request type (e.g. 'update-check').

Return values
string —