Skip to content
man glossary/request-timeout

glossary define request-timeout

Name

Request Timeout

The longest a client waits for a connection or a response before abandoning an API call, so a hung request fails fast instead of blocking.

Synopsis

Connect timeout, Read timeout, Client timeout, Request deadline

Section

Reliability & scale

Level

practitioner

▍

Reviewed

Drag the clock: when should this send give up?

13 / 13

Time since it opened

12s

ClosedDeadline spent: stop, report and fall back to SMS
Attempt 1 sent
Connect cap (2 s)
Read timeout (5 s)
Attempt 2, same ID
0s2.5s5s7.5s10sWindow closes
A ten-second deadline for a login OTP. Drag time past the connect cap and the first read timeout (outcome unknown), through a two-second status check and a retry with the same ID, to the point where the client must stop and fall back.

12s in: window closed. Deadline spent: stop, report and fall back to SMS.

Description

What is a request timeout?

A request timeout is the maximum time a client is willing to wait on an outbound call before giving up. You set it on your side of the connection, and it exists because networks fail in a particularly unhelpful way: instead of returning an error, a connection can simply hang. Without a timeout, the thread, the worker slot or the customer's login screen waits with it.

In practice there are several distinct limits. The connect timeout bounds DNS lookup, the TCP connection and the TLS handshake. The read (or socket) timeout bounds how long the client waits for bytes once the request is sent — usually per read, so a slow trickle of data can keep it alive. An overall deadline caps the whole operation, retries included. Servers and proxies keep their own clocks too, and two HTTP status codes report them: 408 means the server gave up waiting for your request, and 504 Gateway Timeout means a proxy gave up waiting for the server behind it.

In a WhatsApp integration, timeouts belong on every call that leaves your process: sends to the /{PHONE_NUMBER_ID}/messages endpoint, media downloads, template management calls and your own outbound calls to CRMs. The subtle part is what a timeout does not tell you. When a send times out you only know that you stopped waiting — the Cloud API may already have accepted the message and returned a wamid you never received, so a blind retry can deliver the same message twice.

Key takeaways

  • A request timeout is the client-side limit on how long one API call may wait before it is abandoned and handled as a failure.
  • Set separate connect and read timeouts, plus an overall deadline that every retry must fit inside.
  • Python's requests library has no timeout by default and many clients wait minutes, so always set one explicitly.
  • A timed-out send may still have been accepted and delivered: check before resending instead of retrying blindly.
  • A timeout is the limit you choose; p99 latency is how long calls actually take. Size the first from the second.

Why it matters

Why does a request timeout matter?

Timeouts decide how your system fails. Without them, one slow dependency quietly ties up every worker until the whole service stalls: the queue backs up, webhooks stop being acknowledged and Meta starts retrying them. With limits that are too tight, healthy calls are cut off and retried, adding load at the worst moment. Well-chosen timeouts, sized from measured latency and fitted inside a deadline, turn a hung connection into a fast, handled error that your retry policy and circuit breaker can act on.

Mechanics

How does a request timeout work?

  1. step 1 — Measure before you choose

    Look at the real latency distribution of each dependency. A common starting point is a read timeout a few times the observed p99, so ordinary slow calls finish and only genuinely stuck ones are cut off.

  2. step 2 — Set connect and read limits separately

    Connecting should take well under a second on a healthy network, so connect timeouts of one to three seconds are typical. The read timeout covers the server's processing time and is usually longer.

  3. step 3 — Give the operation a deadline

    Decide how long the whole job may take — a login OTP, say ten seconds — and pass the remaining budget down to each attempt, so retries can never push the operation past it.

  4. step 4 — Treat a timed-out send as unknown, not failed

    Tag every send with your own ID in biz_opaque_callback_data. Meta does not deduplicate on it, but it echoes the value in status webhooks, so before resending after a timeout you can check whether a status for that ID has already arrived.

  5. step 5 — Retry only inside the budget

    If time remains, retry with exponential backoff. If not, stop, record the failure and fall back — for an OTP, offer SMS or a 'resend code' button instead of leaving the user on a spinner.

Usage

A request timeout in code

