Short answer is no it isn't asynchronous. Longer answer is "Not unless you wrote the backend yourself to do so."
If you're using XHR, each request is going to have a different worker thread on the backend which means no request should block any other, barring hitting process and memory limits. While XHR presents an event-based interface, it's still a live HTTP request being handled synchronously by the browser (you only get 1 thread in js). The php backend is also synchronously making curl calls, not returning results for your XHR's http request until the curl call finishes. Now, you could set your javascript up to poll for results, but since your time-to-live is <3-5 seconds, it's not worth it.
If you're using websockets, then you'll have to tell us. A given websocket is tied to one process on the backend, but you can fork/thread/do whatever in that process. It also allows you to push events to the browser directly without the client initiating a request. This could be asynchronous, but if the slowdown is in your backend, it isn't going to help to change to an asynchronous design.
Realistically, you should have your client javascript wait to issue the next search until the last search returns. On the back side, to prevent DOS, if a single client starts sending you too many completion search requests, start dropping the requests with HTTP 429 and handle 429 responses in your JS to do incremental backoff and retry later if appropriate.
Another thing you should definitely be doing is setting the request timeout in curl to something much lower so it times out appropriately. If the search data is only useful for 2-3 seconds, your curl request timeout should be about the same. If your backend is intelligent enough, it will interpret a closed connection to mean "stop searching" and hopefully you'll stop the resource loss in time for another process to use them.