Search queries are usually small, so the increased load on the server may not be as significant as you think. Sending a request for every keystroke should be great if you keep a limit on the length of requests.
In any case, this is a server that knows how it is loaded, so the place to control the download is on the server side. For example, you could follow a strategy something like this:
On the client:
- When changing the search text, send it to the server.
- When the server sends some results, refresh the page.
On the server, when the request is received from the client:
- If I am already processing a request from this client, cancel the old request.
- , .
- , .