AL+

Language: RO (română) EN (English)

Email us: paul@alplustech.com

Looking back at the week of 14–20 January 2026

Rails retry delays should be able to use the error

Rails added error-aware wait functions on main in January 2026. Separate useful recovery signals from invalid hints, permanent errors and release assumptions.

Citiți articolul în română

An execution count tells a job how often it has failed. It does not tell the job when the remote service expects to recover. If an error carries a usable recovery signal, the retry delay should be able to consider it. Rails' January 2026 change made that policy expressible in the delay function, while leaving the application responsible for deciding whether the signal deserves trust.

The 16 January Rails update introduced error-aware retry_on wait procs. Pull request 56601, also readable in its public discussion and diff, merged into main on 14 January. That is development-branch evidence. It does not establish availability in an application's stable release, either that week or at the time you read this retrospective.

The function receives information, not a recovery decision

The merged implementation preserves the execution-count-only call when a proc has arity exactly one. Otherwise it calls the proc with the count and error. That exact distinction matters for strict lambdas and optional arguments. The newsletter's broader description of zero-argument compatibility should not be read as a promise that a strict zero-argument lambda accepts those calls. Check the actual callable and installed implementation before adopting it.

The example's retry_after is an application-defined error property. Rails is not automatically parsing an HTTP response header in that example. A client integration would need to interpret the response, validate its meaning and expose whatever information the application's delay policy expects. Merely giving a property the same name as a familiar header does not perform that work.

This creates a useful separation of responsibilities. The client can describe the failure in an error object. The job's policy can choose an appropriate delay. The job's main business operation need not acquire a separate scheduling branch for every upstream condition. That is a design benefit of making the error available; it is not evidence that every existing job should change its schedule.

Treat recovery hints as input to a bounded policy

A rate-limit response can carry a meaningful suggestion about waiting. A malformed value cannot be treated with the same confidence. Before using a hint, an application should decide what types and units it accepts, which range is reasonable and what happens when the value is absent. Those decisions should be visible in the integration contract.

The fallback deserves as much attention as the preferred path. If the hint is unusable, the application should still have a deliberate schedule rather than accidentally retrying immediately. A negative duration or an implausibly large wait can be a sign that parsing or assumptions are wrong. Silently converting every such value into a delay can hide the integration defect.

There is also a difference between a recovery estimate and permission to try again. A temporary limit may justify waiting. An invalid request may require a code or data correction. Receiving an error object gives the policy more information, but it cannot make a permanent failure transient. The decision to retry should precede the choice of delay.

A policy should also account for the time at which a hint was produced. A relative duration and an absolute future time are different inputs. If the error object passes one while the delay function assumes the other, a syntactically valid value can still produce the wrong schedule. Defining that boundary is application work, independent of the small Rails API change.

Better timing has limits under shared load

A job that obeys an upstream recovery signal can avoid some unnecessary attempts. That does not establish a system-wide reduction in load. Many jobs can receive the same signal and become runnable together. The team should consider whether its scheduling policy spreads subsequent work appropriately and whether aggregate demand remains within the upstream service's limits.

The important unit of observation is therefore larger than one successful retry. Useful evidence would distinguish why a delay was selected, whether a hint was accepted and what happened on the next attempt. Such observations can show whether a policy is helping or repeatedly postponing unresolved failures. They should avoid recording sensitive response contents merely to explain a scheduling decision.

Attempt limits and a stopping condition remain necessary parts of the design. A more informed delay does not justify an unlimited chain of attempts. There should be a defined response when the job cannot complete within the application's acceptable window. Otherwise respecting a recovery hint can become a way to hide a backlog rather than recover from it.

The consequences of repeating the business operation also remain separate. Timing alone cannot make a repeated external action harmless. Those safeguards belong in the operation's design, even though the topic here is the narrower question of how its next eligible execution time is chosen.

A fixed schedule may be the better policy

The strongest counterargument is simplicity. If a dependency offers no reliable recovery signal, a bounded generic schedule may be easier to reason about and operate. Error-aware code can add branches that rarely help while making incident diagnosis harder. The extra information is only useful when the application has a justified response to it.

That objection should influence adoption. Keep a simple policy when it fits the failure model. Introduce error-dependent timing for a specific signal with a defined contract, rather than because an additional callback parameter exists. The resulting behaviour should be explainable to someone investigating a delayed business task.

This January change also needs version discipline. A merged PR and a maintainer newsletter cannot replace checking the Rails version in the application and its relevant source. The merged interface establishes what the development change enabled. An adoption decision still needs evidence from the version the application will run.

For an integration in a custom software project, agree on the error contract alongside the expected recovery behaviour. Define what counts as a usable hint, how the fallback works and when attempts stop. Error-aware waiting earns its place when it changes a scheduling decision for a reason the team can verify.