Perplexity API 504 Gateway Timeout
A Perplexity request does not just generate — it goes and reads the live web first, so its latency is bounded by the slowest page it fetched, and that is what your deadline is really racing.
📡 Monitor your APIs — know when they go down before your users do
Better Stack checks uptime every 30 seconds with instant Slack, email & SMS alerts. Free tier available.
Affiliate link — we may earn a commission at no extra cost to you
Live Perplexity status right now
Settle this before anything else. A genuine Perplexity incident makes the timer analysis below irrelevant — you should be failing over, not reading proxy configs.
A 504 is a statement about a clock, not about a failure. Some intermediary decided in advance how long it was willing to wait, the answer did not arrive inside that window, and the intermediary wrote an error of its own. Nothing in the status code tells you that Perplexity failed. It tells you that a deadline expired, and deadlines are configuration — which means the fault is findable by reading a number rather than by guessing.
Whose clock is the whole question. It might be Perplexity's edge. It might just as easily be your ingress controller, a service-mesh sidecar, a corporate egress proxy, a platform request limit, or the timeout argument you passed to your own SDK three releases ago and have not looked at since. These produce an identical status code and entirely different remediation.
30-second triage: read the elapsed time, not the status code. If your 504s cluster on a round number — 30s, 60s, 120s — that number is somebody's configured constant and your job is to find whose. If the elapsed times are scattered, something variable is being waited on. Either way, checklive Perplexity statusfirst so you know whether any of this analysis is worth doing.
504 against the rest of the 5xx family
These five get filed together as “the API is broken” and then handed one retry policy, which guarantees the policy is wrong for at least three of them. The last column is the one that matters, because it is the only one that changes what you do next.
| Code | Who authored it | Correct response |
|---|---|---|
429 | Perplexity, deliberately, about your allowance | Slow down. Never fail over — you export your own pacing bug |
500 | The service, about an unhandled fault | Retry once or twice; a persistent 500 is a bug report |
502 | An intermediary, about an unusable reply | Identify the hop from the body, then one jittered retry |
503 | The service, about having no capacity | Retry with a budget, then fail over or degrade |
504 | An intermediary, about a deadline it set | Find the timer from elapsed time; retry only if idempotent |
502 and 504 are the two gateway-authored codes and they are routinely conflated. The difference is simple and it changes your diagnosis: a 502 means the gateway got an answer it could not use, so the evidence is in the response body; a 504 means it got nothing and stopped waiting, so the evidence is in the elapsed time. The unusable-reply case is covered in thePerplexity 502 guide, the capacity case in thePerplexity 503 guide, and throttling in thePerplexity 429 guide.
Find Out Whose Timer Expired
External checks run from outside your own network on a known deadline, so a timeout inside your infrastructure looks different from one at the provider edge — instead of identical, which is what your application logs show you.
Try Better Stack Free →Why Perplexity returns 504 specifically: you are timing a web crawl, not a generation
Every other provider on this list answers from weights. Perplexity answers from weights plus the live web: a request triggers a search, a fan-out of fetches against external sites, and only then a generation grounded in what came back. That architecture is the product, and it is also the entire explanation for its timeout behaviour, because the request's total latency is bounded below by the slowest external page it decided to read.
This inverts the usual relationship between load and failure. On a conventional inference API, timeouts correlate with request rate — more traffic, more queueing, more deadline expiry. On Perplexity, they correlate with prompt complexity. A broad, recent, multi-entity question triggers a wider fan-out than a narrow one, and a single slow or unresponsive source in that fan-out can hold the whole request open. Your quiet Sunday can produce more 504s than your busy Tuesday if the questions asked on Sunday were harder.
The consequence for deadline-setting is that a single timeout value applied to all requests is guaranteed to be wrong in both directions: too short for genuinely research-shaped queries and too long for lookups that should have returned in a second. If your product has both shapes, they need different deadlines, and the classification has to happen before the request rather than after it fails.
Sample rather than probe once, and record all three columns. One request cannot tell a total failure apart from the far more common partial one:
for i in $(seq 1 10); do
curl -s -o /dev/null -w "%{http_code} %{time_total}s %{content_type}\n" \
--max-time 90 \
https://api.perplexity.ai/chat/completions \
-H "Authorization: Bearer $PERPLEXITY_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model":"sonar-pro","messages":[{"role":"user","content":"ping"}],"max_tokens":1}'
doneThe status code says whether it failed, the elapsed time says which timer expired, and the content type says who wrote the error. Set --max-time deliberately higher than the deadline you are investigating, otherwise curl becomes the shortest timer in the path and you measure your own probe instead of the system.
The Perplexity warning sign: thin citations on a 200 precede the 504s
The most useful Perplexity-specific metric is not the error rate, it is the citation count on successful responses. When retrieval is degraded — sources timing out, fan-out returning less — the first thing that happens is not a failure. It is a 200 that came back suspiciously fast with two citations where it normally has eight. That response is materially worse for your users and your dashboards will score it as a success.
Record the number of citations on every response and alert on the distribution rather than on errors alone. A collapse in median citation count is the leading indicator; the 504s, when they arrive, are the lagging one. This is the single highest-value instrumentation choice specific to this provider, and almost nobody makes it.
When you do set deadlines, set them against the retrieval tail rather than the median. Measure your own p95 for research-shaped prompts and put the deadline above it, then handle expiry as a product state — a visible “still searching” affordance — rather than as an error. Retrying a research query that timed out will usually take just as long the second time, because the slow source is still slow.
The streaming case, where the 504 stops happening at all
Streaming is the most underrated fix for 504s, and it works for a reason that is easy to miss: most gateway timeouts are idle timeouts rather than total-duration limits. They fire when no bytes have moved for N seconds, not when the request has been open for N seconds. A streamed response puts bytes on the wire as soon as the first tokens exist, which resets the idle timer continuously and keeps a long generation alive under a deadline that would have killed the buffered equivalent.
- Check which kind of timeout you have. An idle timeout is defeated by streaming; a hard request-duration cap is not. They are configured separately and confusing them wastes a day.
- Assert on the terminal event. An iterator finishing is not the same as a stream completing. If the terminal marker never arrived, the response was truncated no matter what the status code said.
- Count partial responses as their own class. Not a success, not a 5xx. On a streamed path they are the metric that moves first, and a status-code-only dashboard stays flat through the entire incident.
- Decide the resume policy in advance. Re-issuing the whole prompt is the honest default and it bills twice; showing the partial output with a visible label is often the better product answer.
A retry policy that fits a 504 specifically
504 is the 5xx where the standard retry advice is most likely to hurt you, because the one thing a 504 does not tell you is whether the work happened. Four rules keep the retry from becoming its own incident:
- Assume the request may have succeeded. Your gateway stopped listening; the upstream did not necessarily stop working. Send an idempotency key for anything with a side effect, and expect a retried completion to be billable twice.
- Do not retry into the same deadline. If the timeout was too short for this request, a second identical attempt will expire identically. Change something — stream it, shrink it, or route it to a path with a longer deadline — or do not retry at all.
- Budget by ratio, not by count. Allow retries as a fraction of recent successes so the allowance collapses on its own when almost everything is failing, with no deploy required. See the Perplexity retry budget guide.
- Retry against a deadline, not a counter. If the user-facing request gave up eight seconds ago, attempt three is load on behalf of nobody. Propagate the deadline and skip attempts that cannot finish inside it.
If 504s persist past a couple of attempts they have stopped being transient, and the failover machinery should take over — which only works if it was kept warm. ThePerplexity failover guidecovers keeping a second path tested rather than merely configured, and thecircuit breaker guidecovers stopping the retries automatically.
Frequently Asked Questions
What does a 504 from the Perplexity API actually mean?
It means an intermediary between your process and the model set a deadline, that deadline expired before a usable response arrived, and the intermediary wrote its own error rather than waiting longer. Two things follow, and both are frequently missed. First, the 504 was authored by whichever hop was holding the timer — which may be Perplexity's edge, but may equally be your own load balancer, service mesh, egress proxy or SDK client. Second, a 504 says nothing about whether the upstream completed the work; it says only that the answer did not come back inside the window. That distinction is what makes the retry decision non-obvious.
How is a 504 different from a 502 on Perplexity?
They are siblings — both are written by intermediaries, neither is authored by the component that actually failed — but they describe opposite events. A 502 means the gateway received something it could not use: an empty body, a reset connection, a malformed reply. A 504 means the gateway received nothing at all and gave up waiting. The practical difference is what you measure next. For a 502 the diagnostic signal is the response body and its content type, because that identifies the author. For a 504 the diagnostic signal is elapsed time, because the elapsed time tells you which timer expired, and timers are configuration you can find and read.
Is a 504 the same as Perplexity being down?
Usually not, and the two call for opposite responses. A real outage is broad, sustained and consistent — every endpoint, every key, every request shape. A 504 is characteristically narrow: it hits the slow requests, the large requests, or the requests that traverse one particular hop, while everything else continues to work. Sample rather than infer from a single failure. Ten identical probes failing over several minutes is an incident and failover is correct; three of ten failing while the fast requests sail through is a deadline set too tight for part of your traffic, and failing over exports the problem rather than solving it.
Is it safe to retry a Perplexity 504?
Less safe than a 502, and the reason is worth understanding rather than memorising. A 504 means the answer did not arrive in time — it does not mean the upstream never did the work. The request may have completed a moment after your gateway stopped listening, which for a completion is a billing question and for anything with a side effect is a correctness one. Retry only what is idempotent, or propagate an idempotency key so the second attempt is provably the same operation rather than a second one. And retry against a deadline rather than a fixed count: if the user-facing request gave up already, attempt three is load on behalf of nobody.
Why do my Perplexity 504s show up as client-side timeout exceptions instead of status codes?
Because whichever timer is shortest wins, and it is often yours. If your SDK's client timeout is below the gateway's, your process abandons the request first and raises a local exception — the 504 that the gateway would eventually have written never reaches you, and your status-code dashboard stays clean through the whole incident. This is why the elapsed-time distribution matters more than the error taxonomy here. Log total elapsed time on every failure, timeouts included, and count local timeouts in the same bucket as 504s; otherwise you are measuring which timer fired rather than how often requests failed.
Why do my Perplexity timeouts not correlate with traffic volume?
Because the thing taking the time is not your request queueing behind other requests — it is a fan-out of fetches against live external websites. Latency is therefore a function of how hard the question is, not how many questions are being asked. A broad, recent, multi-entity prompt reads more sources than a narrow one, and one slow source holds the whole response open. This is why the usual triage runbook misfires here: scaling down concurrency does nothing, and the useful lever is classifying prompts by expected retrieval breadth and giving them different deadlines.
Is a fast Perplexity response with few citations a good sign?
It is usually the opposite, and it is the most valuable early warning this API gives you. Degraded retrieval shows up first as successful responses that returned quickly with a thin citation set — the fan-out came back short, the model grounded on less, and the answer is worse in a way that no status code reflects. Track median citations per response as a first-class metric. When it drops, you are watching retrieval degrade in real time, typically minutes before the timeouts start; an error-rate-only dashboard will show nothing until the damage is already user-visible.
Related Perplexity Guides
Know Whose Deadline Expired — Before Your Users Do
API Status Check watches Perplexity and the rest of your stack from outside your own network on a known deadline, so you find out whether the timer that fired was theirs or yours — in seconds, not after twenty minutes of reading a status page that was never going to mention it.
Start Your Free Trial →Alert Pro
14-day free trialStop checking — get alerted instantly
Alert Pro checks the 60+ APIs we monitor every hour and emails you within the hour of a detected change.
- Email alerts for up to 10 of the APIs we monitor
- $0 charged today — card required to start
- Cancel anytime — $9/mo after trial
🌐 Can't Access Perplexity?
If Perplexity is working for others but not for you, it might be an ISP or regional issue. A VPN can help bypass network-level blocks and routing problems.
Troubleshoot with a VPN
Connect from a different region to test if the issue is local to your network. Also protects your connection on public Wi-Fi.
Try NordVPN — 30-Day Money-Back GuaranteeSecure Your Perplexity Account
Service outages are a common time for phishing attacks. Use a password manager to keep unique, strong passwords for every account.
Try NordPass — Free Password Manager🛠 Tools We Use & Recommend
Tested across our own infrastructure monitoring 200+ APIs daily
SEO & Site Performance Monitoring
Used by 10M+ marketers
Track your site health, uptime, search rankings, and competitor movements from one dashboard.
“We use SEMrush to track how our API status pages rank and catch site health issues early.”