Advanced Features

This document covers advanced capabilities within Sling API specifications: pagination strategies, expression functions, incremental sync, and rules for error handling with retry logic.

For response processing basics (format handling, record extraction, deduplication, processors), see Response Processing.

Content Overview

Pagination

Pagination controls how Sling navigates through multiple pages of results for each iteration (if iterate is used) or for the single endpoint execution (if iterate is not used).

Pagination Flow

Common Pagination Patterns

1. Cursor-based Pagination

Uses the ID of the last record to fetch the next page.

2. Page Number Pagination

Increments a page number for each request.

3. Offset Pagination

Increments an offset value based on records received.

Extracts the next page URL from the response headers.

💡 Tip: For better performance, avoid using response variables in next_state expressions when possible. This allows Sling to prepare the next request before the current one finishes, increasing parallelism.

Functions

Functions are the building blocks of dynamic expressions in Sling API specifications. They enable sophisticated data transformations, validations, and manipulations within your API configurations.

Using Functions

Functions can be used throughout your API specification wherever expressions are supported, including:

  • Request Configuration: Dynamic URLs, headers, parameters, and payloads

  • Response Processing: Data transformation and extraction

  • Pagination Logic: Computing next page parameters

  • Conditional Logic: Rules, iteration conditions, and stop conditions

  • State Management: Transforming and aggregating state variables

Common Function Patterns

Dynamic Request Construction

Data Transformation in Processors

Pagination with Functions

Advanced Data Processing

Function Error Handling

Functions can help with graceful error handling and fallback values:

Best Practices

  1. Use coalesce() for Defaults: Always provide fallback values for optional fields

  2. Validate Required Fields: Use require() to ensure critical data is present

  3. Handle Date Formats: Use date_parse() with "auto" format when possible

  4. Escape Special Characters: Use encoding functions for URLs and other special contexts

  5. Test Complex Expressions: Break down complex expressions into smaller, testable parts

For a complete reference of all available functions, see the Functions documentation.

💡 Tip: Use the log() function during development to debug complex expressions: log("Processing record: " + record.id)

⚠️ Warning: Functions are evaluated for each record or iteration. Avoid expensive operations in frequently-called expressions.

Sync State for Incremental Loads

The sync key allows persisting state variables between runs, enabling incremental data loading (fetching only new or updated data).

Incremental Sync Workflow

Example: Timestamp-Based Incremental Sync

💡 Tip: Always use coalesce() with sync variables to handle the first run when no previous state exists.

Combining Incremental Sync with Context Variables

For advanced scenarios, you can combine sync state with context variables to support both incremental loading and backfilling. Context variables are runtime values passed from the replication configuration.

Key context variables for incremental sync:

  • context.range_start - Start of backfill range (from source_options.range)

  • context.range_end - End of backfill range (from source_options.range)

  • context.mode - Replication mode (incremental, full-refresh, backfill)

  • context.limit - Maximum records to fetch (from source_options.limit)

Example: Incremental with Backfill Support

Backfill Usage:

Incremental Usage:

This pattern allows the same endpoint to handle both historical backfills and ongoing incremental updates. See Context Variables for full details.

Rules & Retries

Rules define actions based on response conditions (status codes, headers, body content), providing fine-grained control over error handling and retries.

Rules Evaluation Flow

Rule Properties

Property
Required
Description
Example

action

Yes

Action to take when condition is true

"retry", "continue", "stop", "break", "skip", "fail"

condition

Yes

Expression that triggers the action

"response.status == 429"

max_attempts

No (for retry)

Max number of retry attempts

5 (default: 3)

backoff

No (for retry)

Strategy for delay between retries

"exponential", "linear", "constant", "jitter", "none"

backoff_base

No (for retry)

Initial delay in seconds

2 (default: 1)

message

No

Message for logging (supports expressions)

"Rate limit hit, retrying..."

Rule Actions

Action
Description
Use Case

retry

Retry the request after delay

Rate limits (429), server errors (>=500)

continue

Process response, ignore error

Non-critical errors (e.g., 404 for optional resources)

skip

Break out of the rule evaluation loop and skip this request

When a request should not be processed

break

Stop the current iteration gracefully without error

Stop iteration within loops when processing complete

stop

Stop current endpoint/iteration

When further requests would be useless

fail

Stop Sling run with error

Critical errors (auth failure, invalid parameters)

Example Rules

📝 Note: Rules are evaluated in order. The first matching rule's action is executed.

Backoff Strategies

When a rule uses the retry action, the backoff strategy determines how long to wait between retry attempts.

Backoff Types

Type
Calculation
Use Case
Example Delays (backoff_base=1)

none

No delay

Immediate retries (use cautiously)

0s, 0s, 0s, ...

constant

Fixed delay

Predictable retry timing

1s, 1s, 1s, ...

linear

base × attempt

Gradual backoff

