- Timeout (outer)
- Rate limiter
- Retry
- Circuit breaker
- Timeout (inner)
Benchmark Results
Compared to older versions, Polly v8 is both faster and more memory efficient.
Performance Tips
If you’re aiming for the best performance with Polly, consider these tips:Use Static Lambdas
Lambdas capturing variables from their outer scope will allocate on every execution. Polly provides tools to avoid this overhead, as shown in the example below:Use Switch Expressions for Predicates
ThePredicateBuilder maintains a list of all registered predicates. To determine whether the results should be processed, it iterates through this list. Using switch expressions can help you bypass this overhead.
Execute Callbacks Without Throwing Exceptions
Polly provides theExecuteOutcomeAsync API, returning results as Outcome<T>. The Outcome<T> might contain an exception instance, which you can check without it being thrown. This is beneficial when employing exception-heavy resilience strategies, like circuit breakers.
Using
ExecuteOutcomeAsync avoids the overhead of exception throwing and catching, which can be significant in high-throughput scenarios.Reuse Resilience Pipeline Instances
Creating a resilience pipeline can be resource-intensive, so it’s advisable not to discard the instance after each use. Instead, you can either cache the resilience pipeline or use theGetOrAddPipeline(...) method from ResiliencePipelineRegistry<T> to cache the pipeline dynamically:
You can also define your pipeline on startup using dependency injection and then use
ResiliencePipelineProvider<T> to retrieve the instance.Performance Best Practices Summary
Static Lambdas
Use static lambdas and pass state as parameters to avoid closure allocations.
Switch Expressions
Prefer switch expressions over PredicateBuilder for better performance.
Outcome API
Use ExecuteOutcomeAsync to avoid exception throwing overhead.
Reuse Pipelines
Cache and reuse resilience pipeline instances instead of creating new ones.