Search code examples
emailvbathrottlingexchange-server-2010

Throttling in VBA


The Back Story

A little while back, I was asked if we could implement a mass email solution in house so that we would have better control over sensitive information. I proposed a two step plan: Develop a prototype in Excel/VBA/CDO for user familiarity, then phase a .Net/SQL server solution for speed and robustness.

What's Changed

3 Months into the 2nd phase, management decides to go ahead and outsource email marketing to another company, which is fine. The 1st problem is that management has not made a move on a company to go through, so I am still implicity obligated to make the current prototype work.

Still, the prototype works, or at least it did. The 2nd problem came when our Exchange 2003 Relay Server got switched with Exchange 2010. Turns out that more "safety" features are turned by default like Throttling Policies, which I have been helping the sysadmin iron out a server config that works. What's happening is that the after +100 emails get sent, the server starts rejecting the send requests with the following error:

The message could not be sent to the SMTP server. The transport error code is 0x800ccc67. 
The server response was 421 4.3.2 The maximum number of concurrent connections has exceeded a limit, closing transmission channel

Unfortunately, we only get to test the server configuration when Marketing has something to send out, which is about once per month.

What's Next?

I am looking at Excel's VBA Timer Function to help throttle my main loop pump to help throttle the send requests. The 3rd problem here is, from what I understand from reading, is that the best precision I can get is 1 second on the timer. 1 email per second would be considerably longer ( about 4x-5x longer) as oppossed to the 5 email/sec we have been sending at. This turns a 3 hour process into a an all day process past the hours of staff availability. I suppose I can invert the rate by sending 5 emails for every second that passes, but the creates more of a burst affect as opposed a steady rate if had more precision on the timer. In my opinion, this creates a less controlled process and I am not sure how the server will handle bursts as opposed a steady rate. What are my options?


Solution

  • You can use the windows sleep API if you need finer timer control. It has it's units in milliseconds:

    Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
    
    Public Sub Testing()
    
    'do something
    Sleep(1000) 'sleep for 1 second
    'continue doing something
    
    End Sub
    

    I'm not very familiar with Exchange, so I can't comment on the throttling policies in place.