NoLAstNamE's avatar

Sending a lot of SMS

How do you guys approach this kind of task? I have 10K users and I need to send them all SMS notifications.

I'm thinking of making a custom artisan command and chunk them by 500, then dispatch a job that will send SMS for each of them. But I don't know if this is performant. Has anyone here done the same thing?

My SMS provider doesn't support bulk sending so I need to send one-by-one.

I'm using database as the queue driver.

1 like
3 replies
LaryAI's avatar

To efficiently send SMS notifications to 10,000 users when your provider only supports one-by-one sending, your approach is on the right track. Here’s a recommended solution using Laravel queues and chunking:

1. Create an Artisan Command

This command will chunk your users and dispatch jobs for each chunk.

// app/Console/Commands/SendBulkSms.php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use App\Models\User;
use App\Jobs\SendSmsJob;

class SendBulkSms extends Command
{
    protected $signature = 'sms:send-bulk';
    protected $description = 'Send SMS to all users in chunks';

    public function handle()
    {
        User::chunk(500, function ($users) {
            foreach ($users as $user) {
                SendSmsJob::dispatch($user);
            }
        });

        $this->info('All SMS jobs dispatched!');
    }
}

2. Create the Job

This job will handle sending the SMS to a single user.

// app/Jobs/SendSmsJob.php

namespace App\Jobs;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use App\Models\User;

class SendSmsJob implements ShouldQueue
{
    use InteractsWithQueue, Queueable, SerializesModels;

    protected $user;

    public function __construct(User $user)
    {
        $this->user = $user;
    }

    public function handle()
    {
        // Replace this with your SMS sending logic
        // Example: SmsService::send($this->user->phone, 'Your message here');
    }
}

3. Queue Configuration

Since you’re using the database queue driver, make sure you have run:

php artisan queue:table
php artisan migrate

And that your queue worker is running:

php artisan queue:work

4. Performance Tips

  • Chunking: Chunking by 500 is good to avoid loading all users into memory.
  • Queue Workers: Run multiple queue workers to process jobs in parallel. For example, you can run 5 workers to speed up processing:
    php artisan queue:work --daemon --queue=default --tries=3
    
    (Run this command in 5 separate terminal windows or use a process manager like Supervisor.)
  • Rate Limiting: If your SMS provider has rate limits, consider adding a delay in the job or using Laravel’s rate limiting features.

Summary

  • Chunk users to avoid memory issues.
  • Dispatch a job for each user to the queue.
  • Run multiple queue workers for concurrency.
  • Monitor your queue and SMS provider’s rate limits.

This approach is scalable and keeps your application responsive.

1 like
martinbean's avatar
Level 80

@nolastname I’d just use a service that does support mass marketing via SMS. Similar to how I would use something like Campaign Monitor if I wanted to send lots of marketing emails, instead of trying to do it myself.

1 like

Please or to participate in this conversation.