# SDS Timeout Limiting: Statistical Logic and Threshold Configuration in Didi SDS

> Understand Didi SDS timeout limiting with its statistical logic. Learn how timeoutThreshold and timeoutCountThreshold in a 10-second window trigger degradation.

- Repository: [DiDi/sds](https://github.com/didi/sds)
- Tags: deep-dive
- Published: 2026-02-28

---

**SDS timeout limiting uses a two-layer statistical model that checks individual request duration against `timeoutThreshold` and aggregate timeout counts against `timeoutCountThreshold` within a 10-second sliding window to trigger degradation.**

SDS (Service Degradation System) from the didi/sds repository implements timeout-based degradation through a sophisticated statistical engine that monitors both per-request latency and windowed failure rates. Understanding the interaction between duration thresholds and count thresholds is essential for configuring effective circuit-breaking behavior in high-throughput services.

## Two-Layer Statistical Model for Timeout Detection

SDS evaluates timeout-related degradations through a dual-threshold system that operates at different granularities.

### Layer 1: Duration Threshold (Individual Request Latency)

The **duration threshold** defines the maximum acceptable execution time for a single request in milliseconds. In [`sds-client/src/main/java/com/didiglobal/sds/client/bean/SdsStrategy.java`](https://github.com/didi/sds/blob/main/sds-client/src/main/java/com/didiglobal/sds/client/bean/SdsStrategy.java), this is stored as `timeoutThreshold` (default `-1` disables the check).

When a request completes, `CommonSdsClient.downgradeFinally` compares the actual `consumeTime` against this threshold. If `consumeTime > timeoutThreshold`, the system increments the timeout counter via `SdsPowerfulCounterService.timeoutInvokeAddAndGet`.

### Layer 2: Count Threshold (Sliding Window Aggregation)

The **count threshold** specifies the maximum number of timeouts permitted within a sliding time window. This uses a **10-second window divided into 10 buckets** (1 second per bucket), implemented in `PowerfulCycleTimeCounter.timeoutData`.

During the degradation decision phase, `TimeoutStrategyExecutor.strategyCheck` retrieves the current window count via `SdsPowerfulCounterService.getTimeoutInvoke` and compares it against `timeoutCountThreshold`. Exceeding this value triggers degradation for the point.

## Runtime Execution Flow

The timeout limiting mechanism executes across three distinct phases during request processing.

### Strategy Definition

Developers configure thresholds through the `SdsStrategy` bean or admin console. Both thresholds must be positive values to activate timeout limiting:

```java
// SdsStrategy.java
private Long timeoutThreshold = -1L;        // ms, -1 = disabled
private Long timeoutCountThreshold = -1L;   // count in sliding window, -1 = disabled

```

These values persist to the database through [`sds-admin/src/main/java/com/didiglobal/sds/admin/dao/bean/PointStrategyDO.java`](https://github.com/didi/sds/blob/main/sds-admin/src/main/java/com/didiglobal/sds/admin/dao/bean/PointStrategyDO.java) as `timeout_threshold` and `timeout_count_threshold` columns.

### Timeout Detection and Collection

After each request executes, `CommonSdsClient.downgradeFinally` performs the duration check:

```java
Long timeoutThreshold = strategy.getTimeoutThreshold();
if (timeoutThreshold != null && timeoutThreshold > 0 && consumeTime > timeoutThreshold) {
    SdsPowerfulCounterService.getInstance()
            .timeoutInvokeAddAndGet(point, downgradeStartTimeValue);
}

```

This code from [`CommonSdsClient.java`](https://github.com/didi/sds/blob/main/CommonSdsClient.java) (lines 120-128) ensures only requests exceeding the duration threshold contribute to the sliding window counter.

### Statistical Evaluation and Degradation Decision

During the `shouldDowngrade` evaluation, `TimeoutStrategyExecutor.strategyCheck` validates the windowed count:

```java
// TimeoutStrategyExecutor.java
if (strategy.getTimeoutCountThreshold() == null || strategy.getTimeoutCountThreshold() < 0) {
    return true;   // no timeout count rule → pass
}
return checkData.getTimeoutCount() < strategy.getTimeoutCountThreshold();

```

The method returns `false` (triggering degradation) when `timeoutCount` equals or exceeds the configured threshold.

## Configuring Timeout Thresholds

SDS supports both programmatic and declarative configuration methods.

### Programmatic Configuration

Define strategy parameters directly in code:

```java
SdsStrategy strategy = new SdsStrategy();
strategy.setPoint("myService.doWork");
strategy.setTimeoutThreshold(250L);          // 250 ms duration limit
strategy.setTimeoutCountThreshold(5L);       // 5 timeouts per 10-second window
SdsStrategyService.getInstance().addStrategy(strategy);

```

### Database and Admin Console Configuration

The admin interface and underlying data layer map these fields:

| Config Source | Database Column | Java Field |
|---------------|----------------|------------|
| Admin UI / JSON | `timeout_threshold` | `timeoutThreshold` |
| Admin UI / JSON | `timeout_count_threshold` | `timeoutCountThreshold` |

The [`PointStrategyDO.java`](https://github.com/didi/sds/blob/main/PointStrategyDO.java) class defines these mappings at lines 56-66.

## Critical Threshold Interactions

Understanding the dependency between these thresholds prevents configuration errors.

- **Both thresholds must be > 0** for timeout limiting to function. Setting only `timeoutThreshold` counts timeouts but never triggers degradation (the executor returns `true` unconditionally).

- **Setting only `timeoutCountThreshold`** without `timeoutThreshold` results in zero timeouts recorded, as the duration check in `CommonSdsClient` never increments the counter.

- **Typical production configuration** sets `timeoutThreshold = 300` ms and `timeoutCountThreshold = 10`, degrading the point after 10 slow requests within 10 seconds.

## Summary

- SDS timeout limiting employs a **two-layer statistical model** combining per-request duration checks with sliding-window count aggregation.
- The **duration threshold** (`timeoutThreshold`) in [`SdsStrategy.java`](https://github.com/didi/sds/blob/main/SdsStrategy.java) filters slow requests, incrementing counters in `PowerfulCycleTimeCounter.timeoutData`.
- The **count threshold** (`timeoutCountThreshold`) evaluated by `TimeoutStrategyExecutor.strategyCheck` triggers degradation when the 10-second sliding window exceeds the limit.
- Both thresholds require positive values; misconfiguring one disables the timeout limiting logic entirely.

## Frequently Asked Questions

### What happens if I only configure timeoutThreshold without timeoutCountThreshold?

SDS will detect and count requests exceeding the duration limit, but will never trigger degradation based on timeouts. The `TimeoutStrategyExecutor` returns `true` (allowing traffic) when `timeoutCountThreshold` is null or negative, effectively disabling the count-based check while still recording metrics.

### How does the sliding window calculate timeout counts?

The implementation uses `PowerfulCycleTimeCounter` with 10 buckets representing 10 seconds of history. The `SdsPowerfulCounterService.getTimeoutInvoke` method aggregates these buckets to return the total timeout count within the current window, providing the value used in `TimeoutStrategyExecutor.strategyCheck`.

### Where does SDS store timeout statistics at runtime?

Timeout counts reside in `PowerfulCycleTimeCounter.timeoutData`, an `AbstractCycleData` structure maintaining per-millisecond buckets. This data structure lives in the client-side counter service and resets automatically as the sliding window advances.

### Can I disable timeout limiting while keeping other SDS strategies active?

Yes. Set both `timeoutThreshold` and `timeoutCountThreshold` to `-1` (or null) in [`SdsStrategy.java`](https://github.com/didi/sds/blob/main/SdsStrategy.java). This disables the duration check in `CommonSdsClient.downgradeFinally` and bypasses the count evaluation in `TimeoutStrategyExecutor`, allowing exception-based or other degradation strategies to function independently.