I have a .NET service that processes a queue on a background thread and from the items in the queue sends out a large number of small e-mail messages at a very high rate (say 100 messages per second if that is even possible). Currently, I use SmtpClient.Send() but I’m afraid that it may hamper performance.
Each call to Send() goes through a full cycle of opening the socket, performing the SMTP conversation (HELO, MAIL FROM, RCPT TO, DATA) and closing the socket. In pseudo code:
for each message {
open socket
send HELO
send MAIL FROM
send RCPT TO
send DATA
send QUIT
close socket
}
(Edit: This statement about SmtpClient.Send() is in fact false as I have explained in my answer.)
I would think that the following pseudo code would be more optimal:
open socket
send HELO
for each message {
send MAIL FROM
send RCPT TO
send DATA
}
send QUIT
close socket
Should I be concerned about the performance of SmtpClient.Send() when sending e-mail at a high rate? What are my options for optimizing the performance?
The
SmtpClientclass is caching SMTP server connections behind the scenes. CallingSmtpClient.Send()repeatedly to submit multiple messages to the same SMTP server will effectively execute the pseudo code in the second example.One way to improve performance may be to use multiple instances of
SmtpClientrunning on multiple threads. Instead of having just one connection to the SMTP server the service will now have many concurrent connections. Incomming e-mail messages are taken from the queue and dispatched to a pool of worker threads that callsSmtpClient.Send()to send the message to the SMTP server.I have done some rudimentary tests and found that this may improve performance by as much as 100%. However, the optimal number of concurrent connections and the actual performance improvement is probably very much dependendent on the SMTP server. One way to extend this idea is to connect to multiple SMTP servers.