Get a Quote!

+1-(334) 899-1293

707 Midland Exd St Ashford, Alabama(AL), 36312

Edit Template

Setting Retry Behavior for Jobs That Fail on First Attempt

Not every scheduled job succeeds on the first attempt, and how a scheduling system handles that failure matters almost as much as how it handles success. An API call to an AI provider times out mid-generation, a WordPress REST endpoint returns a transient 502 because the host restarted PHP-FPM at the wrong moment, an image upload fails because a CDN hiccupped for four seconds — none of these are permanent failures, and blindly marking the job dead on the first hiccup wastes content that would have gone through fine a minute later. But retrying blindly has its own failure mode: retry the wrong kind of error and you risk publishing a post twice, or grinding through the same doomed API call five times before finally giving up and burning through rate limits in the process.

AutoSchedulePost’s approach sits between those two extremes — a small number of automatic attempts for the failures that are genuinely likely to be transient, and a hard stop into the Queue & Log’s failed status for anything that either exhausts its retries or looks like the kind of error retrying won’t fix. Understanding where that line sits, and where you have control over it, is the difference between a queue that quietly recovers from routine hiccups and one that either gives up too early or hammers a broken endpoint five times before telling you anything’s wrong.

Why Retry Behavior Isn't One-Size-Fits-All

The obvious approach — retry every failure a fixed number of times before giving up — sounds reasonable until you look at what actually causes jobs to fail. A timeout on an AI generation call and a 401 from an expired API key are both “failures,” but only one of them has any chance of succeeding if you just try again. Retrying an authentication error five times doesn’t fix the expired key, it just delays the moment you find out about it by however long the retry backoff takes, and burns five API calls doing nothing useful.

That’s the reasoning behind treating retry eligibility as a property of the error, not a blanket policy applied to every failure equally. Errors that look transient — timeouts, rate-limit responses, connection resets — get queued for another attempt. Errors that look structural — bad credentials, a malformed request, a site that’s returned the same 404 twice in a row — get routed straight to failed status instead, since retrying them just delays a fix that has to happen somewhere else anyway.

The Default Retry Count

Out of the box, a job that fails on a retry-eligible error gets up to two additional attempts beyond the first — three tries total — before it’s marked failed and handed off for a manual restart. That default is intentionally conservative rather than aggressive: enough attempts to smooth over the routine transient failures (a brief API timeout, a momentary REST hiccup) without turning a genuinely broken connection into a job that silently retries for the better part of an hour before anyone notices.

Each retry attempt still has to fit inside the same 300-second job timeout as the original attempt, and retries aren’t instantaneous — there’s a backoff delay between attempts rather than an immediate re-try, specifically so a rate-limited API call gets a real chance to recover rather than being hit again within the same second that produced the rate-limit response in the first place.

Sorting Errors Into Retryable and Non-Retryable

In practice, the errors that actually show up in a queue log over time cluster into a fairly predictable set on each side of the line. Worth knowing which is which before you’re staring at a failed item trying to guess whether a restart is likely to help:

  • Retryable: request timeouts, connection resets, 5xx server errors from either the AI provider or the target WordPress site, and explicit rate-limit responses.
  • Retryable: transient DNS resolution failures, which show up more often than you’d expect on shared hosting during off-hours maintenance windows.
  • Non-retryable: authentication failures (expired or revoked API keys, invalid application passwords), which won’t resolve themselves no matter how many times the same request fires.
  • Non-retryable: 4xx client errors other than rate limits — a malformed request or a target endpoint that’s been moved or removed — since the request itself is the problem, not the timing.
  • Non-retryable: content-policy rejections from an AI provider, where the same prompt will produce the same rejection on every attempt until the prompt itself changes.

That second category is exactly why the failed status exists as a real stopping point rather than an obstacle to route around automatically — some failures need a person to change something before any retry, automatic or manual, has a chance of succeeding.

Where You Have Control Over the Defaults

The default of two retries beyond the first attempt is tuned to work reasonably well across most sites without anyone touching it, but it isn’t the only reasonable setting for every situation. A site running against a particularly flaky third-party integration might reasonably want a third retry attempt to smooth over a provider with a habit of failing twice before succeeding on the third try. A site that would rather see a failure quickly and restart it manually with full attention, instead of waiting through two automatic attempts first, might prefer fewer retries and a faster hand-off to the failed queue.

