Limiting Exchange 2010 SP1 Database Cache

Some time ago, I blogged about on how to limit the amount of memory Exchange 2010 can allocate for database cache. After the introduction of Exchange 2010 Service Pack 1 this didn’t seem to work anymore, as many people reported.

After some investigation, it turns out you also need to set the msExchESEparamCacheSizeMin value for Exchange 2010 SP1’s cache manager to honor the minimum and maximum limits for allocating database cache memory.

To show you this, I’ll first show Exchange 2010 SP1 where I only set msExchESEparamCacheSizeMax. In this example, I’ll use a value of 1024 which corresponds to 32 MB (1024 * 32kb pages). I then turned on Performance Monitor and started monitoring the following MSExchange Database Cache\Information Store counters:

  • Database Cache Size, the current allocated database cache size;
  • Database Cache Size Min, the minimum database cache size;
  • Database Cache Size Max, the maximum database cache size.

After restarting the Information Store and putting on some load on the Exchange server, you will see that the allocated database cache (green line) rises above the configured maximum (blue line).


When you check the database cache minimum size (red line), you’ll see it contains a default value, which can be larger than the configured maximum. So apparently, Exchange 2010 SP1’s cache manager contains different logic compared to Exchange 2010 RTM when the (default) minimum value is larger than the configured maximum.

To get Exchange 2010 SP1 to honor the configured msExchESEparamCacheSizeMax value, we need to configure msExchESEparamCacheSizeMin as well. The location is identical, so consult the initial post on how to perform this step; where it reads msExchESEparamCacheSizeMax, use msExchESEparamCacheSizeMin as well.

When we configure a value of 256 for msExchESEparamCacheSizeMin (8 MB) we get the following result after restarting the information store:


As you can see, the reported database cache size now nicely flattens out around the 32MB line when under load. Notice that it may go over it a little bit once in a while, but that may have to do with allocating and releasing memory.

Now only one question remains: is this a fault in Exchange 2010 SP1 or expected behavior. At least, it’s different behavior when compared to earlier Exchange versions.

Note that the above information also applies to Small Business Server 2011 since SBS2011 includes Exchange 2010 SP1.

Limiting Exchange 2010 Database Cache

Note (6apr2011): Setting the MsExchESEParamCacheSizeMax only doesn’t produce the required result as of Exchange 2010 SP1. For more information on how to limit the database cache size in Exchange 2010 SP1, see Limiting Exchange 2010 SP1 Database Cache.

I received a question from someone implementing Exchange 2010 who was surprised to see Exchange taking up all available memory. This is because in Exchange 2010 (2007 as well) memory allocation is dynamic, contrary to Exchange 2003 and earlier versions where, depending on the situation, you had to fiddle around with boot.ini switches like /3GB to make memory available to Exchange. Also, the maximum database cache size was limited in Exchange 2003 to around 1.2 GB due to virtual address space limitations (see MSKB 815372).

The main reason Exchange 2007/2010 claims memory for its database cache is performance. The more memory is assigned to the database cache, the less I/O’s are generated because things can be dealt with in-memory and the database cache becomes more effective. When a certain amount of transactions has been reached, changes will be physically written to databases (so far they’ve been stored in-memory and written to transaction logs). This limit is called the log checkpoint depth target.

Since Exchange 2003, the log checkpoint depth target is 20 MB databases. As of Exchange 2007, for configurations existing of 2+ database copies, the depth target is 100 MB for active copies and 5 MB for passive copies. This means, after 100 MB of transactions changes will be physically flushed to the database. The more changes are delayed (i.e. stored in-memory and in transaction logs), the chance of overlapping changes or combined writes increases lessening I/O’s required. Note that to lessen the time to fail-over, passive copies have a lower depth target making them commit changes more often, minimizing the log files to replay after a fail-over.

Back to the topic, Database Cache. Exchange uses by default certain mailbox database cache sizes for certain amounts of memory. The table below contains these values for systems holding the mailbox server role as well as servers holding multiple roles (source):

