How can I check the status of a queue in Laravel?
Stefan Bogdanescu
Founder & Senior Architect · 2026-06-29
# How Can I Check the Status of a Queue in Laravel? A Deep Dive
Dealing with asynchronous jobs is one of the cornerstones of modern application development, and Laravelâs queue system makes managing background tasks incredibly powerful. When you submit jobsâlike processing large CSV filesâyou need a way to communicate the current state back to the user: are the jobs still running, or are they complete?
The core challenge here is that the queue itself is an external, decoupled process managed by workers, not a simple object with a `.is_complete()` method. Therefore, checking the status requires querying the persistence layer where Laravel stores its queue data, which often means interacting directly with the underlying queue driver.
This post will walk you through the most practical methods for determining if your Laravel queue has finished processing, focusing on the common database driver scenario.
---
## Understanding Queue Status in Laravel
Laravel queues rely on a specific storage mechanism (like the database, Redis, or SQS) to hold the jobs waiting to be processed. When you dispatch a job using `dispatch()`, an entry is created in this storage. The worker process then moves these entries from the "waiting" state to the "processing" and finally to the "failed" or "completed" states.
There is no single global method available on the queue facade that tells you, "Are all jobs done?" Instead, we must inspect the data stored by the driver.
## Method 1: Checking Job Count (The Simplest Approach)
For many simple scenarios, checking the count of pending jobs might suffice. If the count is zero, it strongly implies completion. However, this method is insufficient if you need to distinguish between "no jobs currently waiting" and "all queued jobs have finished processing."
```php
use Illuminate\Support\Facades\Queue;
class JobStatusController extends Controller
{
public function checkStatus()
{
// Check how many jobs are currently in the queue (pending or processing)
$pendingJobs = Queue::attempts(); // Note: This is often more useful for tracking attempts, but checking the actual storage count is better.
// For database drivers, you would typically query the jobs table directly.
// Example conceptual check:
// $totalQueued = DB::table('jobs')->count();
// $processedCount = DB::table('jobs')->where('status', 'completed')->count();
if ($totalQueued === $processedCount) {
return response()->json(['status' => 'completed']);
}
return response()->json(['status' => 'processing']);
}
}
```
While checking the count is easy, it doesn't solve the problem robustly across all queue types or complex workflows.
## Method 2: Direct Querying via the Database Driver (The Reliable Approach)
Since you are using the database queue driver, the most reliable way to get an accurate status is to query the actual `jobs` table that Laravel uses for persistence. This technique works regardless of whether you are using the database, Redis, or another supported driver, as long as you know the structure of the storage mechanism.
For your specific requirementâdisplaying results only when processing is doneâyou need to track jobs by their status column (e.g., `status` or tracking job attempts).
Here is how you would structure a controller method to query the database for completion status:
```php
use Illuminate\Support\Facades\DB;
class FileQueueController extends Controller
{
public function getProcessingStatus()
{
// Query the jobs table stored by the database queue driver
$jobs = DB::table('jobs')
->where('queue', 'your_specific_queue_name') // Filter for your specific queue
->select('id', 'status')
->get();
if ($jobs->isEmpty()) {
return response()->json(['status' => 'completed', 'message' => 'All jobs have finished processing.']);
}
// If the set is not empty, check if any are still pending or running
$activeJobs = $jobs->where('status', 'pending')
->orWhere('status', 'processing')
->count();
if ($activeJobs === 0) {
return response()->json(['status' => 'completed', 'message' => 'All jobs have finished processing.']);
}
// If active jobs exist, the queue is still running
return response()->json(['status' => 'processing', 'count' => $activeJobs]);
}
}
```
### Best Practice: State Management Over Polling
While polling (repeatedly hitting this endpoint) works, it can be inefficient. A better architectural pattern involves using **state management**. Once a job is dispatched, store the unique ID of that job in a separate tracking table in your database. The worker updates this tracking table upon completion.
1. **Dispatch:** Store Job ID $X$ with status `pending` in a `user_queue_tracking` table.
2. **Worker:** When the job finishes, the worker updates the corresponding record for Job ID $X$ to `completed`.
3. **Controller:** The controller simply queries this small tracking table: "Are there any records with status `pending`?"
This approach removes the need to constantly inspect potentially massive queue tables and provides a highly optimized, direct answer for your UI. Remember that understanding how Laravel manages its data storage is key to building scalable applications, as detailed in documentation like [laravelcompany.com](https://laravelcompany.com).
## Conclusion
Checking the status of a Laravel queue boils down to inspecting the persistence layer used by the chosen driver. For database queues, direct SQL queries against the `jobs` table are the most direct way to assess job completion. However, for optimal performance and cleaner architecture, consider implementing explicit state tracking in your own database tables rather than relying solely on polling the queue system itself. This ensures your application remains responsive while accurately reflecting the asynchronous work being performed in the background.