The practical way to reason about where to set it is less about finding a universally correct number and more about weighing two costs against each other: too many retries delays the moment a genuine problem becomes visible, since each additional attempt with backoff adds real wall-clock time before the item ever reaches someone’s attention; too few retries means routine, self-resolving hiccups end up needing manual restarts more often than they should, adding busywork for something that would have cleared up on its own with one more try.

Backoff, and Why It's Not a Fixed Delay

The gap between retry attempts widens with each subsequent try rather than staying constant — a short pause before the second attempt, a longer one before the third. This matters most for rate-limit errors specifically, where retrying too quickly just produces another rate-limit response rather than giving whatever limit was hit time to reset. A fixed short delay would work fine for a one-off timeout but would be nearly useless against a rate limit that needs tens of seconds to clear, so the widening delay covers both cases reasonably well without needing to know in advance which kind of transient failure actually occurred.

What Happens When Retries Are Exhausted

Once a job has used up its retry attempts without succeeding, it lands in the Queue & Log with a failed status, the same terminal state a non-retryable error reaches immediately. From that point, nothing further happens automatically — no fourth silent attempt, no quiet re-queuing. The item sits there until a human looks at it and either restarts it manually or decides it’s not worth retrying and clears it from the queue instead.

That deliberate stop, rather than an indefinite retry loop, is a design choice worth understanding on its own terms: a job that’s failed three times in a row on the same underlying error is unlikely to succeed on a fourth automatic attempt with nothing about the situation having changed, and continuing to retry it automatically mostly just delays the moment someone notices there’s an actual problem to fix — an expired credential, a site that’s gone offline, a prompt that’s tripping a content filter every time.

Restarting a Failed Job Without Duplicating Content

The manual restart available from the failed status is built specifically to avoid the most common way retries go wrong on other platforms — publishing the same content twice because a retry fired after the original attempt had actually partially succeeded. A restart re-runs the job from its last confirmed state rather than blindly starting over from scratch, so a job that failed after content generation succeeded but before the WordPress publish call completed doesn’t regenerate the content a second time, it picks up from where it actually stopped.

This matters more than it might sound like it does, because AI generation calls aren’t free, and a naive “just try the whole thing again” restart would waste both the API cost and the time of a call that had already succeeded once.

Where Retry Behavior Doesn't Apply

The ASAP publishing path — Add to Queue → ASAP — happens synchronously within a single request rather than as a background job picked up by the scheduler tick, and it doesn’t go through the same retry machinery at all. If an ASAP publish fails, it fails immediately and visibly, in the same request that triggered it, rather than being queued for a background retry a minute later. That’s a deliberate difference in behavior, not an oversight: ASAP exists for the moment you need to know right now whether something published, and a silent background retry would undermine exactly the immediacy that path is for.

Scheduled and workflow-driven jobs are the ones that go through the full retry-then-failed lifecycle, since those were already going to be picked up by a background process rather than watched live by a person at the moment of publishing.

Reading Retry History in the Queue

A job that succeeded on its second or third attempt still shows as posted in the Queue & Log — the retry history isn’t hidden, but it also isn’t the headline status, since from a purely “did the post go out” perspective a job that recovered on attempt two looks identical to one that succeeded on attempt one. For sites where retry frequency itself is worth monitoring, a pattern of jobs consistently needing two or three attempts before succeeding, rather than occasional isolated retries, is usually a signal worth investigating on its own: it often points to a specific integration, a particular AI provider, a specific target site’s REST endpoint, that’s less reliable than the rest of the pipeline rather than to random bad luck.

Where to Go Next

Retry behavior is one piece of a larger reliability story that runs underneath every scheduled and workflow-driven post — the same every-minute tick, the same Queue & Log statuses, and the same failed-to-restart path apply whether a job failed on its first attempt or its third. For the complete picture of how scheduling and workflow automation fits together end to end, see our complete guide to scheduling and workflow automation.

Leave a Reply

Your email address will not be published. Required fields are marked *

Services Built for Expansion

Smart Bots Built for Real Impact

Lose away off why half led have near bed. At engage simple father of period others except. My giving do summer of though narrow marked at. Spring formal no county ye waited.
You have been successfully Subscribed! Ops! Something went wrong, please try again.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut elit tellus, luctus nec ullamcorper mattis, pulvinar dapibus leo.

Support

Powered by Joinchat