DEV Community

chen qin
chen qin

Posted on

Your AI API Request Is Hanging? Add a Timeout With AbortController

An AI API request should never be allowed to wait indefinitely.

Network problems, overloaded providers, or unexpectedly long generations can leave a request open much longer than your application should tolerate.

In JavaScript, AbortController provides a simple way to define a timeout and cancel the request.

A basic timeout wrapper

async function fetchWithTimeout(url, options = {}, timeoutMs = 15_000) {
  const controller = new AbortController();

  const timeoutId = setTimeout(() => {
    controller.abort();
  }, timeoutMs);

  try {
    return await fetch(url, {
      ...options,
      signal: controller.signal,
    });
  } finally {
    clearTimeout(timeoutId);
  }
}
Enter fullscreen mode Exit fullscreen mode

You can use it with an OpenAI-compatible endpoint:

const response = await fetchWithTimeout(
  "https://your-api-endpoint/v1/chat/completions",
  {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.AI_API_KEY}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      model: "your-model",
      messages: [
        {
          role: "user",
          content: "Explain exponential backoff in one paragraph.",
        },
      ],
    }),
  },
  30_000
);
Enter fullscreen mode Exit fullscreen mode

Handle cancellation separately

An aborted request should not be treated like every other network failure:

try {
  const response = await fetchWithTimeout(url, options, 30_000);

  if (!response.ok) {
    throw new Error(`HTTP ${response.status}`);
  }

  const data = await response.json();
  console.log(data);
} catch (error) {
  if (error.name === "AbortError") {
    console.error("The AI request exceeded its timeout.");
  } else {
    console.error("The request failed:", error);
  }
}
Enter fullscreen mode Exit fullscreen mode

Separating AbortError makes it easier to log timeouts, display an appropriate message, and decide whether another attempt is safe.

Don’t retry blindly

A timeout and a retry solve different problems:

  • A timeout prevents your application from waiting indefinitely.
  • A retry creates a new request.

Automatically retrying an aborted request can duplicate work or produce unintended side effects. Before retrying, consider:

  • Is the operation safe to repeat?
  • Did the provider begin processing the original request?
  • Could the request create or modify data?
  • Is an idempotency key available?
  • How many attempts have already been made?
  • Should the retry use exponential backoff and jitter?

Retries should have a limit. They should also respect provider headers such as Retry-After when available.

Choose the timeout deliberately

There is no universal timeout value for every AI workload.

A short classification request may need a much lower limit than a long reasoning or generation task. Streaming responses may also need separate connection and inactivity timeouts.

Measure real production latency and choose limits based

Top comments (0)