What Are Concurrent Requests?
Concurrent requests refer to HTTP calls that execute simultaneously rather than sequentially. When your application needs data from multiple API endpoints, firing those requests in parallel significantly reduces total load time compared to waiting for each request to complete before starting the next.
For three requests with 500ms response times each, sequential execution requires approximately 1500ms total. The same three requests fired concurrently complete in roughly 500ms, as they execute in parallel. This threefold improvement directly impacts perceived performance and user satisfaction in mobile applications.
Key benefits of concurrent requests:
- Faster data loading across multiple endpoints
- Improved user experience with responsive interfaces
- Efficient use of network connections
- Better handling of real-time data requirements
LogRocket's concurrent request fundamentals provide deeper insights into these patterns.
Why Axios for Concurrent Requests?
Axios offers several advantages for managing concurrent HTTP operations:
- Promise-based API that integrates naturally with async/await
- Automatic JSON transformation
- Configurable timeouts and interceptors
- Consistent error handling across iOS and Android
The Axios library works seamlessly in React Native applications, providing a consistent API across platforms. Its popularity ensures extensive community support and comprehensive documentation for production applications. When building mobile apps with React Native, Axios provides the reliability and flexibility needed for complex data fetching scenarios.
For web applications that integrate with mobile backends, Axios also serves as an excellent HTTP client in web development, maintaining consistent request patterns across your entire technology stack.
1import axios from 'axios';2 3async function fetchDashboardData() {4 const requestOne = axios.get('https://api.example.com/users');5 const requestTwo = axios.get('https://api.example.com/posts');6 const requestThree = axios.get('https://api.example.com/notifications');7 8 const responses = await axios.all([requestOne, requestTwo, requestThree]);9 10 const users = responses[0].data;11 const posts = responses[1].data;12 const notifications = responses[2].data;13 14 return { users, posts, notifications };15}Using axios.spread for Cleaner Response Handling
The axios.spread utility function distributes the array of responses from axios.all into separate arguments. This makes accessing individual responses more intuitive without array indexing. The spread approach transforms an array of responses into individual parameters, enabling destructuring assignment and providing clear, named variables for each result.
How axios.spread distributes responses:
When axios.all resolves, it returns an array of response objects in the same order as the original request array. The axios.spread function takes a callback where each parameter corresponds to one response, eliminating the need for array indexing. This is particularly valuable when working with four or more concurrent requests where manual indexing becomes error-prone and reduces code readability.
Destructuring as an alternative:
Modern JavaScript destructuring combined with axios.all often eliminates the need for explicit axios.spread calls. For simple scenarios, direct array destructuring provides a cleaner alternative that works seamlessly with both axios.all and Promise.all. This approach makes your code more portable and consistent across different promise-returning operations.
When to use each pattern:
Use axios.spread when you prefer callback-style code, need compatibility with older JavaScript environments, or find the functional style more readable. Use destructuring when you prefer async/await syntax, want to avoid additional function wrappers, or need to integrate with other await expressions in your code. Both patterns are commonly used in React Native development for fetching data from REST APIs and integrating with backend services built with modern web technologies.
1import axios from 'axios';2 3async function fetchUserProfile(userId) {4 const profileRequest = axios.get(`/api/users/${userId}`);5 const postsRequest = axios.get(`/api/users/${userId}/posts`);6 const followersRequest = axios.get(`/api/users/${userId}/followers`);7 8 return axios.all([profileRequest, postsRequest, followersRequest])9 .then(axios.spread((profile, posts, followers) => {10 return {11 profile: profile.data,12 posts: posts.data,13 followers: followers.data14 };15 }));16}Key patterns and practices for reliable concurrent API calls
Error Handling
Handle errors for individual requests or collectively catch all failures at once depending on your requirements.
Request Interceptors
Add authentication headers, logging, and request transformations globally across all axios requests.
Cancellation Tokens
Cancel pending requests when components unmount to prevent memory leaks and unnecessary network usage.
Dynamic Request Arrays
Generate request arrays programmatically based on application state for flexible data fetching.
Error Handling Strategies
Robust error handling is essential when working with concurrent requests. Axios provides several patterns for managing failures effectively, from granular per-request error handling error collection.
Individual Request to aggregated Error Handling:
For scenarios where partial failures should be handled gracefully, attach catch handlers to individual requests before combining them. This approach prevents a single failure from rejecting the entire operation, allowing successful requests to complete while logging or recovering from failures. Each request can be wrapped with its own error handler that returns a null or default value, which you then filter out after all requests complete.
Collective Error Handling:
When any request failure should halt the entire operation, a single catch handler after axios.all provides simpler code and clearer intent. This approach suits scenarios where all data must be available for the application to function correctly, such as loading critical user profile data alongside permissions and settings.
Apidog's error handling patterns demonstrate these strategies in production scenarios.
Implementing proper error handling in your React Native app ensures users receive consistent feedback regardless of network conditions or API availability.
1import React, { useEffect, useState } from 'react';2import axios from 'axios';3 4const DashboardScreen = () => {5 const [data, setData] = useState({ user: null, activity: [], notifications: [] });6 const [loading, setLoading] = useState(true);7 const [error, setError] = useState(null);8 9 useEffect(() => {10 const loadDashboard = async () => {11 try {12 const [userResponse, activityResponse, notificationsResponse] = await axios.all([13 axios.get('/api/user/profile'),14 axios.get('/api/user/activity'),15 axios.get('/api/notifications')16 ]);17 18 setData({19 user: userResponse.data,20 activity: activityResponse.data,21 notifications: notificationsResponse.data22 });23 setLoading(false);24 } catch (err) {25 setError('Failed to load dashboard data');26 setLoading(false);27 }28 };29 30 loadDashboard();31 }, []);32 33 if (loading) return <LoadingSpinner />;34 if (error) return <ErrorMessage message={error} />;35 36 return <DashboardView {...data} />;37};Request Cancellation in Mobile Apps
In mobile applications, users may navigate away from screens before requests complete. Implementing cancellation prevents memory leaks and unnecessary network usage, which is particularly important on devices with limited resources and battery constraints. The React Native component lifecycle controls data fetching and cleanup, making proper cancellation essential for optimal performance.
CancelToken Usage:
Axios CancelToken provides a mechanism to signal pending requests to abort when they're no longer needed. You create a cancel token source for each component or request batch, then pass the token to individual requests. When cancellation is needed, calling cancel on the source triggers an error in all requests using that token. This pattern works equally well with axios.all by creating a single cancel token source and passing its token to all requests in the concurrent array.
Component Unmounting Patterns:
The useEffect cleanup function is the ideal place to cancel pending requests when a component unmounts. By storing the cancel token source in a useRef, you can access it in both the effect function and the cleanup return. When the component unmounts, all pending requests receive cancellation signals simultaneously, preventing state updates on unmounted components and reducing unnecessary network traffic.
Cleanup Strategies:
Always cancel requests in the useEffect cleanup return when the component dependencies change or when the user navigates away. Check for cancellation errors using axios.isCancel() to distinguish between intentional cancellations and actual failures. This ensures your error handling logic doesn't treat expected cancellations as actual problems requiring user notification.
When debugging mobile apps across different devices, proper cancellation patterns help identify and resolve memory leaks and performance issues more effectively.
1import axios from 'axios';2import { useEffect, useRef } from 'react';3 4const UserDetailScreen = ({ userId }) => {5 const cancelTokenSource = useRef(axios.CancelToken.source());6 7 useEffect(() => {8 const fetchUserData = async () => {9 try {10 const response = await axios.get(`/api/users/${userId}`, {11 cancelToken: cancelTokenSource.current.token12 });13 setUserData(response.data);14 } catch (error) {15 if (axios.isCancel(error)) {16 console.log('Request cancelled');17 } else {18 setError(error.message);19 }20 }21 };22 23 fetchUserData();24 25 return () => {26 cancelTokenSource.current.cancel('Component unmounted');27 };28 }, [userId]);29 30 return <UserView userData={userData} />;31};Frequently Asked Questions
Sources
- LogRocket: Using axios.all to make concurrent requests - Foundational concepts, axios.all/axios.spread syntax, Promise.all comparison
- Apidog: How to make Multiple Requests with Axios - Error handling strategies, interceptors, real-world examples
- Axios Documentation - Official HTTP client documentation