---
schema_version: "1"
id: 3835c4780beafe3defdf7e20f2b3fc173bd43aa6eae0e6aa3050dfb57afad701
title: Using Spike Control Library Functions
collection: mulesoft
version: current
locale: en-us
portal_url: https://docs.salesforce.com/mulesoft/current/en-us/pdk/latest/policies-pdk-configure-features-spike-control.md
canonical_url: https://docs.mulesoft.com/pdk/latest/policies-pdk-configure-features-spike-control
source_site: docs.mulesoft.com
content_type: documentation
content_hash: 342b3169cde0bca2d7ca5c045e67ab3368f6a73d2040dc71b5d7c4f032569dd9
description: MuleSoft Documentation Site
release: "1.10"
latest: true
---
---
product: Omni Gateway Policy Development Kit (PDK)
version: 1.10
is-latest-version: true
---

# Using Spike Control Library Functions

> For the full documentation index, see: https://docs.mulesoft.com/llms.txt

> [!NOTE] To view an example policy project that uses Omni Gateway Policy Development Kit (PDK)'s
> Spike Control library, see
> [Spike Policy Example](https://github.com/mulesoft/pdk-custom-policy-examples/blob/1.10.0/spike/README.md).

To prevent sudden surges from overwhelming upstream services or exhausting shared capacity, spike
control regulates how quickly traffic can grow. With the Spike Control library, you drive a handler
modeled as a token bucket with a xref:policies-pdk-configure-features-timer.adoc\[Timer\] and a
\`Clock\` ticker, then you call \`is\_allowed\` from request or response filters. Use the library
for custom policies that need spike arrest, smoothing, or rate style limits like those in Omni
Gateway, with Rust logic you control.

Use the library when your custom policy must perform these tasks.

- Reject or delay traffic when request volume spikes beyond configured tiers.

- Share one handler across filters while a periodic ticker refreshes bucket state.

- Return `429 Too Many Requests` or another HTTP outcome when `is_allowed` reports overload.

## Inject `SpikeControlBuilder` and Build a Handler

Inject `SpikeControlBuilder` and `Clock` in the
[`#[entrypoint` configure function\]. Include `Launcher` and your other configuration types. From `Clock`, create a ticker, pass it to the builder, add at least one bucket as `Tier` values with `requests` and `period_in_millis`, and call `build` to get a `SpikeControlHandler` you share with filters inside `std::rc::Rc`. The `Tier` layout matches](policies-pdk-configure-features#policy-template)
[rate limiting examples](https://docs.mulesoft.com/pdk/latest/policies-pdk-configure-features-rate-limiting).

```Rust
use anyhow::Result;
use pdk::hl::*;
use std::rc::Rc;
use std::time::Duration;

use pdk::spike_control::{
    SpikeControlBuilder, SpikeControlError, SpikeControlHandler, Tier,
};

#[entrypoint]
async fn configure(
    launcher: Launcher,
    clock: Clock,
    spike_control: SpikeControlBuilder,
) -> Result<()> {
    let ticker = Rc::new(clock.period(Duration::from_millis(100)));

    let handler = Rc::new(
        spike_control
            .new("example-spike-control".to_string())
            .with_ticker(ticker)
            .with_bucket(
                "default".to_string(),
                vec![Tier {
                    requests: 1,
                    period_in_millis: 1000,
                }],
            )
            .with_retry(200, 2)
            .build()
            .map_err(|e| anyhow::anyhow!("failed to build spike control example: {e}"))?,
    );

    launcher
        .launch(on_request({
            let handler = Rc::clone(&handler);
            move |state| request_filter(state, handler.as_ref())
        }))
        .await?;
    Ok(())
}
```

Use the fluent builder on `SpikeControlBuilder` to register a spike control name, ticker, buckets,
and optional `with_retry` behavior. See the PDK Rust API documentation for a list of `with_*`
methods. The documentation also explains what happens when you omit a call and what the `with_retry`
method does.

## Evaluate Traffic with `is_allowed`

Pass a reference to `SpikeControlHandler` into your `on_request` or `on_response` filters. For each
request, call `is_allowed` with the bucket name, the traffic scope key, the permit count for this
call, and the boolean flags your design requires. See the PDK Rust API documentation for full
parameter and return value details.

```Rust
async fn request_filter(state: RequestState, handler: &SpikeControlHandler) -> Flow<()> {
    let _ = state.into_headers_state().await;

    match handler.is_allowed("default", "sample", 1, true).await {
        Ok(_) => Flow::Continue(()),
        Err(SpikeControlError::TooManyRequests(_)) => Flow::Break(Response::new(429)),
        Err(_) => Flow::Break(Response::new(503)),
    }
}
```

Match each `is_allowed` outcome to the HTTP response your API contract requires. The example
continues the request when the call succeeds and sends `429 Too Many Requests` when spike control
rejects the call for rate reasons.

## Interpret Spike Control Errors

`Err(SpikeControlError::TooManyRequests(_))` means traffic exceeded the tier for that bucket and
key. Other error variants signal internal faults, such as timer or storage problems. If you need
operational detail, log at the debug or warn level. If you can’t expose internal details, return a
generic message to clients.

## See Also

- [Implementing Your Custom Policy Features in Rust](https://docs.mulesoft.com/pdk/latest/policies-pdk-configure-features)

- [Configuring Delayed, Periodic, and Synchronous Functions](https://docs.mulesoft.com/pdk/latest/policies-pdk-configure-features-timer)

- [Rate Limiting Requests](https://docs.mulesoft.com/pdk/latest/policies-pdk-configure-features-rate-limiting)
