SpikeArrest policy

This pageapplies toApigee andApigee hybrid.

View Apigee Edge documentation.

The SpikeArrest policy protects against traffic surges with the<Rate> element. This element throttles the number of requests processed by an API proxy and sent to a backend, protecting against performance lags and downtime.

This policy is aStandard policy and can be deployed to any environment type. For information on policy types and availability with each environment type, seePolicy types.

The difference between SpikeArrest and Quota

TheQuota policy configures the number of request messages that a client app is allowed to submit to an API over the course of an hour, day, week, or month. The Quota policy enforces consumption limits on client apps by maintaining a distributed counter that tallies incoming requests.

Use Quota to enforce business contracts or SLAs with developers and partners, rather than for operational traffic management. Use SpikeArrest to protect against sudden spikes in API traffic. See alsoComparing Quota and SpikeArrest policies.

Videos

These videos discuss use cases for this policy:

Why You Need It

Compare Quota Policy

<SpikeArrest> element

Defines the SpikeArrest policy.

Default ValueSeeDefault Policy tab, below
Required?Optional
TypeComplex object
Parent Element n/a
Child Elements<Identifier>
<MessageWeight>
<Rate> (Required)
<UseEffectiveCount>

Syntax

The<SpikeArrest> element uses the following syntax:

<SpikeArrestcontinueOnError="[false|true]"enabled="[true|false]"name="policy_name"><DisplayName>display_name</DisplayName><Properties/><Identifierref="flow_variable"/><MessageWeightref="flow_variable"/><Rateref="flow_variable">rate[pm|ps]</Rate><UseEffectiveCount>[false|true]</UseEffectiveCount></SpikeArrest>

Default Policy

The following example shows the default settings when you add a SpikeArrest policy to your flow in the UI:

<SpikeArrest async="false" continueOnError="false" enabled="true" name="Spike-Arrest-1">  <DisplayName>Spike Arrest-1</DisplayName>  <Properties/>  <Identifier ref="request.header.some-header-name"/>  <MessageWeight ref="request.header.weight"/>  <Rate>30ps</Rate>  <UseEffectiveCount>false</UseEffectiveCount></SpikeArrest>

This element has the following attributes that are common to all policies:

AttributeDefaultRequired?Description
nameN/ARequired

The internal name of the policy. The value of thename attribute can contain letters, numbers, spaces, hyphens, underscores, and periods. This value cannot exceed 255 characters.

Optionally, use the<DisplayName> element to label the policy in the management UI proxy editor with a different, natural-language name.

continueOnErrorfalseOptionalSet tofalse to return an error when a policy fails. This is expected behavior for most policies. Set totrue to have flow execution continue even after a policy fails. See also:
enabledtrueOptionalSet totrue to enforce the policy. Set tofalse toturn off the policy. The policy will not be enforced even if it remains attached to a flow.
async  falseDeprecatedThis attribute is deprecated.

Examples

The following examples show some of the ways in which you can use the SpikeArrest policy:

Example 1

The following example sets the rate to five per second:

<SpikeArrest name="SA-Static-5ps">  <Rate>5ps</Rate>  <UseEffectiveCount>false</UseEffectiveCount></SpikeArrest>

This sample policy allows a maximum of 5 requests per second. Via smoothing, it is enforced as a maximum of one request for every 200millisecond (1000/5) interval.

Example 2

The following example sets the rate to 12 per minute:

<SpikeArrest name="SA-Static-12pm">  <Rate>12pm</Rate>  <UseEffectiveCount>true</UseEffectiveCount></SpikeArrest>

This sample policy allows a maximum of 12 requests per minute at the rate of one request per 5second (60/12) interval. If there is more than one request in the 5second interval, such requests are allowed (no smoothing) provided the number of requests is less than the configured rate limit of 12 per minute.

Example 3

The following example restricts requests to 12 per minute (one request allowed every five seconds, or 60/12):

<SpikeArrest name="SA-With-Dynamic-Weight-1">  <Rate>12pm</Rate>  <Identifier ref="client_id" />  <MessageWeight ref="request_specific_weight" />  <UseEffectiveCount>true</UseEffectiveCount></SpikeArrest>

In addition, the<MessageWeight> element accepts a custom value (theweight header) that adjusts message weights for specific apps or clients. This provides additional control over throttling for entities that are identified with the<Identifier> element.

Example 4

The following example instructs SpikeArrest to look for a runtime value set via the request that is passed in as therequest.header.runtime_rate flow variable:

<SpikeArrest name="SA-From-Inbound-Header-1">  <Rate ref="request.header.runtime_rate" />  <UseEffectiveCount>true</UseEffectiveCount></SpikeArrest>

