Consecutive HTTP
A Consecutive HTTP issue is created when your service makes several slow calls to other services one after another, and those calls don't depend on each other. Because they are independent, they could have been made at the same time, and the request would have finished much sooner.
This matters more for HTTP calls than for database queries, because calls to other services tend to be slower and less predictable. If a request makes three calls that each take a second, doing them one by one costs three seconds. Doing them together costs about one.
This issue is found in APM.
How Middleware detects it#
Middleware looks at the outgoing HTTP calls made under one operation in a request. It flags a run of calls when:
- The calls happen back to back, each starting after the previous one has finished, with only a short gap between them.
- Each call is slow. Fast calls are not reported, since there is little to gain from changing them.
- There are several of them in the run.
- The time you could save by running them together is significant.
The issue title tells you how much time could be saved, so you can decide whether the change is worth making. Middleware can't see inside your code, so it can't know for certain that the calls are independent. Check that before you change anything.
What you'll see in Middleware#

The title shows how many calls ran in sequence, the operation they belong to, and how much time could be saved, for example 5 sequential HTTP calls in /checkout (2405ms could be saved). Open the issue to see each call in order.
Common causes#
- A service that gathers data from several other services and calls them one at a time.
- Code written step by step, where each call is placed after the last out of habit, not because it needs the result.
- Missing concurrency. The language supports parallel work, but this code path doesn't use it.
- A chain of helper functions that each make their own call, run one after another.
How to fix it#
- Make the calls in parallel. Start every independent call first, then wait for all of them to finish. Most languages offer this through promises, async tasks, goroutines, futures, or thread pools.
- Keep dependent calls in order. If one call needs the result of another, it has to wait. Only parallelize the ones that don't.
- Speed up the slowest call. When calls run in parallel, the slowest one sets the total time. Making that one faster now helps the whole request.
- Combine calls where you can. If the other service offers a single endpoint that returns everything you need, one request can replace several.
- Set timeouts. When you run calls in parallel, a single hung call can hold up the whole request. A sensible timeout keeps that contained.
Example#
A checkout service calls a pricing service, an inventory service, and a shipping-estimate service to build an order summary. Each call takes about 900 milliseconds, and the code makes them one after the other, so the summary takes about 2.7 seconds.
None of the three calls needs data from the others. After changing the code to start all three at once and wait for them together, the summary takes a little over 900 milliseconds. The Consecutive HTTP issue stops receiving new occurrences.
Related issues#
- Consecutive DB Queries: the same idea, for database queries.
- N+1 API Calls: the same endpoint called again and again.
Need assistance or want to learn more about Middleware? Get in touch with us via our Contact Us or join our Slack channel.