Skip to main content

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:

AttemptDelay
12 seconds
22 seconds
32 seconds
42 seconds
52 seconds

Always the same—predictable and simple.

Common Configurations

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

StrategyPatternBest For
Fixed▁▁▁▁▁Files, predictability, tests
Linear╱╱╱╱╱Databases, lock contention
Exponential╱╱╱╱╱ (steep)APIs, distributed services

Best Practices

  1. Use for Testing: Fixed delays make tests deterministic
  2. Use for Files: File I/O recovery is typically uniform
  3. Add Jitter in Production: Prevent synchronized retries
  4. Keep Delay Reasonable: 1-5 seconds for most scenarios
  5. Monitor Performance: Ensure delays don't bottleneck pipeline
  6. 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);
}
}