const DEADLINE_MS = 10_000;
export async function sendWithDeadline(payload, attemptId) {
const started = Date.now();
for (let attempt = 1; attempt <= 3; attempt++) {
const remaining = DEADLINE_MS - (Date.now() - started);
if (remaining < 1_000) break; // not enough budget left
try {
const res = await fetch(
"https://graph.facebook.com/v26.0/{PHONE_NUMBER_ID}/messages",
{
method: "POST",
headers: {
Authorization: "Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
},
body: JSON.stringify({ ...payload, biz_opaque_callback_data: attemptId }),
signal: AbortSignal.timeout(Math.min(5_000, remaining)), // per-attempt cap
},
);
return await res.json();
} catch (err) {
if (err.name !== "TimeoutError") throw err;
// Outcome unknown: the API may have accepted the message.
if (await statusSeen(attemptId, 2_000)) return { alreadySent: true };
}
}
throw new Error("deadline exceeded: fall back or report");
}

Each attempt's timeout is cut from what is left of the deadline, and a timeout triggers a status check before any resend.

Properties

A request timeout: key facts and limits

Python requests default
No timeout unless timeout= is set
Node.js per-call limit
AbortSignal.timeout(ms), raises TimeoutError
Typical connect timeout
1–3 seconds
Server-side timeout statuses
408 Request Timeout, 504 Gateway Timeout
Media download URLs
Expire 5 minutes after they are issued
Correlating unknown outcomes
biz_opaque_callback_data, echoed in status webhooks

Example

Example: An OTP that timed out but still arrived

A Hyderabad fintech app gives login OTPs a ten-second budget. One evening a network path degrades: the first send connects, but no response comes back within the five-second read timeout. The client marks the attempt as unknown rather than failed. A second later, while the client is still checking, a sent status webhook arrives carrying the attempt's ID in biz_opaque_callback_data, so the app shows 'Code sent' and does not fire a second OTP. On the rare night when no status arrives inside the budget, the app offers an SMS code instead of quietly resending the same WhatsApp message.

Caveats

Common mistakes with a request timeout

  • Relying on library defaults

    Many HTTP clients wait indefinitely or for several minutes. One hung call per worker is enough to stall a queue, so set connect and read timeouts explicitly on every client you create.

  • Treating a timeout as a failed send

    The request may have reached the Cloud API and been accepted. Resending without checking can deliver a duplicate OTP or order update; correlate with your own ID first.

  • Inner timeouts longer than outer ones

    If your webhook handler waits on a slow CRM call before returning 200, Meta may count the delivery as failed and retry it while the first handler is still running. Acknowledge first, and keep every inner timeout shorter than the one wrapping it.

  • Retries that ignore the budget

    Three attempts with a ten-second timeout each can keep a user waiting thirty seconds or more. Compute each attempt's timeout from the time left in the overall deadline.

  • Never revisiting the numbers

    Latency shifts as traffic, regions and payload sizes change. Review timeouts against current p99 latency and alert on the timeout rate itself.

Questions

Request Timeout FAQs

What is a good timeout for the WhatsApp Cloud API?
There is no official number, so base it on your own measured latency. Many teams start with a connect timeout of about two seconds and a read timeout a few times their observed p99, then tune it from the timeout rate.
What is the difference between a connect timeout and a read timeout?
A connect timeout limits how long establishing the connection may take; a read timeout limits how long the client waits for response data after sending. They fail for different reasons, so set them separately.
If a send times out, was the WhatsApp message delivered?
Possibly. A timeout only means your client stopped waiting; the API may have accepted the message. Look for a status webhook carrying your biz_opaque_callback_data before deciding to resend.
What is the difference between HTTP 408 and 504?
408 means the server stopped waiting for the client to finish sending its request; 504 means a proxy or gateway gave up waiting for the server behind it. Your own client-side timeout raises a local error with no HTTP status at all.

Notes

Best practices for a request timeout

  • Log timeouts as their own outcome, separate from HTTP errors, so a rising rate is visible at a glance.
  • In media retrieval, download the file as soon as you fetch its URL: the URL expires after five minutes, so a slow queue turns into failed downloads.
  • Put a deadline on the whole user action and propagate it, rather than tuning each call in isolation.
  • Pair timeouts with a circuit breaker so repeated timeouts stop new calls instead of piling more onto a sick dependency.

See InfiQ pricing

Put Request Timeout to work

InfiQ is an official Meta Business Partner. Start a 7-day free trial — no card needed — and see this running on your own number.