Do not store large object graphs in HttpSession. This can severely affect the performance of a WebSphere application. Look for alternatives like an application specific JDBC framework that can augment or replace HttpSession for storing servlet state data. Application design for performance and scalability requires consideration of servlet state data. If your application requires a large amount of servlet data, consider application specific alternatives that either augment or replace the use of HttpSession.
This best practice applies to the following product, version, and platform:
- WebSphere Application Server Base, all platforms, versions 3.0.2.x, 3.5.x, 4.0
Large applications require using persistent HttpSessions. However, there is a cost. An HttpSession must be read by the servlet whenever it is used and rewritten whenever it is updated. This involves serializing the data and reading it from and writing it to a database. In most applications, each servlet requires only a fraction of the total session data. However, by storing the data in the HttpSession as one large object graph, an application forces WebSphere® Application Server to process the entire HttpSession object each time.
WebSphere Application Server has HttpSession configuration options that can optimize the performance impact of using persistent HttpSessions. The HttpSession configuration options are discussed in detail in the WebSphere Application Server documentation. Also consider alternatives to storing the entire servlet state data object graph in the HttpSession. Using your own JDBC connection alternative is described and discussed below.
Do not forget to explicitly invalidate the HttpSession when you are finished with it.
When configuring persistent sessions in WebSphere Application Server, use a dedicated data source. To avoid contention for JDBC connections, do not reuse an application DataSource or the WebSphere Application Server repository for persistent session data.
Figure 1 compares the relative performance of a sample application with a single object of different sizes. As the size of the objects stored in the HttpSession increases, throughput decreases, in large part due to the serialization cost.
Figure 1. HTTP Session Single Object

In most applications, each servlet needs only a fraction of the entire application's state data. As an alternative to storing the entire object graph in the HttpSession, use JDBC for partitioning and maintaining the state data needed by each servlet in the application.
A sample JDBC solution maintains the state data needed by each servlet as a separate row in an application-maintained JDBC datasource. The primary keys for each row (the data for each servlet) are stored as separate attributes in the HttpSession. The use of the HttpSession is reduced to the few strings needed to locate the data.
JDBC alternative - session data
// Get the session data value
try {
conn= getPooledConnection(); // Uses DataSources to Get JDBC Connection
See Best Practice
conn.setAutoCommit(false);
sessionKey = (String) session.getValue(TOP_KEY);
// Session Key Does Not Exist - This is a new Session Build the Data
if (sessionKey == null) {
sessionKey = UniqueValue.getUniqueValue();
session.putValue(TOP_KEY, sessionKey);
sessionDtaa = new SessionLargeObjectCollection(NUM_REPS);
psi = conn.prepareStatement(INSERTSTMT);
psi.setString(1,sesisonKey);
psi.setBytes(2,convertToBytes(sessionData)); // Serialize and Write Out
psi.executeUpdate();
sessionKey = UniqueValue.getUniqueValue();
session.putValue(Integer.toString(i+1),sessionKey);
}
else { // The Session Does Exist...Retrieve the Data to Generate Load
sessionKey = (String)session.getValue(TOP_KEY);
pss.conn.prepareStatement(SELECTSTMT);
pss.setString(1,sessionKey);
rs.pss.executQuery();
if (rs.next()) { // De-serialze and read in
sessionData = convertBytesToSessionObjectCollections
(rs.getBytes("SAVESERIALIZEDDATA"));
}
// Update the Data to Generate Load
psu = conn.prepareStatement(UPDATESTMT);
psu.setString(2,sessionKey);
psu.setBytes(1,convertToBytes(sessionData)); // Serialize and Write Out
psu.executeUpdate();
}
conn.commit();
}
catch (Exception e) { // Handle Errors }
finally {
// Close Connections and Statements - See Best Practice
}
|
Figure 2 shows the performance improvement of partitioning the servlet state data and using JDBC over maintaining servlet state data as a single object in the HttpSession.
Figure 2. Using JDBC to store servlet state instead of HttpSession

JDBC alternative - cleanup Issues
The homegrown servlet state data framework illustrated in the example creates records in a user database. At some point, these records need to be deleted through a cleanup process. Two good alternatives for this purpose are:
- Periodic offline: Non-WebSphere process. On UNIX systems, this would be a CRON job. On Windows® NT or Windows 2000, it would be a scheduled function. In either case, it would delete records after a certain period of time depending on the application. In this example, the database is keyed on servlet data time of creation.
- HttpSessionBindingListener: This homegrown alternative stores the servlet state data in an application - specific database. It stores the primary keys for the servlet state data records in the HttpSession. When the HttpSession is about to be destroyed, the javax.servlet.http.HttpSessionBindingEvent for valueUnbound could direct a delete of the servlet state data. If the lifetime of servlet state data is longer than that of the HttpSession, use the first alternative instead.