RAM Physical Memory Database Cache Size, Mailbox Role Database Cache Size, Multiple Roles
2 GB 512 MB Unsupported
4 GB 1 GB Unsupported
8 GB 3.6 GB 2 GB
16 GB 10.4 GB 8 GB
32 GB 24.4 GB 20 GB
64 GB 53.6 GB 44 GB
128 GB 111.2 GB 92 GB

Now what if you have a real uncontrollable urge to limit Exchange in its attempt to optimize its database cache and you want to restrict its growth?  You can do this by changing the following Active Directory property (per store) using ADSIEDIT.msc (or using another tool or scripting language of your liking) as follows:

  1. Start ADSIEDIT.msc
  2. Navigate to Configuration > Services > Microsoft Exchange > <Organization Name> > Administrative Groups > <Administrative Group> > Servers > <Server Name> > InformationStore
  3. Right-click InformationStore, and edit msExchESEParamCacheSizeMax. Set it it to the number of pages to maximize the Database Cache to. Note that Exchange 2007 works with 8 KB pages and Exchange 2010 with 32 KB pages!
  4. Restart the Microsoft Exchange Information Store service for the change to become effective.

So, for instance, if you want to limit the Database Cache to 4 GB of an Exchange 2010 server, set msExchESEparamCacheSizeMax to 131072 (4 GB = 4.194.304 KB / 32 KB). If you want to limit the Database Cache to 2 GB of an Exchange 2007 server, set msExchESEparamCacheSizeMax to 262144 (2 GB = 2.097.152 KB / 8 KB).

Note that lowering these values may degrade performance, in terms of server performance as well as in terms of end-user experience. However, smaller organizations with a limited number of mailbox users may benefit because they don’t let Exchange claim significant amounts of memory which it will never use.

Exchange 2010 Database Compression

One of the features of Exchange versions up to 2007 is Single Instance Storage (SIS). What SIS does is that it creates a single instance of messages sent to multiple recipients within the same database. Simply said, the first one gets a copy of the message in his or her mailbox, others get a referral to the message.

With the arrival of Exchange 2010 Microsoft made changes to the Extensible Storage Engine (ESE) .. again. Many of these changes are beneficiary to the performance of the system (read: less IOPS). For instance, Exchange 2010 uses larger pages and it orders database pages in the background. In an optimal situation this will result in an IOPS reduction of 70% versus Exchange 2007 (against Exchange 2003 a whopping 90%).

However, one of the victims of the new ESE is Single Instance Storage. This sounds worse than it is. Large (1 GB+) mailboxes are common nowadays, the maximum number of databases has increased and when looking at recovery times you are more likely to use multiple databases to reduce recovery times.

These developments also reduce the effectiveness of Single Instance Storage, which only works in a single database. In addition, the price of storage has dropped enormeously and focus these days is more on performance than on disk space.

Now before you think about getting additional storage space to counter the effects of SIS absence, I have good news. The new Exchange 2010 ESE engine has built-in storage compression. Certain parts of e-mail messages (headers, body) are stored in compressed format. Attachments are not compressed. Reason for not compressing attachments is that (de)compressing would be too CPU intensive (goodbye to performance improvements due to I/O reduction). Another reason I can think of is that it would be pointless to compress attachments as 90% of the attachments are probably already compressed (zip, docx, jpg).

First measurements show storage compression neutralizes the effects of SIS being gone. In fact, results are expected to be a lot better because storage compression doesn’t rely on messages being stored in the same database. Measurements also indicate overhead caused by (de)compression is equal or less than the amount of overhead required for the extra IOPS for fetching/storing uncompressed information.

For those interested, the algorithm used here is the same as in MAPI and DAG network traffic, i.e. XPRESS. This is a Microsoft implementation of the LZ77 algorithm. For more background information – or if you can’t sleep – check out the underlying RTF Extensions Specification.