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

NoLAstNamE's avatar

Timed out command

I'm running a command on one of my websites

php artisan command:here

after a few minutes I get this status "Timed Out", is there any way to increase something to prevent the time out?

subscriptions table has 40,000 records and incomes table has 8,000,000. Every subscription has a maximum of 200 records in the incomes table.

Subscription.php

public function income()
{
    return $this->hasMany(Income::class);
}

Income.php

public function subscription()
{
    return $this->belongsTo(Subscription::class);
}

Code of the command I want to run

foreach (Subscription::where('status', 'ACTIVE')->lazy() as $subscription) {
    $count_earnings = $subscription->income()->count();
    $recent_bonus = $subscription->income()->latest('id')->first();

    if ($recent_bonus) {
        if ($count_earnings < 200) {
            $hour_difference = now()->diffInHours($recent_bonus->created_at);

            if ($hour_difference > 1) {
                $to_insert = 200 - $count_earnings;
                $max = $hour_difference;

                if ($hour_difference > $to_insert) {
                    $max = $to_insert;
                }

                for ($i = 0; $i < $max; $i++) {
                    $income = new Income;
                    $income->user_id = $subscription->user_id;
                    $income->subscription_id = $subscription->id;
                    $income->amount = (100 * 0.002) * 100;
                    $income->save();
                }

                if (($count_earnings + $max) >= 200) {
                    $subscription->update(['status' => 'COMPLETED']);
                }

                Log::info('Fix for:'.$subscription->id.' | User:'.$subscription->user_id.' | Total:'.$max);
            }
        } else {
            $subscription->update(['status' => 'COMPLETED']);
        }
    }
}
0 likes
20 replies
Nakov's avatar

At the top of your script add this:

ini_set('max_execution_time', 0);
1 like
NoLAstNamE's avatar

@Nakov In my command file right?

<?php
ini_set('max_execution_time', 0);

namespace App\Console\Commands;
NoLAstNamE's avatar

I had to put it under the namespace as I got this error Namespace declaration statement has to be the very first statement or after any declare call in the script

Nakov's avatar

@benjamin1509 you should put it at the start of your script:

So if you have a command

public function handle()
{
	ini_set('max_execution_time', 0);
....
1 like
NoLAstNamE's avatar

@Nakov still, no luck, I'm lacking of knowledge in forge I think there's something I need to change there.

NoLAstNamE's avatar

@Nakov Thanks for giving me the link, I also tried this one setting the max execution time to 3600, it's weird it runs for about 5 minutes and then Timed out again.

Nakov's avatar

@benjamin1509 well that means that it takes more than 5 minutes to run. You might want to reconsider your script because it is obviously stuck. Have you tried it locally, does it work? It might be going into an infinite loop for some reason. But as for your initial question that's the only answer.

1 like
NoLAstNamE's avatar

@Nakov I've run this before when it has few records like 10,000 subscriptions records, but now that it has 40,000 records this is happening.

NoLAstNamE's avatar

@Nakov what can you recommend using? currently, I'm using ->lazy() as seen in the code above.

Nakov's avatar
Nakov
Best Answer
Level 73

@benjamin1509 Here are couple of improvements, because 40.000 are not a lot of records:

in Subscription.php add this:

public function latestIncome()
{
    return $this->hasOne(Income::class)->latestOfMany();
}

then in your script:

// replace this
foreach (Subscription::where('status', 'ACTIVE')->lazy() as $subscription) {
    $count_earnings = $subscription->income()->count();
    $recent_bonus = $subscription->income()->latest('id')->first();

// with:
foreach (Subscription::with('latestIncome')->withCount('income')->where('status', 'ACTIVE')->lazy() as $subscription) {
    $count_earnings = $subscription->income_count;
    $recent_bonus = $subscription->latestIncome;

Obviously test it locally first.

1 like
Nakov's avatar

@benjamin1509 Forgot to say that you should be using one of the latest 8.* versions of laravel for the latestOfMany methods to work.

1 like
NoLAstNamE's avatar

@Nakov I'm still getting the status of Timed Out but will mark this as the Best answer anyway, I contacted the forge support and ask why I'm getting that maybe they can help me on some configs (not sure).

Nakov's avatar

@benjamin1509 You need to work on optimising your script, so you can seed data locally and make it 50.000 and work on improving the queries and everything that you do within the code, it is not a forge problem what you are facing.

1 like
NoLAstNamE's avatar

@Nakov Thank you for the advice, I really don't know at the moment what to optimize in my code in that command I am running, I've implemented your suggestions, the rest of the code is comparing the date, performing subtractions, and updating when a certain count is reached.

NoLAstNamE's avatar

@Nakov I got a reply from James Brooks saying.. "The Commands panel has a time out of 2 minutes for commands to run in. It's not designed for long-running commands. You should SSH into the server and run this command manually.".. I didn't know about this, I haven't read anything, told them it would be great to have a note on that in the Commands panel.

Please or to participate in this conversation.