The value of the flow variable must be in the form ofintpm orintps.

To try this example, execute a request like the following:

curl http://myorg-myenv.apigee.net/price -H 'runtime_rate:30ps'
Tip: Check out How can I use API products to set spike arrest limits? that explains how to set the SpikeArrest rate using custom variables set in an API product.

Child element reference

This section describes the child elements of<SpikeArrest>.

<DisplayName>

Use in addition to thename attribute to label the policy in the management UI proxy editor with a different, more natural-sounding name.

The<DisplayName> element is common to all policies.

Default ValueN/A
Required?Optional. If you omit<DisplayName>, the value of the policy'sname attribute is used.
TypeString
Parent Element <PolicyElement>
Child Elements None

The<DisplayName> element uses the following syntax:

Syntax

<PolicyElement><DisplayName>POLICY_DISPLAY_NAME</DisplayName>  ...</PolicyElement>

Example

<PolicyElement><DisplayName>My Validation Policy</DisplayName></PolicyElement>

The<DisplayName> element has no attributes or child elements.

<Identifier>

Lets you choose how to group the requests so that the SpikeArrest policy can be applied based on the client. For example, you can group requests by developer ID, in which case each developer's requests will count towards their own SpikeArrest rate and not all requests to the proxy.

Use in conjunction with<MessageWeight> element for more fine-grained control over request throttling.

If you leave the<Identifier> element empty, one rate limit is enforced for all requests into that API proxy.

Default Valuen/a
Required?Optional
TypeString
Parent Element<SpikeArrest>
Child Elements None

Syntax

<SpikeArrestcontinueOnError="[false|true]"enabled="[true|false]"name="policy_name"><Identifierref="flow_variable"/></SpikeArrest>

Example 1

The following example applies the SpikeArrest policy per developer ID:

<SpikeArrest name="Spike-Arrest-1">  <Identifier ref="developer.id"/>  <Rate>42pm</Rate/>  <UseEffectiveCount>true</UseEffectiveCount></SpikeArrest>

The following table describes the attributes of<Identifier>:

AttributeDescriptionDefaultPresence
refIdentifies the variable by which SpikeArrest groups incoming requests. You can use any flow variable to indicate a unique client, such those available with theVerifyAPIKey policy. You can also set custom variables using theJavaScript policy or theAssignMessage policy.n/aRequired

This element is also discussed inthis Apigee Community post.

<MessageWeight>

Specifies the weighting defined for each message. Message weight modifies the impact of a single request on the calculation of the SpikeArrest rate. Message weight can be any flow variable, such as an HTTP header, query parameter, form parameter, or message body content. You can also use custom variables using theJavaScript policy or theAssignMessage policy.

Use in conjunction with<Identifier> to further throttle requests by specific clients or apps.

For example, if the SpikeArrest<Rate> is10pm, and an app submits requests with a weight of2, then only five messages per minute are permitted from that client because each request counts as 2.

Default Valuen/a
Required?Optional
TypeInteger
Parent Element<SpikeArrest>
Child Elements None

Syntax

<SpikeArrestcontinueOnError="[false|true]"enabled="[true|false]"name="policy_name"><MessageWeightref="flow_variable"/></SpikeArrest>

Example 1

The following example restricts requests to 12 per minute (one request allowed every five seconds, or 60/12):

<SpikeArrest name="SA-With-Dynamic-Weight-1">  <Rate>12pm</Rate>  <Identifier ref="client_id" />  <MessageWeight ref="request_specific_weight" />  <UseEffectiveCount>true</UseEffectiveCount></SpikeArrest>

In this example,<MessageWeight> accepts a custom value (theweight header in the request) that adjusts message weights for specific clients. This provides additional control over throttling for entities that are identified with the<Identifier> element.

The following table describes the attributes of<MessageWeight>:

AttributeDescriptionPresenceDefault
refIdentifies the flow variable that contains the message weight for the specific client. This can be any flow variable, such as an HTTP query param, header, or message body content. For more information, seeFlow variables reference. You can also set custom variables using theJavaScript policy or theAssignMessage policy.RequiredN/A

<Rate>

Specifies the rate at which to limit traffic spikes (or bursts) by setting the number of requests that are allowed in per minute or per second intervals. You can also use this element in conjunction with<Identifier> and<MessageWeight> to smoothly throttle traffic at runtime by accepting values from the client. Use the<UseEffectiveCount> element to set the rate limiting algorithm used by the policy.

Note: The use of<UseEffectiveCount> with a value orfalse is not supported forany Apigee organizations or for Apigee hybrid organizations running production workloads.For more information, see<UseEffectiveCount>.

