spatie/laravel-long-running-tasks
Monitor externally executed long-running tasks in Laravel by polling instead of webhooks. Extend LongRunningTask, implement check() returning TaskResult::ContinueChecking or StopChecking, and start with MyTask::make()->meta($data)->start(). Checks run on a configurable interval until the task...
sleep() loops or bespoke cron jobs.long_running_task_log_items table with pending / running / completed / failed / didNotComplete is a ready-made backing store for status badges, "we'll email you when your export is ready" flows, and support-tooling lookups. That makes "show progress on long jobs" a cheap roadmap item instead of a design debate.keep_checking_for_in_seconds (default 5 min) is a product-set abandonment policy: after this, the task is marked didNotComplete rather than hanging forever. That's a decision about when to tell a user "this failed, try again" versus leaving them waiting — worth an explicit answer per task type.onFail() returning ContinueChecking vs. nothing lets you decide, per task class, whether a transient provider error is retried silently or surfaced as a hard failure. This is the difference between "we retried and it worked" and "the user saw an error for something that self-healed."check() body. Useful when triaging a backlog of third-party integrations for sequencing.Adopt when:
Look elsewhere when:
For executives (30 seconds): Several of our integrations work by starting a job on a vendor's side and then repeatedly asking "is it done?" Today each of those is bespoke engineering. This MIT-licensed, free package gives us that pattern once, with a status table we can show users and support, configurable retry timing so we don't over-pay for API calls, and automatic timeouts so nothing hangs forever. It converts a repeated multi-week build into a repeated one-day build. The tradeoff is maturity: it's a small, young open-source package, so we'd pin the version, wrap it in our own thin layer, and keep it off the highest-risk paths until it earns trust.
For engineering leads: Low-ceremony dependency from a well-known Laravel vendor. Three files of substance to understand: the LongRunningTask base class with check(), the LongRunningTaskLogItem model, and RunLongRunningTaskJob. Both the model and the job are designed to be subclassed and swapped via config, so we own the schema extensions and the queue behavior. Requires an existing queue setup. Recommended adoption shape: publish config and migrations, create App\Models\LongRunningTaskLogItem, keep task classes in one namespaced directory behind our own marker interface, pin to the current minor and review on upgrade. Cost is essentially zero; the risk we're accepting is maintenance risk, which the wrapper contains.
For the operating/SRE conversation: Watch the check frequency against vendor rate limits, and pick a backoff strategy explicitly rather than accepting the 10-second default. Set keep_checking_for_in_seconds per task type to match what we're willing to tell a user "this is still working." Budget queue capacity for the re-check jobs, and alert on didNotComplete and failed counts — those are the two states that generate support tickets.
How can I help you explore Laravel packages today?