Fixed Delay
Fixed delay provides the simplest retry strategy—waiting the same amount of time between every retry. Ideal for file system operations and scenarios where consistent behavior is preferred.
When to Use
Use fixed delay when:
- Processing file system operations
- Dealing with expected uniform recovery times
- You need simplicity and predictability
- Testing retry behavior (without jitter)
Why This Matters
File system operations typically have uniform recovery times—a file handle releases immediately or within milliseconds. Unlike distributed services that need exponential backoff, file operations benefit from consistent, simple retry timing.
Fixed delays provide:
- Simplicity: Easy to understand and reason about
- Predictability: Testing becomes deterministic (no jitter variability)
- Efficiency: No overhead from calculating exponential growth
When not to use:
- External APIs: Use exponential backoff instead
- Databases: Use linear backoff instead
- Distributed systems: Use exponential backoff with jitter
Basic Configuration
using NPipeline;
using NPipeline.Pipeline;
var context = PipelineContext.Default;
context.UseFixedDelay(TimeSpan.FromSeconds(2));
Parameters:
- delay: The constant delay between retries
Delay Progression
With fixed delay of 2 seconds:
| Attempt | Delay |
|---|---|
| 1 | 2 seconds |
| 2 | 2 seconds |
| 3 | 2 seconds |
| 4 | 2 seconds |
| 5 | 2 seconds |
Always the same—predictable and simple.
Common Configurations
File System Operations (Recommended)
context.UseFixedDelay(TimeSpan.FromSeconds(2));
Rationale:
- File handles typically release immediately
- 2 seconds is reasonable for lock recovery
- Simple and effective
Quick Retry (Network Hiccups)
context.UseFixedDelay(TimeSpan.FromMilliseconds(500));
Use when:
- Expected immediate recovery
- Dealing with brief network glitches
- Need responsive behavior
Slow Retry (Heavy Load)
context.UseFixedDelay(TimeSpan.FromSeconds(10));
Use when:
- System under heavy load
- Can tolerate longer waits
- Upstream service needs more recovery time
Testing (Preferred)
Fixed delay is perfect for unit and integration tests because results are deterministic:
[Fact]
public async Task RetryBehavior_WithFixedDelay()
{
// No jitter = predictable timing for tests
var context = CreateTestContext();
context.UseFixedDelay(TimeSpan.FromMilliseconds(10));
var stopwatch = Stopwatch.StartNew();
await ExecuteWithRetries(context, maxRetries: 3);
stopwatch.Stop();
// With 3 retries and 10ms delay each:
// Expected minimum: 30ms (3 × 10ms)
Assert.True(stopwatch.ElapsedMilliseconds >= 30);
}
With Jitter
While fixed delay is deterministic, adding jitter prevents synchronized retries in production:
var context = PipelineContext.Default;
context.UseFixedDelay(
TimeSpan.FromSeconds(2),
jitterStrategy: JitterStrategies.FullJitter());
Effect with 2s fixed delay + jitter:
- Actual delays will vary between 0-2 seconds randomly
- Prevents "thundering herd" when multiple clients retry
Pipeline Integration
public sealed class FileProcessingPipeline : IPipelineDefinition
{
public void Define(PipelineBuilder builder, PipelineContext context)
{
// Configure fixed delay for file operations
context.UseFixedDelay(TimeSpan.FromSeconds(2));
var source = builder.AddSource<FileSource, FileData>("file-source");
var transform = builder.AddTransform<FileTransform, FileData, ProcessedData>("transform");
var sink = builder.AddSink<FileSink, ProcessedData>("file-sink");
builder.Connect(source, transform);
builder.Connect(transform, sink);
builder.WithRetryOptions(new PipelineRetryOptions(
MaxItemRetries: 3,
MaxNodeRestartAttempts: 2,
MaxSequentialNodeAttempts: 5
));
}
}
Comparison with Other Strategies
| Strategy | Pattern | Best For |
|---|---|---|
| Fixed | ▁▁▁▁▁ | Files, predictability, tests |
| Linear | ╱╱╱╱╱ | Databases, lock contention |
| Exponential | ╱╱╱╱╱ (steep) | APIs, distributed services |
Best Practices
- Use for Testing: Fixed delays make tests deterministic
- Use for Files: File I/O recovery is typically uniform
- Add Jitter in Production: Prevent synchronized retries
- Keep Delay Reasonable: 1-5 seconds for most scenarios
- Monitor Performance: Ensure delays don't bottleneck pipeline
- Consider Context: Different operations may need different delays
Real-World Example
public sealed class FileProcessingExample
{
public async Task ProcessLargeFileAsync()
{
var context = PipelineContext.Default;
// Use fixed delay for file operations
context.UseFixedDelay(TimeSpan.FromSeconds(1));
var definition = new FileProcessingPipeline();
var runner = PipelineRunner.Create();
await runner.RunAsync(definition, context);
}
}
Related Topics
- Retry Configuration - Overall retry configuration options
- Retry Delays - Overview of all retry delay strategies
- Exponential Backoff - Exponential delay progression
- Linear Backoff - Linear delay progression
- Advanced Patterns - Custom strategies and patterns
- Testing Retries - Testing retry behavior
- Monitoring Retries - Observing retry metrics