Concurrency and Parallelism: Tips and Tricks for API Integrations

Efficient API integration requires smart ways to handle data. This guide looks at concurrency and parallelism—techniques that can speed up data processing and reduce delays in your integrations.
Written by
Ricardo Guntur, Senior Software Engineer
Published on
February 4, 2025

What are concurrency and parallelism?

  • Concurrency is the ability to manage multiple tasks simultaneously but not necessarily at the same instant. 
  • Parallelism is the act of executing multiple tasks simultaneously

Both can significantly boost performance and reduce overall runtime of your code, especially when dealing with I/O-bound tasks such as API requests where network latency has an impact. 

Why do they matter for API Integrations?

Most API integrations include these steps:

  1. Extract data from an external source
  2. Transform or process that data
  3. Push or load the transformed data into another system

For each step of the pipeline you may need to wait before moving on to the next step but within each step there are often many tasks that can happen simultaneously.

Using p-map in Javascript

For Javascript integrations we can utilize p-map, a popular package that simplifies processing data in parallel by applying an asynchronous function to each item in a list, with a specified level of concurrency.

Example scenario:

  • You need to fetch 50,000 records
  • The endpoint only supports 100 records per call
  • The API rate limit allows 50 requests per minute

Naive, Sequential Approach:

  • Make a request for 100 records, wait for the response.
  • Make the next request, wait again.
  • Repeat for all 50,000 records.

Although the theoretical rate limit is 50 per minute, the sequential approach may not take full advantage of it because you’re waiting for each request to finish before starting the next. By using p-map with a concurrency of 10, you can make 10 requests simultaneously. This approach reduces the overall impact of network latency by overlapping multiple requests.

A simplified code snippet with p-map might look like this:

Parallel Data Transformations

After fetching data, you may need to transform it – such as filtering, aggregating or other computations. Javascript’s default single-threaded event loop can become a bottleneck if transformations are CPU-intensive. Consider using p-map or worker threads.

Concurrency is not limited to Javascript. Nearly every programming language has robust libraries or built-in libraries for concurrency and parallelism. Here are some common examples:

Python

  • asyncio and aiohttp:
    • asyncio is Python’s standard asynchronous framework. You can create a list of coroutines and gather them together with asyncio.gather().
    • aiohttp is an HTTP client library designed for asyncio and is used for making concurrent API requests.
  • multiprocessing:
    • Good for CPU-bound tasks (data transformations, calculations). It will spin up separate processes to utilize multiple CPU cores.

Java

  • Parallel streams:
    • Java 8 introduced parallel streams, making it simpler to run stream operations concurrently. For example: yourList.parallelStream().map(...).collect(...).
  • ExecutorService/Thread Pools
    • Powerful for managing a pool of threads to handle concurrent tasks.

Best Practices and Considerations

  1. Respect API Rate Limits
    • Find the theoretical rate limit of the system you’re interacting with and prevent exceeding it or risk being throttled or blocked.
    • Consider traffic control strategies like token bucket to handle bursts of requests or leaky bucket to handle a steady stream of requests.
  2. Handle Errors Gracefully
    • With multiple requests in flight, you need robust error handling and potentially a retry mechanism for failed requests.
    • Below is a code snippet example of handling retries using axios.

  • And here is a snippet that handles if some requests fail when using p-map

  1. Mind Resource Constraints
    • It may be easy to just punch in 10 concurrent workers while writing code but be aware of the hardware that is running the script. Running simultaneous tasks will increase memory and CPU usage. Utilizing too many workers can worsen performance.
  2. Test and Tune
    • Experiment with different concurrency levels to see which yields the best throughput for your use case.

Leveraging concurrency and parallelism in API integrations can significantly enhance performance and efficiency. By implementing techniques such as p-map in JavaScript, asyncio in Python, or parallel streams in Java, developers can optimize ETL. However, it's crucial to balance these performance gains with responsible API usage, robust error handling, and careful resource management. As you implement these strategies, remember to respect rate limits, handle errors gracefully, and fine-tune your approach through testing. By mastering these concepts and best practices, you can create more efficient, scalable, and reliable API integrations that maximize throughput while minimizing potential issues.

Latest

From the Blog

Check out our latest content on technology partnerships, integration and APIs. Access research, resources, and advice from industry experts.

API Authentication Methods

Understand what authentication methods are available when using APIs including basic auth, JWT access token and OAuth 2.0.

A Guide to Integrating with Klaviyo's API

Get expert insights on integrating with the Klaviyo API. Understand authentication, customizations and triggers.