Skip to content
tezvyn:

How do you structure concurrent API calls with asyncio.gather in FastAPI?

Source: fastapi.tiangolo.comMediumHow cards are made

How do you structure concurrent API calls with asyncio.gather in FastAPI?

Tests FastAPI async concurrency. Strong answer: async def endpoint with two async HTTP requests in asyncio.gather, cutting total latency from sum to max of the two. Red flag: using sync clients or threads instead of async I/O.

What's really being asked

This tests whether you understand FastAPI's concurrency model for I/O-bound operations. FastAPI runs on Starlette and Uvicorn, which use an asyncio event loop. The interviewer wants to know if you grasp that independent network calls should not block each other and that asyncio.gather is the idiomatic tool for fanning out multiple awaitables. They also care whether you can articulate the latency win and avoid blocking the loop with synchronous libraries.

The full answer

First, declare the path operation with async def so FastAPI treats it as a coroutine. Second, use an async-capable HTTP client such as httpx.AsyncClient or aiohttp rather than synchronous requests. Third, structure the two fetches as independent coroutines and pass them to asyncio.gather to schedule them concurrently on the event loop. Fourth, explain the performance benefit in concrete terms: if API A takes 300 ms and API B takes 250 ms, sequential execution takes roughly 550 ms while concurrent execution takes roughly 300 ms, the maximum of the two. Fifth, mention error handling, noting that gather raises the first exception encountered unless return_exceptions=True is passed, and that you should consider timeouts via asyncio.wait_for or the client itself.

The mistakes people make

A major red flag is using the standard synchronous requests library inside an async endpoint; this blocks the event loop and stalls all other requests. Another mistake is suggesting threading or multiprocessing for this use case, confusing parallelism with concurrency. Some candidates forget to await the gather result or try to use gather with regular synchronous functions, which does not create true concurrency. Proposing a global event loop manipulation or nest_asyncio is also a signal of weak asyncio fundamentals.

What usually comes next

The interviewer may ask what happens if one call fails, how you would apply a timeout to both calls, or how you would limit concurrency if the endpoint needed to fan out to fifty APIs instead of two. They might also ask how this changes under heavy load or whether you would cache one of the responses. Be ready to discuss backpressure and connection pooling with an async HTTP client.

A concrete example

Imagine an endpoint GET /dashboard that needs user profile data from a CRM and notification count from a messaging service. You write async def get_dashboard():, create an httpx.AsyncClient, then define coroutines fetch_crm() and fetch_messaging(). You call results = await asyncio.gather(fetch_crm(), fetch_messaging()). The event loop sends both requests, suspends while waiting for I/O, and resumes as each response arrives. Total latency is dictated by the slower service, not the sum.

Interview question

Which implementation correctly minimizes total latency when a FastAPI endpoint must fetch data from two independent external APIs?

  • a.Inside an async def endpoint, pass two httpx.AsyncClient coroutines to asyncio.gather and await the result.Correct
  • b.Inside an async def endpoint, pass two synchronous requests.get calls to asyncio.gather and await the result.
  • c.Inside an async def endpoint, await an httpx.AsyncClient call to the first API, then await a second call to the other API.
  • d.Inside an async def endpoint, run two synchronous requests.get calls concurrently using threading.Thread.
Why?

asyncio.gather with an async HTTP client schedules both I/O-bound coroutines concurrently on the event loop, reducing total latency to roughly the slower call. Option C is tempting because it uses async/await correctly, but sequential awaiting means the second request cannot start until the first finishes, so latencies add up.

Just read this? Test yourself on what you have been reading.

Read the original → fastapi.tiangolo.com

You just looked this up. Could you explain it out loud?

That is the part interviews actually test. Tezvyn takes questions like this one and gives you what the interviewer is really checking, the answer that lands, and the mistake that ends the conversation, in the four minutes before your next meeting.

The iPhone app is on the way

We are building it. Until it lands, nothing here is held back from you: every interview card, your saved cards, streaks and the job board all work in Safari, plus hundreds of free practice quizzes of thirty questions each. Sign in and it all carries over to the app the day it arrives.

Want it as an icon? Tap Share at the bottom of Safari, then Add to Home Screen. It opens full screen and the cards you have read stay available offline.

Get it on Google PlayiPhone app coming soon

We are hiring for this. Open roles that interview on fastapi — each one lists the topics its interview covers.

See open roles