# SDS Exception Limiting vs Exception Rate Limiting in Didi SDS: A Complete Configuration Guide

> Understand SDS exception limiting vs exception rate limiting in Didi SDS. Learn configuration differences and optimal strategies for service degradation. Guide for didi/sds.

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

---

**Exception limiting** triggers service degradation after an absolute failure count exceeds `exceptionThreshold`, while **exception rate limiting** calculates the ratio of failures to successful calls once traffic surpasses `exceptionRateStart`, degrading services when the percentage exceeds `exceptionRateThreshold`—both mechanisms are configured via the `SdsStrategy` class in the didi/sds repository and enforced by distinct strategy executors.

The didi/sds (Service Degradation System) provides two orthogonal approaches to exception-based circuit breaking. Understanding the distinction between these exception handling strategies allows operators to protect low-traffic services with hard caps and high-traffic services with percentage-based thresholds that account for normal variance.

## Core Differences Between Exception Limiting and Exception Rate Limiting

Both mechanisms utilize the same strategy executor chain but implement distinct rules in separate executor classes:

- **Exception limiting** guards against absolute failure volume using `ExceptionStrategyExecutor`. It checks whether the total exception count recorded for a business point exceeds the configured `exceptionThreshold`. This approach is ideal for catching sudden bursts of failures regardless of overall traffic volume.

- **Exception rate limiting** guards against failure proportion using `ExceptionRateStrategyExecutor`. It computes the failure rate as `exceptionCount / (visitCount - downgradeCount)` only after the visit count exceeds `exceptionRateStart`. If this percentage exceeds `exceptionRateThreshold`, the point is downgraded. This prevents premature degradation during low-traffic periods with statistically insignificant failure samples.

The two executors operate independently within the degradation pipeline. If either executor determines its threshold is violated, it returns `false` from its `judge(...)` method, triggering the downgrade action.

## Configuration Parameters in SdsStrategy