1s, 2s, 3s, 4s, 5s, ...

exponential

base × 2^(attempt-1)

Aggressive backoff (recommended)

1s, 2s, 4s, 8s, 16s, ...

jitter

exponential + random(0-50%)

Avoid thundering herd

1s, 3s, 5s, 10s, 20s, ...

Backoff Examples with Timing

None (No Backoff)

Retry Timeline:

  • Request 1 (fails) → 0s wait

  • Request 2 (fails) → 0s wait

  • Request 3 (fails) → Give up

⚠️ Warning: No backoff can overwhelm failing services. Use only when retries must be immediate.

Constant Backoff

Retry Timeline:

  • Request 1 (fails) → Wait 2s

  • Request 2 (fails) → Wait 2s

  • Request 3 (fails) → Wait 2s

  • Request 4 (fails) → Wait 2s

  • Request 5 (fails) → Give up

Total time: ~8 seconds

Linear Backoff

Retry Timeline:

  • Request 1 (fails) → Wait 3s (3 × 1)

  • Request 2 (fails) → Wait 6s (3 × 2)

  • Request 3 (fails) → Wait 9s (3 × 3)

  • Request 4 (fails) → Wait 12s (3 × 4)

  • Request 5 (fails) → Give up

Total time: ~30 seconds

Retry Timeline:

  • Request 1 (fails) → Wait 2s (2 × 2⁰ = 2)

  • Request 2 (fails) → Wait 4s (2 × 2¹ = 4)

  • Request 3 (fails) → Wait 8s (2 × 2² = 8)

  • Request 4 (fails) → Wait 16s (2 × 2³ = 16)

  • Request 5 (fails) → Give up

Total time: ~30 seconds

💡 Tip: Exponential backoff is the industry standard for API retries. It quickly backs off from transient failures while giving services time to recover.

Jitter Backoff (Best for High Concurrency)

Retry Timeline (example with random jitter):

  • Request 1 (fails) → Wait 2.3s (2s + 15% jitter)

  • Request 2 (fails) → Wait 5.1s (4s + 28% jitter)

  • Request 3 (fails) → Wait 10.4s (8s + 30% jitter)

  • Request 4 (fails) → Wait 20.8s (16s + 30% jitter)

  • Request 5 (fails) → Give up

Total time: ~38 seconds (varies due to randomness)

📝 Note: Jitter adds 0-50% random delay to exponential backoff. This prevents multiple clients from retrying simultaneously (thundering herd problem).

Choosing the Right Backoff Strategy

Scenario
Recommended Strategy
Reasoning

Rate limits (429)

exponential or jitter

Gives API time to recover quota

Server errors (5xx)

exponential

Allows server recovery time

Temporary network issues

linear

Moderate, predictable backoff

Must retry immediately

constant with low base

Fast retries, simple timing

High-concurrency scenarios

jitter

Prevents retry storms

Rate Limit Handling

Sling automatically detects and respects rate limit headers from API responses. This works in conjunction with backoff strategies to optimize retry timing.

Automatic Rate Limit Detection

When a retry rule triggers on a 429 status, Sling automatically checks for rate limit headers:

Supported Rate Limit Headers

Sling checks for these headers in order of priority:

1. IETF Standard Headers (Preferred)

Header
Description
Example

RateLimit-Reset

Seconds until quota resets

60 (wait 60 seconds)

RateLimit-Remaining

Requests remaining in window

0

RateLimit-Policy

Rate limit window and quota

"60;q=100;w=60"

Behavior: Sling will wait 30 seconds before retrying.

2. Legacy/Alternative Headers

Header
Description
Example

Retry-After

Seconds or HTTP date to retry after

120 or Wed, 21 Oct 2025 07:28:00 GMT

X-RateLimit-Reset

Unix timestamp when quota resets

1743158739

Behavior: Sling will wait 60 seconds before retrying.

Rate Limit Header Processing

When rate limit headers are detected, they override the backoff calculation:

Rate Limit Policy Parsing

For APIs using the IETF RateLimit-Policy header:

Format: "name";q=quota;w=window

  • q: Quota (number of requests)

  • w: Window duration (seconds)

Sling's behavior:

  • If RateLimit-Remaining is 0, waits for the full window

  • Otherwise, calculates proportional wait: window × (1 - remaining/quota)

Complete Rate Limit Example

What happens:

  1. On first 429, checks for RateLimit-Reset header

  2. If found, waits that duration (ignoring backoff calculation)

  3. If not found, uses exponential backoff (2s, 4s, 8s, ...)

  4. Retries up to 5 times

  5. Fails if still getting 429 after all retries

Testing Rate Limits

Use the trace flag to see rate limit handling in action:

Look for output like:

💡 Tip: Most well-designed APIs include rate limit headers. Always use exponential or jitter backoff as a fallback for APIs that don't.

Last updated

Was this helpful?