Skip to main content
Known Participant
June 24, 2011
Question

ColdFusion server crashes at 20k emails

  • June 24, 2011
  • 3 replies
  • 1645 views

Hello,

I'm looping through a 60K recordset and sending mail for each loop iteration. Right arount 20K emails sent, the memory consumed gets so high that the server slows, then crashes. The loop is never able to finish. I notice in Server Monitor that the memory usage slowly creeps up, then right when it hits 100%, it crashes. Hitting garbage collection does no good.

The loop that is running does a simple cfmail, then an insert into the database to log this process in order to follow the process and see how many mails went out. The code is located in a cffunction inside a cfc.

I'm running ColdFusion 8.0, Standard Edtion. Should I increase the Heap size? That seems like it might give it more time before it crashes again. It seems like the server is holding memory for some reason, as if the loop iteration is requiring CF to create objects, then load them into memory, and not release until the process has stopped. I'm not creating anything that I think would cause CF to store into memory.

Any help is appreciated.

Peter

    This topic has been closed for replies.

    3 replies

    peterswanAuthor
    Known Participant
    June 25, 2011

    Thanks iSaid for your reply,

    I'm sure the memory problems I'm having are due to the repeated inserts into the SQL Server database that I'm trying to do for each mail sent. ColdFusion must be caching the queries. On Monday I'll look into setting some options in the CF Administrator which might prevent ColdFusion from caching (Maximum Pooled Statements, query caching, etc.) However, I think this might be a limitation in ColdFusion 8.0 with repeated trips to the database within the same process. This is all happening within a CFFunction so I'll try to run this from a URL request to see if I have the same issues. I have a feeling that such a large amount of SQL queries will crash ther server regardless.

    I've looked into sending a simple command to a stored procedure in SQL Server to do the inserts after the CF process is finished. This will do fine for logging purposes if the process completes OK, however, if the process fails for whatever reason, I won't know what to log because I won't know how far along in the process the failure occured. Also, part of the requirement for this project is to allow for real time monitoring of the emails sent. This way the user can watch how many mails are going out, as they are being sent.

    Of course we can always change our requirements for the project and try a different logging solution, however, it would be nice if I could get a real time logging process in place, as each email is sent.

    Thanks for any further replies.

    Peter

    peterswanAuthor
    Known Participant
    June 24, 2011

    OK, i took out the logging query and it made it up to 50K before crashing.

    I knew that taking out the insert query would speed things up a bit, which it did, but what would that have to do with a memory leak?

    Does ColdFusion store the text of each query into memory?

    Thanks for your help,

    Peter

    P.S. Also considering a scheduler solution.

    Known Participant
    June 25, 2011

    Do you think CF is crashing because of the amount of emails it's trying to send or the amount of queries/looping etc that it needs to do (looping through 60,000 records)?

    As a test are you able to take out the cfmail part (so it doesn't send an email) and perhaps print a line to the screen to see if it finishes fully.

    Also could this be a limitation to the Standard edition?  In the CF edition comparision guide online the Enterprise edition has a "High Scalability Email Engine" - (without knowing) could this be different engine to the standard edition.  Just a thought, I could be wrong (and probably am).

    Alternatively (like Owain North mentioned), breaking it down into batches.  Good luck.

    Owainnorth
    Inspiring
    June 24, 2011

    You can increase the heap size, but that's more masking the problem rather than fixing it.

    Reality is that 60,000 emails is a *lot* to create in one loop, and I'd be surprised if a system ever really worked like that successfully. What I'd suggest you implement is something like we have here - you do one initial database query which creates rows in a messages table. A separate process then goes through said table and processes rows one at a time, changing the row status from unsent to send, or similar. That way it doesn't matter that they don't all send in one loop, it'll just pick up where it left off.

    Essentially you need to look into some way of batching the emails rather than sending that many at once. What if someone in your database has an invalid email address which crashes out CF on email 59,999? You now have no choice but to send the whole lot again, which is pretty weak.