Understanding and Resolving Race Conditions in API Requests

When working with OAuth connectors like Xero and Salesforce that require authentication tokens, race conditions can occur when multiple concurrent requests are made. This guide explains what's happening with the race condition and how to resolve it.

Diagram showing token refresh race condition problem and solution with Apideck

What is a Token Refresh Race Condition?

When working with OAuth-based APIs, access tokens have a limited lifespan and need to be refreshed periodically. A race condition can occur when multiple concurrent API requests are made with an access token that's about to expire.

The Problem

Here's what happens in a race condition scenario:

  1. Your application makes multiple concurrent API requests
  2. Each request independently checks if the token is about to expire
  3. If the token is about to expire, each request tries to refresh it
  4. This leads to multiple simultaneous token refresh operations
  5. Different requests might end up using different token versions
  6. Some requests might fail due to token validation issues

Why This Causes Problems

When multiple token refresh operations happen simultaneously:

  • Different requests might use different token versions
  • Some requests might fail due to token validation issues
  • The system might experience unexpected behavior due to inconsistent token states

What does this mean in the Apideck context?

  1. When Apideck receives a request, it checks if the access token will expire within 30 seconds
  2. If the token is about to expire, Apideck refreshes the token before processing the original request
  3. When multiple concurrent requests are made, each request independently triggers this token refresh process
  4. This leads to multiple simultaneous token refresh operations, which can cause inconsistencies

Visual Representation

Request 1 ──> Checks token ──> Refreshes token ──> Uses new token A ──> Success
                    │
Request 2 ──> Checks token ──> Refreshes token ──> Uses new token B ──> Success/Failure?
                    │
Request 3 ──> Checks token ──> Refreshes token ──> Uses new token C ──> Success/Failure?

The Solution

The solution is to validate the connection and refresh the token once before making any concurrent requests:

                                                  ┌──> Request 1 ──> Uses token X ──> Success
                                                  │
Validate connection ──> Refresh token once ──────┼──> Request 2 ──> Uses token X ──> Success
                                                  │
                                                  └──> Request 3 ──> Uses token X ──> Success

Implementation Steps

  1. Use the Apideck Vault API's validateConnectionState endpoint:
    • This endpoint forces a refresh of the access token
    • Returns a 200 status code on success
  2. Only after receiving a successful validation response, proceed with your concurrent requests

Best Practices

  • Always validate connections before starting a batch of concurrent requests
  • Consider implementing retry logic with exponential backoff for failed requests