Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sending SMTP e-mail at a high rate in .NET

Tags:

.net

email

smtp

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?

like image 748
Martin Liversage Avatar asked Apr 26 '10 13:04

Martin Liversage


People also ask

Can .NET send emails?

NET and . NET Core come with built-in support for sending emails through the System. Net.Mail namespace. While it might seem like the easy choice, you will need an SMTP server for this to work.

What is SMTP in C#?

Simple Mail Transfer Protocol (SMTP) is a TCP/IP protocol used in sending and receiving e-mail. Most e-mail systems that send mail over the Internet use SMTP to send messages from one server to another. The messages can then be retrieved with an e-mail client using either POP or IMAP.


2 Answers

The SmtpClient class is caching SMTP server connections behind the scenes. Calling SmtpClient.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 SmtpClient running 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 calls SmtpClient.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.

like image 112
Martin Liversage Avatar answered Oct 27 '22 21:10

Martin Liversage


Create an email server that sends off emails asynchronously using a threadpool or something. That way you can "fire and forget" your emails at the server and let it worry about sending them all off. Set it up with a few threads or more and it should be able to whip through emails pretty fast.

like image 29
Chris Avatar answered Oct 27 '22 23:10

Chris