See theSpikeArrest section of the Limits page for the maximum rate limits you can specify.

Default Valuen/a
Required?Required
TypeInteger
Parent Element<SpikeArrest>
Child Elements None

Syntax

You can specify rates in one of the following ways:

  • A static rate that you specify as the body of the<Rate> element
  • A variable value, which can be passed by the client; identify the name of the flow variable using theref attribute
<SpikeArrestcontinueOnError="[false|true]"enabled="[true|false]"name="policy_name"><Rateref="flow_variable">rate[pm|ps]</Rate></SpikeArrest>

Valid rate values (either defined as a variable value or in the body of the element) must conform to the following format:

  • intps (number of requests per second, smoothed into intervals of milliseconds)
  • intpm (number of requests per minute, smoothed into intervals of seconds)

The value ofint must be a positive, non-zero integer.

Example 1

The following example sets the rate to five requests per second:

<SpikeArrest name="SA-Static-5ps">  <Rate>5ps</Rate>  <UseEffectiveCount>false</UseEffectiveCount></SpikeArrest>

The policy smoothes the rate to one request allowed every 200milliseconds (1000/5).

Example 2

The following example sets the rate to 12 requests per minute:

<SpikeArrest name="SA-Static-12pm">  <Rate>12pm</Rate>  <UseEffectiveCount>true</UseEffectiveCount></SpikeArrest>

This example policy smoothes the rate to one request allowed every fiveseconds (60/12).

The following table describes the attributes of<Rate>:

AttributeDescriptionPresenceDefault
refIdentifies a flow variable that specifies the rate. This can be any flow variable, such as an HTTP query parameter, header, or message body content, or a value such as a KVM. For more information, seeFlow variables reference.

You can also use custom variables using theJavaScript policy or theAssignMessage policy.

If you define bothrefand the body of this element, the value ofref is applied and takes precedence when the flow variable is set in the request. (The reverse is true when the variable identified inref isnot set in the request.)

For example:

<Rate ref="request.header.custom_rate">1pm</Rate>

In this example, if the client doesnot pass acustom_rate header, then the rate for the API proxy is 1 request per minute for all clients. If the client passes acustom_rate header, then the rate limit becomes 10 requests per second for all clients on the proxy — until a request without thecustom_rate header is sent.

You can use<Identifier> to group requests to enforce custom rates for different types of clients.

If you specify a value forref but do not set the rate in the body of the<Rate> element and the client does not pass a value, then the SpikeArrest policy throws an error.

Optionaln/a
The following table describes the attributes ofRate defining the traffic throttling behavior:
AttributeDescription
messagesPerPeriodSpecifies the number of messages allowed within a defined period. For example, if a policy is configured for '10ps' (10 per second), themessagesPerPeriod value would be 10.
periodInMicrosecondsDefines the time period, in microseconds, over which themessagesPerPeriod is calculated. For a '10ps' configuration, this value would be 1,000,000, which is equivalent to one second.
maxBurstMessageCountRepresents the maximum number of requests that can be allowed instantly or in a short burst at the beginning of a new interval.
Note: The values and calculations for these attributes can be affected by the number of MPs and whether theUseEffectiveCount setting is enabled. For instance, if you set a rate of '10ps' with 10 MPs andUseEffectiveCount is enabled, the effective rate for each MP is 1ps. The internal attributes of the individual MP are adjusted to reflect this. For example, themessagesPerPeriod attribute could be set to 1 andperiodInMicroseconds to 1,000,000.

<UseEffectiveCount>

This element lets you choose between distinct spike arrest algorithms by setting thevalue totrue orfalse, as explained below:

true

If set totrue, SpikeArrest is distributed in a region. That means request counts are synchronized across message processors (MPs) in a region. In addition, a "sliding window" rate limiting algorithm is employed. This algorithm provides consistent rate limit behavior and does not "smooth" the number of incoming requests that can be sent to the backend. If a burst of requests are sent in a short time interval, they are allowed as long as they do not exceed the configured rate limit, as set in the<Rate> element. For example:

<SpikeArrest name="Spike-Arrest-1">  <Rate>12pm</Rate>  <Identifier ref="client_id" />  <MessageWeight ref="request.header.weight" />  <UseEffectiveCount>true</UseEffectiveCount></SpikeArrest>

false (default)

Note: Although the default value isfalse, Apigee organizations should set this element totrue.

Rate smoothing is not supported for Apigee organizations.

