Courtesy : 4GuysFromRolla.com/Scott Mitchell
Caching is the process of taking information that is time-instensive to collect and storing it in a location that requires less time to access. For example, in your office your desk serves as a cache of sorts - it's much quicker to work with documents on your desk than to have to walk over to the filing cabinet each time you need a new document.
In the ASP-world, some time-intensive tasks include, among other things, accessing a database. It is much, much faster in an ASP page to access an in-memory variable than to retrieve the value from a database. (This is due to the time-expensive steps that must be taken to work with a database - setting up the database connection, issuing the query, retrieving the results, etc.)
We can use application-level variables as a cache to store database results. Since application variables are accessible from any ASP page they are quite a logical choice for a caching system. A real-world example of caching can be seen on the ASPMessageboard. On the home page a list of the various messageboard forums is presented along with how many posts each forum has received in the current day and since the forum's existence. This information is retrieved from a database. Rather than querying the database each time someone visits the main page, I use application variables to cache the results of the database query. I also use an application variable to record at what time I last updated the cache with database results. Once that time is greater than 15 minutes, I invalidate the cache. That is, I rerun the database query and populate the application variables with the result of the latest database query.
With this caching technique in place, database hits on the ASPMessageboard homepage only occur, at most, once every 15 minutes. Previously, a database read occurred each time someone visited the home page. So, if 500 page views occurred on the home page in a 15 minute cycle, 500 database reads would have occurred. With the caching system in place, regardless of how many folks visit the home page in a 15 minute period, there will be only one database read! This illustrates the performance benefit inherent with caching!
To read about the technical specifics of using application variables in caching, be sure to read: A Real-World Example of Caching Data in the Application Object. That article examines the ASPMessageboard home page cachine discussed in this FAQ, a great read.
Also, for a thorough collection of caching-related article be sure to check out the Caching Article Index.
I (Scott Mitchell) recently tweaked the ASPMessageboard homepage so that the database values displayed are cached (as opposed to needing to make a call to the database each time the homepage is visited). The front page on the messageboard shows the number of posts for each forum in a given day... (If you're not familiar with the messageboard's front page, take a moment to check it out!).
Before my recent change, the front page made a database call each time it was viewed. The database call grabbed the number of daily posts and total posts for each forum (as well as for the entire messageboard). The front page is the ASPMessageboard's second most-visited page (after the ASP Q&A Forum), so I reasoned that I could remove a little bit of stress on the database by caching the various forum post counts as opposed to grabbing them every single page request.
For this project I decided to cache my data as application-level variables. There are a number of methods you can choose to use when it comes to caching data... there are third-party components avaiable, for example. In my opinion, using the Application object is the simplest and makes the most sense. (With ASP+ there is a built-in Caching object that you can use!)
As with any caching technique, you need to decide what event invalidates the cache. For this project, I decided to have it be time-based: if it had been more than 15 minutes since I last cached, I invalidated the cache, and hit the database, reloading the cache. To start, I needed an application-level variable to keep track of the last time the cache was created: DateCached. Second, I needed to initialize the variable in the Global.asa file's Application_OnStart event handler. Obviously, I need the cache to be invalid when the messageboard's front page is hit for the first time after a server restart. Therefore, I have the DateCached application variable initialized to one day prior to the current time:
<SCRIPT LANGUAGE=VBScript RUNAT=Server>
Sub Application_OnStart
'Initialize the DateCached application variable to
'one day prior to the current date/time
Application("DataCached"

= DateAdd("d", -1, Now())
End Sub
</SCRIPT>
For more information on DateAdd check out this popular FAQ: How can I add or subtract time from a date? For more information on Global.asa be sure to read: Everything you Wanted to Know about Global.asa, but Were Afraid to Ask!
Now, in the front page for the messageboard (Default.asp), I needed to first determine if the cache was invalid (i.e., the difference between the current time and the Application("DateCached"

variable was greater than 15 minutes). If it was, then I needed to hit the database and populate the various application-level variables with the results. If the cache was not invalid, then I simply needed to display the cached data.
To determine if my cache is invalid, I use this simple conditional:
If DateDiff("n", Application("DateCached"

, Now()) > 15 Then
This statement uses the VBScript DateDiff function to determine the time between the DateCached application variable and the current time. If this conditional is true (that is, the time between our last cache operation and the current time exceeds 15 minutes), then we need to hit the database and repopulate the cache like so:
Application.Lock 'Lock the application object
If DateDiff("n", Application("DateCached"

, Now()) > 15 then
'******* Cache is invalid!! *********
'We need to repopulate the cache...
'Make connection to database
Dim objConn
Set objConn = Server.CreateObject("ADODB.Connection"

objConn.Open "DSN=Foo"
'Get the post Count
Dim objRS
Set objRS = objConn.Execute("sp_GetPostCount"
'Now, set the application level cache to the
'database results
Application("iTotal"

= objRS("TotalPosts"

.Value
Application("iASP"

= objRS("ASPPosts"

.Value
Application("iDatabase"

= objRS("DatabasePosts"

.Value
' ... some code snipped for brevity ...
' **** VERY VERY IMPORTANT!! ****
'We must now update the time with which we last
'cached our data!
Application("DateCached"

= Now()
End If
Application.UnLock 'Unlock the application object
Note that we are setting a slew of application-level variables to database results. These are displayed further down in our ASP page, where the HTML is outputted displaying the post counts for each forum for the day. Note that we don't need to do anything if the cache is valid... we already have the cached database results!
Note that we use the Lock method of the Application object before we check to see if the cache valid or not... furthermore, we UnLock the cache once we've completed this step. When the Application object is locked, no other concurrent users can access application-level variables until it is unlocked. Therefore, we prudently Lock the Application object before altering its values.
The Default.asp page concludes with the HTML output that integrates the various application-level variables:
... some HTML removed for brevity ...
<li><a HREF="/forum/asp.asp">ASP Questions and Answers</a>
(<%=FormatNumber(Application("iASP"

,0)%> new posts today<br>
<li><a HREF="/forum/ASPPlus.asp"><b>Moderated</b> ASP+ Forum</a>
(<%=FormatNumber(Application("iASPPlus"

,0)%> new posts today<br>
<li><a HREF="/forum/databases.asp">Database (ADO/SQL/Access) Questions
and Answers</a> (<%=FormatNumber(Application("iDatabase"

,0)%>
new posts today, <%=FormatNumber(iDatabaseTotal,0)%> total!)<br>
... some HTML removed for brevity ...
<font size=2><i>
Last cached on <%=Application("DateCached"

%>
</I></font>
Well, that about wraps it up! In this article we examined how to use the Application object to cache data. On several sites there's no real need to hit the database everytime, especially if the values change infrequently.... simply cache the data in application-level variables! All you need to do is decide how to invalidate the cache, and write a small bit of code!
Rushi Shroff Rushi@emqube.com
"Life is beautiful."