Skip to content

Retry System API Reference

Retry Policies

boilermaker.retries.RetryPolicy

Bases: BaseModel

Configuration for task retry behavior and backoff strategies.

Defines how many times a task should be retried and with what delay pattern when it fails. Supports multiple backoff modes with configurable limits.

Attributes:

Name Type Description
max_tries int

Maximum number of execution attempts (default: 5)

delay int

Base delay in seconds between retries (default: 0)

delay_max int

Maximum delay cap in seconds (default: 3600)

retry_mode RetryMode

Strategy for calculating delays (default: Fixed)

Example

Fixed delay of 60 seconds, max 3 attempts

policy = RetryPolicy(max_tries=3, delay=60, retry_mode=RetryMode.Fixed)

Exponential backoff starting at 30s, max 10 minutes

policy = RetryPolicy( ... max_tries=5, ... delay=30, ... delay_max=600, ... retry_mode=RetryMode.Exponential ... )

get_delay_interval(attempts_so_far)

Calculate delay in seconds before the next retry attempt.

Uses the configured retry mode to determine appropriate delay: - Fixed: Returns constant delay value (capped at delay_max) - Linear: Returns delay * attempts_so_far (capped at delay_max) - Exponential: Returns 2^attempts * delay with jitter (capped at delay_max)

Exponential mode includes random jitter to prevent thundering herd effects when many tasks retry simultaneously.

Parameters:

Name Type Description Default
attempts_so_far int

Number of previous attempts (0-based)

required

Returns:

Name Type Description
int int

Delay in seconds before next retry

Example

policy = RetryPolicy(delay=30, retry_mode=RetryMode.Exponential) policy.get_delay_interval(0) # First retry: ~15-30s policy.get_delay_interval(1) # Second retry: ~30-60s policy.get_delay_interval(2) # Third retry: ~60-120s

Source code in boilermaker/retries.py
def get_delay_interval(self, attempts_so_far: int) -> int:
    """Calculate delay in seconds before the next retry attempt.

    Uses the configured retry mode to determine appropriate delay:
    - Fixed: Returns constant delay value (capped at delay_max)
    - Linear: Returns delay * attempts_so_far (capped at delay_max)
    - Exponential: Returns 2^attempts * delay with jitter (capped at delay_max)

    Exponential mode includes random jitter to prevent thundering herd
    effects when many tasks retry simultaneously.

    Args:
        attempts_so_far: Number of previous attempts (0-based)

    Returns:
        int: Delay in seconds before next retry

    Example:
        >>> policy = RetryPolicy(delay=30, retry_mode=RetryMode.Exponential)
        >>> policy.get_delay_interval(0)  # First retry: ~15-30s
        >>> policy.get_delay_interval(1)  # Second retry: ~30-60s
        >>> policy.get_delay_interval(2)  # Third retry: ~60-120s
    """
    match self.retry_mode:
        case RetryMode.Fixed:
            return min(self.delay, self.delay_max)
        case RetryMode.Linear:
            return min(self.delay * attempts_so_far, self.delay_max)
        case RetryMode.Exponential:
            # Jitter is added so that a lot of work doesn't get bunched up at the
            # end and eventually hurt throughput.
            exponential_delay = min(
                (2**attempts_so_far) * self.delay, self.delay_max
            )
            return (exponential_delay // 2) + random.randint(
                0, exponential_delay // 2
            )

Retry Exceptions

boilermaker.retries.RetryException(msg, policy=None)

Bases: Exception

Base exception class that can specify a custom retry policy.

When raised by a task function, this exception allows the task to override its default retry policy for this specific failure.

Attributes:

Name Type Description
msg

Error message describing the failure

policy

Custom retry policy to use (None for task default)

Example

def unreliable_task(): ... if should_retry_aggressively(): ... aggressive_policy = RetryPolicy(max_tries=10, delay=5) ... raise RetryException("Temporary failure", aggressive_policy) ... else: ... raise RetryException("Use default retry policy")

Source code in boilermaker/retries.py
def __init__(self, msg: str, policy: RetryPolicy | None = None):
    self.msg = msg
    self.policy = policy

boilermaker.retries.RetryExceptionDefault(msg)

Bases: RetryException

Retry exception that uses the default retry policy.

Convenience class for raising retriable exceptions with standard retry behavior (5 attempts, 120s fixed delay).

Example

def task_with_retries(): ... if network_unavailable(): ... raise RetryExceptionDefault("Network timeout")

Source code in boilermaker/retries.py
def __init__(self, msg: str):
    super().__init__(msg, policy=RetryPolicy.default())

boilermaker.retries.RetryExceptionDefaultExponential(msg, **kwargs)

Bases: RetryException

Retry exception with exponential backoff default policy.

Uses exponential backoff with jitter (30s base, 600s max, 5 attempts). Suitable for failures that may benefit from backing off more aggressively over time, such as rate limiting or temporary resource exhaustion.

Parameters:

Name Type Description Default
msg str

Error message

required
**kwargs

Override default policy parameters

{}
Example

def rate_limited_task(): ... if rate_limit_exceeded(): ... raise RetryExceptionDefaultExponential( ... "Rate limited", max_tries=3, delay=10 ... )

Source code in boilermaker/retries.py
def __init__(self, msg: str, **kwargs):
    defaults = {
        "max_tries": 5,
        "delay": 30,
        "delay_max": 600,
        "retry_mode": RetryMode.Exponential,
    }
    defaults.update(kwargs)
    super().__init__(msg, policy=RetryPolicy.model_validate(defaults))

boilermaker.retries.RetryExceptionDefaultLinear(msg, **kwargs)

Bases: RetryException

Retry exception with linear backoff default policy.

Uses linear backoff (30s base, 600s max, 5 attempts) where delay increases linearly with each attempt. Suitable for failures where a steady increase in wait time is appropriate.

Parameters:

Name Type Description Default
msg str

Error message

required
**kwargs

Override default policy parameters

{}
Example

def database_task(): ... if database_busy(): ... raise RetryExceptionDefaultLinear( ... "Database busy", delay=60, delay_max=300 ... )

Source code in boilermaker/retries.py
def __init__(self, msg: str, **kwargs):
    defaults = {
        "max_tries": 5,
        "delay": 30,
        "delay_max": 600,
        "retry_mode": RetryMode.Linear,
    }
    defaults.update(kwargs)
    super().__init__(msg, policy=RetryPolicy.model_validate(defaults))

Retry Modes

boilermaker.retries.RetryMode

Bases: IntEnum

Enumeration of retry backoff strategies.

Defines how delay intervals are calculated between retry attempts. Each mode provides different backoff behavior suitable for various failure scenarios and system load characteristics.

Attributes:

Name Type Description
Fixed

Constant delay between retries (e.g., 30s, 30s, 30s...)

Exponential

Exponentially increasing delay with jitter to prevent thundering herd

Linear

Linearly increasing delay (e.g., 30s, 60s, 90s...)

boilermaker.retries.NoRetry()

Bases: RetryPolicy

Retry policy that disables retries (single execution attempt only).

Convenience class that creates a RetryPolicy with max_tries=1, effectively disabling retry behavior. Tasks using this policy will be marked as failed after the first execution attempt.

Example

no_retry_task = Task.si(risky_function, policy=NoRetry())

Task will not retry on failure

Duplicates RetryPolicy.no_retry() constructor

Source code in boilermaker/retries.py
def __init__(self):
    """Duplicates RetryPolicy.no_retry() constructor"""
    super().__init__(max_tries=1, delay=5, delay_max=5, retry_mode=RetryMode.Fixed)