 <p>You should move the time logic into your database query - there's no point in fetching ALL rows, only to throw away some (most? all?) of the rows if there's nothing to do:</p> <pre><code>SELECT * FROM users WHERE `time` &lt; (now() - INTERVAL 3 DAY) </code></pre> <p>Once that's done, I'd suggest moving the actual mail() portion out of the database fetching loop, so that you can batch together each user's brochures first:</p> <pre><code>$users = array(); while($row = mysql_fetch_array($time_query_result)) { if (!array_key_exists($row['userID'], $users)) { $users[$row['userID']] = array('email' =&gt; $row['email'], 'brochures' =&gt; array()); $users[$row['userID']]['brochures'] = array('b' =&gt; $row['brochures'], 't' =&gt; $row['time']); } } </code></pre> <p>You'd then loop over this $users array to build emails for the users:</p> <pre><code>foreach ($users as $user) { $text = '&lt;html&gt;&lt;body&gt;&lt;p&gt;Brochure reminder&lt;/p&gt;'; $i = 1; foreach ($user['brochures'] as $brochure) { $text .= 'Brochures:&lt;br /&gt;'.$i++ .$row['b']. $row['b']; } $text .= '&lt;/body&gt;&lt;/html&gt;'; mail($user['email'], $subject, $text, $headers); } </code></pre> <p>This way, you fetch all the user details in one go. You then build a SINGLE email to each user, listing all of their brochures, and (hopefully) problem solved.</p>