Long-running operations (async responses) in Rest API - Time & Space Complexity
When dealing with long-running operations in APIs, it's important to understand how the time to complete grows as the work increases.
We want to know how waiting for async responses affects the total time as input size changes.
Analyze the time complexity of the following code snippet.
async function fetchData(ids) {
const results = [];
for (const id of ids) {
const response = await fetch(`/api/data/${id}`);
const data = await response.json();
results.push(data);
}
return results;
}
This code fetches data for each id one after another, waiting for each response before starting the next.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Fetching data from the API for each id.
- How many times: Once per id in the input list, sequentially.
Each id causes a separate fetch call that waits for a response before moving on.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | 10 fetch calls, done one after another |
| 100 | 100 fetch calls, each waiting for the previous |
| 1000 | 1000 fetch calls, total time grows with each call |
Pattern observation: Total time grows roughly in direct proportion to the number of ids because calls happen one after another.
Time Complexity: O(n)
This means the total time grows linearly with the number of requests because each waits for the previous to finish.
[X] Wrong: "Since the calls are async, all requests happen at the same time, so time stays constant regardless of input size."
[OK] Correct: In this code, each fetch waits for the previous one to finish before starting, so calls happen one after another, not in parallel.
Understanding how async calls affect total time helps you design APIs and clients that handle many requests efficiently and shows you can reason about real-world performance.
What if we changed the code to start all fetch calls at once and then wait for all to finish? How would the time complexity change?
Practice
Solution
Step 1: Understand client-server interaction in async operations
Clients start a task and receive a URL to check progress later, avoiding waiting.Step 2: Identify the benefit of async responses
This approach keeps apps responsive and user-friendly by not blocking clients.Final Answer:
To let clients start a task and check its progress later without waiting. -> Option BQuick Check:
Async responses = clients check progress later [OK]
- Thinking server processes all requests instantly
- Assuming client waits for task completion
- Ignoring the use of status URLs
Solution
Step 1: Recall HTTP status codes for async start
202 Accepted means the request is accepted but processing is not complete yet.Step 2: Compare with other codes
200 OK means completed, 404 means missing resource, 500 means server error.Final Answer:
202 Accepted -> Option CQuick Check:
Async start = 202 Accepted [OK]
- Using 200 OK for async start
- Confusing 404 with async status
- Assuming 500 means task started
{"status": "accepted", "status_url": "/tasks/123/status"}What should the client do next to get the task result?
Solution
Step 1: Identify the purpose of status_url
The status_url is provided for the client to check the task progress or result.Step 2: Determine correct HTTP method to check status
GET requests are used to retrieve information, so client should GET the status URL.Final Answer:
Send a GET request to /tasks/123/status to check progress. -> Option DQuick Check:
Check progress = GET status URL [OK]
- Using POST instead of GET to check status
- Expecting server to push result without polling
- Using DELETE to check or cancel unintentionally
response = start_task()
if response.status_code == 202:
status_url = response.json()["status_url"]
result = requests.post(status_url)
print(result.json())What is the error in this code?
Solution
Step 1: Review HTTP method used to check status
The code uses POST to check status, but status URLs require GET requests.Step 2: Confirm other parts of code
Checking status_url existence and status_code handling are good practices but not the main error here.Final Answer:
Using POST instead of GET to check the status URL. -> Option AQuick Check:
Status check = GET, not POST [OK]
- Using POST instead of GET for status check
- Ignoring missing status_url key
- Not handling unexpected status codes
Solution
Step 1: Understand async response design
Server accepts task, returns 202 with status URL for client to poll progress.Step 2: Evaluate other options
Immediate processing (200 OK) blocks client; 404 is wrong status; holding connection open blocks client.Final Answer:
Client POSTs image, server returns 202 Accepted with a status URL; client polls status URL until done. -> Option AQuick Check:
Async design = 202 + status URL + polling [OK]
- Returning 200 OK immediately for slow tasks
- Using 404 for slow processing
- Keeping connection open until done
Ready to prove it?
Pass the test and this pattern moves unknown
