#Laravel

The page can wait a second. The customer should not have to.

Zulu Shack illustration for “The page can wait a second. The customer should not have to.”: open door and waiting boxes

If a page needs to update a nonessential count, we probably don’t need to hold the customer at the door until the arithmetic finishes.

That doesn’t mean every job can be moved out of sight and considered solved.

Laravel 11.23’s September 2024 updates include deferred functions, concurrency features and Cache::flexible.1 They offer useful ways to change when work happens or how fresh a response needs to be. Each still needs a clear agreement about correctness and recovery.

The choice is less do it later and more which kind of later can this task safely tolerate?

Defer the work that can safely follow the response

A deferred function can run after the HTTP response is sent. That can suit a small task that doesn’t need to delay the person’s next step.

It is different from designing durable background processing around a queue and its workers. Moving an operation after the response doesn’t automatically give it the persistence, retry and operating behavior a critical workflow requires.

For a fictional account page, refreshing a secondary usage summary may be a candidate. Committing an order or promising that a payment has completed needs a more careful design.

The customer’s screen should describe what the application has actually established. A quicker page isn’t permission to move the truth into a more convenient part of the request lifecycle.

Serve a recent result when recent is good enough

Cache::flexible supports a stale-while-revalidate approach. Within configured periods, the application can serve a cached value while arranging its refresh, rather than making every visitor wait for recalculation.

Choose the acceptable age by consequence

A general activity summary may tolerate some delay. A final capacity check before booking may not.

Define the freshness requirement for the actual use, including account and permission boundaries. A cached number can be useful context while the action itself still checks authoritative state.

Connecting systems that were never introduced? See our integrations and AI work.

The official cache documentation distinguishes fresh, stale and expired periods. After the allowed stale period ends, recalculation may still make a request wait. The feature isn’t a promise that nobody ever experiences refresh work.

That is a useful limitation to understand before a proposal describes the entire site as instant.

Make an old result look appropriately old

If the age affects a decision, provide useful context rather than styling every value as current.

A last-updated time can help on a report. A clear pending state can help during preparation. The exact interface depends on what the person needs to do.

Don’t make the user infer the data’s freshness from how enthusiastically the loading animation moves. A spinner can convey activity; it cannot negotiate the business’s tolerance for stale information.

Use a queue when the job needs an operating life

Longer or consequential work may belong in an explicitly tracked background process. Define what happens when a worker stops, a provider is unavailable or a task is attempted again.

Derek Comartin’s workflow work is relevant to coordinating those states across boundaries.2 Laravel Pulse can help reveal slow jobs and application activity, but a dashboard doesn’t decide who should respond to an unresolved task.

Worth reading next: Your Laravel app needs a dashboard before it needs more horsepower.

Parallel work still needs independent responsibilities

Concurrency can reduce waiting when suitable tasks are independent. It doesn’t eliminate shared-data races or turn several external actions into one transaction.

Check which tasks can overlap and which depend on another result. If two operations compete for the same resource, that problem needs its own protection.

The feature should serve the workflow, rather than the workflow being rearranged to demonstrate the feature.

Use it forWatch for
Deferred functionA small task that runs after the response and needn’t delay the next step, like refreshing a secondary usage summaryIt doesn’t give the work persistence, retries or an operating life
Recent cached resultA value that can be a little old, like a general activity summary (Cache::flexible)Final checks, such as capacity before a booking, still need authoritative data
Queued background jobLonger or consequential work that needs tracking until it’s doneDecide what happens when a worker stops or a provider is unavailable
Which kind of “later” can the task tolerate?

For a first improvement, identify one visible delay and classify the work behind it. Can it follow the response, use an acceptably recent result or run as a durable task with a clear status?

Then test the failure path and compare the actual customer journey. If the page responds sooner but staff have lost track of unfinished work, the delay has mainly changed address.

I like faster interfaces. I like them even more when the application remains honest about what it has done.

Let the customer move on when it is safe to do so. Give the work left behind a plan for finishing.

Turn reading into results

Like what you’re reading? Let’s put it to work on your brand.