Sunday, April 22, 2012

Email Latency

If you want to find out the overall latency for e-mails flowing in your Exchange 2007 organization, you can use the MSGAnalyzer tool from Microsoft or you have to check when an e-mail first reached your servers, check when it was delivered to the recipient’s mailbox and then calculate the time difference.

The good news is that with Exchange 2010 this is much, much easier as this information is saved in the Message Tracking Logs. When a HUB server delivers a message (through the Store Driver) it generates a DELIVER event which contains the TimeStamp of when the message was delivered (as with Exchange 2007) but now it also includes the MessageLatency which is the difference between the original arrival time of the message and this timestamp.

So, if you want to check the latency for all the e-mails arriving in your organization, simply use the a cmdlet similar to the following one:

Get-TransportServer | Get-MessageTrackingLog -ResultSize Unlimited -Start "03/26/2012" -EventID DELIVER | FT MessageLatency

Which will give you a TimeSpan value like “00:00:03.8130000” which means the e-mail took almost 4 seconds to be delivered.

If you are just interested in a particular day and also want to know which HUB server delivered it each message:
Get-TransportServer | Get-MessageTrackingLog -ResultSize Unlimited -Start "03/26/2012" -End "03/27/2012" -EventID DELIVER | Select TimeStamp, ClientHostname, @{Label="LatencyMil"; Expression={$($_.MessageLatency).TotalMilliseconds}} | Export-Csv Latency_20120326.csv -NoTypeInformation

Note that this time we are printing the TotalMilliseconds it took to deliver each message which makes it easier to calculate the average for the day in Excel.


  1. Great post!
    I have a client with HT in NA, EU, & AU, and all of the inbound message traffic comes into the HT in NA and then gets routed to the associated sites. We're trying to help in justification with larger pipes in EU & AU so being able to show how long a message takes to be delivered from HTs here to HTs there and vice versa further helps our case.
    The only problem I ran into with this script is that I added in a Select for ServerHostname and ClientHostname, but the ServerHostname doesnt reflect what I see by running a Get-MessageTrackingLog | FL. For example, instead of seeing my HT server name shoudn't I see external sources, like
    Any advise?

  2. Hi Chris,

    Thank you! :)
    It looks like an interesting but challenging task!
    Exchange calculates the latency from the moment a message hits the first Exchange server. For example, in my case an e-mail comes from the Internet, to MessageLabs, to my “Edge” server (not exchange), to a HUB server and finally to a mailbox server.
    If I do a trace for such e-mail I will see first the e-mail coming in from the “edge” server into the HUB:
    Timestamp : 28/04/2012 08:15:53
    ClientIp :
    ClientHostname :
    ServerIp :
    ServerHostname : HUBserver
    Source : SMTP
    EventId : RECEIVE

    And then from the HUB to the mailbox server:
    Timestamp : 28/04/2012 08:15:53
    ClientIp :
    ClientHostname : HUBserver
    ServerIp :
    ServerHostname : MBXserver
    Source : STOREDRIVER
    EventId : DELIVER
    MessageLatency : 00:00:00.4530000
    MessageLatencyType : EndToEnd

    In this lat one the ServerHostname will be your mailbox server and the ClientHostname the HUB server that delivered the e-mail.
    You will only see the last external source before the e-mail reaches your Exchange server (the “edge” server in my case). You will never see except on the message headers or on the sender’s e-mail address.

    If I send an e-mail to someone in EU, does it go like this: internet -> edge -> hubNA -> hubEU ->mbxEU?
    If this is the case the latency will be latency from hubNA -> hubEU and from hubEU ->mbxEU so you might have to update your query to calculate the latency just between these two servers.

    Does this help?