If set tofalse (the default), the SpikeArrest policy uses a "token bucket" algorithm that smooths traffic spikes by dividing the rate limit that you specify into smaller intervals. A drawback of this approach is that multiple legitimate requests coming in over a short time interval can potentially be denied.

For example, say you enter a rate of 30pm (30 requests per minute). In testing, you might think you could send 30 requests in 1 second, as long as they came within a minute. But that's not how the policy enforces the setting. If you think about it, 30 requests inside a 1-second period could be considered a mini spike in some environments.

  • Per-minute rates get smoothed into full requests allowed in intervals ofseconds.

    For example, 30pm gets smoothed like this:
    60 seconds (1 minute) / 30pm = 2-second intervals, or 1 request allowed every 2 seconds. A second request inside of 2 seconds will fail. Also, a 31st request within a minute will fail.

  • Per-second rates get smoothed into full requests allowed in intervals ofmilliseconds.

    For example, 10ps gets smoothed like this:
    1000 milliseconds (1 second) / 10ps = 100-millisecond intervals, or 1 request allowed every 100 milliseconds. A second request inside of 100ms will fail. Also, an 11th request within a second will fail.

Note: In rate smoothing, the number of requests is always a whole number greater than zero. Smoothing never involves calculating fractions of requests.
Default ValueFalse
Required?Optional
TypeBoolean
Parent Element<SpikeArrest>
Child Elements None

Flow variables

When a SpikeArrest policy executes, the following flow variable is populated:

VariableTypePermissionDescription
ratelimit.policy_name.failedBooleanRead-OnlyIndicates whether or not the policy failed (true orfalse).

For more information, seeFlow variables reference.

Error reference

This section describes the fault codes and error messages that are returned and fault variables that are set by Apigee when this policy triggers an error. This information is important to know if you are developing fault rules to handle faults. To learn more, seeWhat you need to know about policy errors andHandling faults.

Runtime errors

These errors can occur when the policy executes.

Tip: Need help resolving an error? Clickin the Fix column for detailed troubleshooting information.
Fault codeHTTP statusCauseFix
policies.ratelimit.FailedToResolveSpikeArrestRate500This error occurs if the reference to the variable containing the rate settingwithin the<Rate> element cannot be resolved to a value within theSpikeArrest policy. This element is mandatory and used to specify the spike arrest rate in the form ofintpm orintps.
policies.ratelimit.InvalidMessageWeight500This error occurs if the value specified for the<MessageWeight> element througha flow variable is invalid (a non-integer value).
policies.ratelimit.SpikeArrestViolation429The rate limit is exceeded.

Deployment errors

These errors can occur when you deploy a proxy containing this policy.

Tip: Need help resolving an error? Click in the Fix column for detailed troubleshooting information.
Error nameCauseFix
InvalidAllowedRateIf the spike arrest rate specified in the<Rate> element of theSpikeArrest policy is not an integer or if the rate does not haveps orpm as a suffix,then the deployment of the API proxy fails.

Fault variables

These variables are set when a runtime error occurs. For more information, seeWhat you need to know about policy errors.

VariablesWhereExample
fault.name="fault_name"fault_name is the name of the fault, as listed in theRuntime errors table above. The fault name is the last part of the fault code.fault.name Matches "SpikeArrestViolation"
ratelimit.policy_name.failedpolicy_name is the user-specified name of the policy that threw the fault.ratelimit.SA-SpikeArrestPolicy.failed = true

Example error response

Shown below is an example error response:

Note: For error handling, the best practice is to trap theerrorcode part of the error response. Do not rely on the text in thefaultstring, because it could change.
{"fault":{"detail":{"errorcode":"policies.ratelimit.SpikeArrestViolation"},"faultstring":"Spike arrest violation. Allowed rate : 10ps"}}

Example fault rule

Shown below is an example fault rule to handle aSpikeArrestViolation fault:

<FaultRules>    <FaultRule name="Spike Arrest Errors">        <Step>            <Name>JavaScript-1</Name>            <Condition>(fault.name Matches "SpikeArrestViolation") </Condition>        </Step>        <Condition>ratelimit.Spike-Arrest-1.failed=true</Condition>    </FaultRule></FaultRules>

The current HTTP status code for exceeding a rate limit set by a Quota or SpikeArrest policy is 429 (Too Many Requests).

Schemas

Each policy type is defined by an XML schema (.xsd). For reference,policy schemas are available on GitHub.

Related topics

Except as otherwise noted, the content of this page is licensed under theCreative Commons Attribution 4.0 License, and code samples are licensed under theApache 2.0 License. For details, see theGoogle Developers Site Policies. Java is a registered trademark of Oracle and/or its affiliates.

Last updated 2026-02-18 UTC.