Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

bvfi-dev's avatar

Laravel 11 Send mail at specific time

Maybe Ive been doing it for too long without any break, but Im banging my head as to how I can make a scheduled email to be sent in Laravel 11. I have this:

if($document->wasRecentlyCreated) {
    DocumentReviewJob::dispatch($document)->delay($document->review_at); //Example of what I want

And I want if this passes, an email to be sent at a timestamp called $document->review_at. I created a DocumentReviewJob with a $document constructor:

public function handle(): void
	{
        $user = User::find($this->document->author);
        Mail::to($user->email)->send(new DocumentReviewReminderMail($this->document));
        $this->document->update(['state' => 38]);
        //Then also set a new "review_at" and create a new job that will execute at the new "review_at" time
	}

But, then I need to use ->delay and that is usually short term. But then I figured, what If this mail needs to be sent in 5 years, would this even work? Answer in most cases is "no". Like, for example, the Amazon SQS queue service has a maximum delay time of 15 minutes. What Im really asking is quite simple. I want when the $document->review_at time is reached, to send out a Mail and do some DB fidgeting. Then when that is executed, I need it to set a new $document->review_at and send another job at that new review_at time. So, kind of like a cycle/Period (I will do calculations myself, it depends on a review_cycle entry in the DB). What is the right way of doing this in Laravel 11, since there's been so much change on Queues between Laravel 10 and 11? I did also take a look at Schedules, but it was not what I needed. I come from a cakePHP environment and over there, we'd make commands and schedule CRONs, but here, its all different and works differently, or at least it seems to me.

0 likes
4 replies
aleahy's avatar

You could create a job that is scheduled to run every minute which checks the value of any $document->review_at in the database and if it has passed then it sends the email. You obviously need some sort of flag to make sure you don't send the same email again.

I'm sure there are other ways, but that is how I would approach it.

1 like
bvfi-dev's avatar

@aleahy I wanted to avoid that, I dont want every minute checks, its a dealbreaker.

aleahy's avatar

@bvfi-dev It doesn't have to be every minute - you could do it once a day or once a week if you wanted to. The scheduler will be running every minute and checking to see if there is a job to run, and runs your job at the frequency of your choosing.

1 like
Snapey's avatar
Snapey
Best Answer
Level 122

@bvfi-dev Then you are out of luck. Putting a job on the queue and hping it will still be there in even a few days is unrealistic. You should use a scheduled job. It does not need to run every minute but it needs to run on a frequency which is appropriate for your business requirements.

1 like

Please or to participate in this conversation.