Recently I've decided to use Mandrill to send emails. I will need to send around 30 000 emails at once, and I thought batch sending with Mandrill could take care of that, however when I check API logs at Mandrill's site, every sent email is shown as a seperate API call (around 200ms call time). The result status for every sent email is equal to 'sent'.
From what I could gather when there's more than 10 recipients it should work asynchronously and the status should be 'queued'.
I'm sending around 600 emails right now and CRON script takes around 7 mins to execute. That's way too long.
Here's the code:
public function getSendEmails()
{
\Log::info('get-send-emails (start)');
$tasks = $this->task->where('published_at', '>', date('Y-m-d', time()))->whereNotNull('published_at')->get();
foreach ($tasks as $task)
{
$users = $this->user->where('task_id', $task->id)
->where('allow_emails', 1)
->where('activated', 1)
->get();
$users_array = array();
foreach ($users as $user)
{
$users_array[] = array(
'email' => $user->email,
'name' => $user->first_name . ' ' . $user->last_name,
'type' => 'to'
);
}
if (!empty($users_array))
{
$html = View::make('emails.notifications.task')->with('task', $task)->render();
$batches = array_chunk($users_array, ceil($users->count()/1000.0));
foreach($batches as $batch)
{
try
{
$mandrill = new \Mandrill('some API key');
$message = array(
'html' => $html,
'subject' => 'Some Subject!',
'from_email' => 'some@email.com',
'from_name' => 'Some Name',
'to' => $batch,
'preserve_recipients' => false
);
$async = true;
$result = $mandrill->messages->send($message, $async);
}
catch(\Mandrill_Error $e)
{
echo 'A mandrill error occurred: ' . get_class($e) . ' - ' . $e->getMessage();
throw $e;
}
}
}
}
\Log::info('get-send-emails (end)');
}
Could u tell me if I'm doing something wrong or is this how long it's supposed to take?
It looks like you're breaking the array in to chunks of very few recipients. Assuming that you have 10 users (so $users->count()
is 10), you're setting the batch sizes to 1 with this line since ceil(10/1000.0)
will return 1:
$batches = array_chunk($users_array, ceil($users->count()/1000.0));
Even with 30K recipients, you'd be setting each batch to be 30 recipients (so still relatively small batches). You probably want to change that to something like this to make each of the batches 1000 recipients:
$batches = array_chunk($users_array, 1000);