All threshold configurations reside in the `SdsStrategy` class located at [`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):

```java
public class SdsStrategy {
    // Absolute count threshold (line 36)
    private Long exceptionThreshold = -1L;
    
    // Rate limiting percentage 0-100 (line 53)
    private Integer exceptionRateThreshold = -1;
    
    // Minimum visits before rate calculation (line 59)
    private Long exceptionRateStart = 0L;
}

```

**Disabling conditions:**
- Set `exceptionThreshold` ≤ 0 to disable absolute count checking
- Set `exceptionRateThreshold` ≤ 0 or > 100 to disable rate-based checking  
- Set `exceptionRateStart` ≤ 0 to evaluate rates from the first request (useful for high-traffic scenarios), or set a positive value to defer calculation until sufficient samples exist

## Exception Limiting: Absolute Count Threshold

The `ExceptionStrategyExecutor` (source: [`sds-client/src/main/java/com/didiglobal/sds/client/strategy/executor/ExceptionStrategyExecutor.java`](https://github.com/didi/sds/blob/main/sds-client/src/main/java/com/didiglobal/sds/client/strategy/executor/ExceptionStrategyExecutor.java)) implements the absolute count check. When the exception counter for a specific point exceeds `exceptionThreshold`, the executor flags the point for immediate downgrade.

This executor reads the current exception count from the `CheckData` object populated by `CommonSdsClient.exceptionSign(...)`. The `exceptionSign` method (lines 51-66 in [`CommonSdsClient.java`](https://github.com/didi/sds/blob/main/CommonSdsClient.java)) increments counters only when the caught exception matches the configured "downgrade exception" list, ensuring that business logic exceptions do not trigger false positives unless explicitly configured.

## Exception Rate Limiting: Percentage-Based Thresholds

The `ExceptionRateStrategyExecutor` (source: [`sds-client/src/main/java/com/didiglobal/sds/client/strategy/executor/ExceptionRateStrategyExecutor.java`](https://github.com/didi/sds/blob/main/sds-client/src/main/java/com/didiglobal/sds/client/strategy/executor/ExceptionRateStrategyExecutor.java)) implements the ratio check with the formula:

```

failureRate = exceptionCount / (visitCount - downgradeCount)

```

The executor evaluates this formula only when `visitCount > exceptionRateStart`. This design prevents volatile failure percentages during service warmup or low-traffic periods. Once the start threshold is met, if the calculated percentage exceeds `exceptionRateThreshold`, the point enters degradation mode.

The denominator excludes `downgradeCount` to ensure that once degradation begins, the existing downgraded requests do not artificially inflate the failure rate calculation for subsequent evaluation cycles.

## Configuring Exception Limits in Production

### Via Admin UI or Database

The most common configuration method persists settings through the `point_strategy` table, mapped by `PointStrategyDao` ([`sds-admin/src/main/java/com/didiglobal/sds/admin/dao/PointStrategyDao.java`](https://github.com/didi/sds/blob/main/sds-admin/src/main/java/com/didiglobal/sds/admin/dao/PointStrategyDao.java)). The admin controller ([`PointStrategyController.java`](https://github.com/didi/sds/blob/main/PointStrategyController.java)) exposes REST endpoints that translate UI inputs into `SdsStrategy` property updates.

Example MyBatis SQL mapping for threshold fields:

```sql
INSERT INTO point_strategy (point_name, exception_threshold, exception_rate_threshold, exception_rate_start)
VALUES (#{point}, #{exceptionThreshold}, #{exceptionRateThreshold}, #{exceptionRateStart});

```

### Programmatic Configuration

For runtime adjustments via the Java client:

```java
// Retrieve existing strategy for point "paymentService"
SdsStrategy strategy = SdsStrategyService.getInstance().getStrategy("paymentService");

// Configure absolute limit: degrade after 50 failures
strategy.setExceptionThreshold(50L);

// Configure rate limit: check after 1000 visits, degrade if > 15% failure rate
strategy.setExceptionRateStart(1000L);
strategy.setExceptionRateThreshold(15);

// Persist changes
SdsStrategyService.getInstance().addOrUpdateStrategy(strategy);

```

### Client-Side Exception Registration

Define which exception types count toward failure statistics using `SdsPointStrategyConfig`:

```java
import com.didiglobal.sds.client.config.SdsPointStrategyConfig;

// Register RuntimeException and SQLException as downgrade triggers
List<Class<?>> downgradeExceptions = Arrays.asList(
    RuntimeException.class, 
    SQLException.class
);
SdsPointStrategyConfig.setDowngradeExceptions("paymentService", downgradeExceptions);

```

Note that `SdsPointStrategyConfig` ([`sds-client/src/main/java/com/didiglobal/sds/client/config/SdsPointStrategyConfig.java`](https://github.com/didi/sds/blob/main/sds-client/src/main/java/com/didiglobal/sds/client/config/SdsPointStrategyConfig.java)) handles exception classification and downgrade delay configuration, while thresholds themselves are managed via `SdsStrategyService` or the admin database.

## Selecting the Appropriate Limiting Strategy

| Traffic Pattern | Recommended Configuration | Rationale |
|-----------------|---------------------------|-----------|
| **Low-traffic or critical services** | Enable `exceptionThreshold` only | Hard caps prevent cascading failures even with small sample sizes where percentage fluctuations are statistically meaningless |
| **High-traffic microservices** | Enable `exceptionRateThreshold` with `exceptionRateStart` | Avoids false positives from single failures during low-traffic windows; responds to sustained error rates |
| **Mission-critical endpoints** | Enable both simultaneously | Protects against sudden failure bursts (absolute count) and gradual service degradation (percentage rate) |

## Complete Implementation Example

The following example demonstrates configuring both limits for a payment processing endpoint and simulating exception recording:

```java
import com.didiglobal.sds.client.SdsClientFactory;
import com.didiglobal.sds.client.bean.SdsStrategy;
import com.didiglobal.sds.client.service.SdsStrategyService;

public class SdsConfigurationExample {
    
    public void setupPaymentProtection() {
        String point = "processPayment";
        SdsStrategy strategy = new SdsStrategy();
        strategy.setPoint(point);
        
        // Absolute limit: maximum 20 exceptions tolerated
        strategy.setExceptionThreshold(20L);
        
        // Rate limit: evaluate after 2000 calls, trigger at 10% failure rate
        strategy.setExceptionRateStart(2000L);
        strategy.setExceptionRateThreshold(10);
        
        // Persist to SDS admin
        SdsStrategyService.getInstance().addOrUpdateStrategy(strategy);
    }
    
    public void executePayment() {
        String point = "processPayment";
        boolean downgraded = SdsClientFactory.getSdsClient().shouldDowngrade(point);
        
        if (downgraded) {
            // Return cached response or throw fallback exception
            return;
        }
        
        try {
            // Execute business logic
            performDatabaseTransaction();
        } catch (RuntimeException ex) {
            // Record exception for SDS statistics
            SdsClientFactory.getSdsClient().exceptionSign(point, ex);
            throw ex;
        }
    }
}

```

The `shouldDowngrade` method internally invokes the executor chain, including both `ExceptionStrategyExecutor` and `ExceptionRateStrategyExecutor`, to determine if the current request should be rejected based on the configured thresholds.

## Summary

- **Exception limiting** uses `exceptionThreshold` in `SdsStrategy` to enforce an absolute cap on failure counts, implemented by [`ExceptionStrategyExecutor.java`](https://github.com/didi/sds/blob/main/ExceptionStrategyExecutor.java).
- **Exception rate limiting** uses `exceptionRateThreshold` and `exceptionRateStart` to enforce percentage-based degradation, implemented by [`ExceptionRateStrategyExecutor.java`](https://github.com/didi/sds/blob/main/ExceptionRateStrategyExecutor.java) using the formula `exceptionCount / (visitCount - downgradeCount)`.
- Both strategies can be enabled simultaneously or independently by setting fields to positive values (or disabling with values ≤ 0).
- Configurations are stored in the `SdsStrategy` bean, persisted via `PointStrategyDao`, and evaluated against counters updated through `CommonSdsClient.exceptionSign(...)`.

## Frequently Asked Questions

### Can I enable both exception limiting and exception rate limiting for the same service point?

Yes. The `SdsStrategy` class supports simultaneous configuration of both `exceptionThreshold` and `exceptionRateThreshold`. When both are enabled, the strategy executor chain evaluates each rule independently. If either the absolute count exceeds the threshold or the calculated failure rate exceeds the percentage limit (after `exceptionRateStart` is met), the service point will enter downgrade mode.

### What is the purpose of the `exceptionRateStart` parameter?

The `exceptionRateStart` parameter prevents premature degradation during low-traffic periods or service startup when the statistical sample size is too small to calculate a meaningful failure percentage. By setting this to a value such as `1000L`, you instruct `ExceptionRateStrategyExecutor` to ignore the failure rate calculation until at least 1000 visits have been recorded, avoiding volatile percentage swings caused by the first few requests failing.

### How does SDS determine which exceptions count toward the limiting thresholds?

SDS only increments the exception counter for exceptions explicitly registered via `SdsPointStrategyConfig.setDowngradeExceptions()` or configured through the admin interface. When `CommonSdsClient.exceptionSign(point, ex)` is called, the client checks if the thrown exception matches the registered list before updating the statistics. This allows business logic exceptions to be excluded from degradation decisions while system errors (like `IOException` or `SQLException`) trigger the counters.

### Where are the exception threshold configurations persisted in a production deployment?

The threshold values (`exceptionThreshold`, `exceptionRateThreshold`, `exceptionRateStart`) are stored in the `point_strategy` database table, accessed through [`PointStrategyDao.java`](https://github.com/didi/sds/blob/main/PointStrategyDao.java) in the `sds-admin` module. The admin web interface provides REST endpoints (handled by [`PointStrategyController.java`](https://github.com/didi/sds/blob/main/PointStrategyController.java)) to update these values dynamically without requiring application restarts, though the SDS client also supports programmatic configuration through `SdsStrategyService` for testing scenarios.