Session Lifecycle & Timeout
Session Lifecycle & Timeout
An HttpSession does not live forever. It is born on demand, carries state across multiple requests, and eventually dies — either because the user explicitly logs out, because the application decides to end it, or because the server reclaims it after a period of inactivity. Understanding this lifecycle precisely is what separates applications that are merely functional from ones that are secure and resource-efficient.
The Four Phases of a Session
- Creation — the session is created (a new JSESSIONID is generated and a server-side store entry is allocated).
- Active use — requests arrive that resolve to the same session; attributes are read and written.
- Idle — no request touches the session for a stretch of time; the server is counting down.
- Invalidation — the session is destroyed, either by timeout or by explicit code.
HttpSession, so it does not extend the timer.
Creating a Session
HttpServletRequest provides two methods for obtaining a session object:
Prefer getSession(false) in read-only contexts — for example, when checking whether a user is already logged in. Calling plain getSession() on every request creates a session even for anonymous visitors, wasting server memory and potentially confusing your analytics.
Reading Session Metadata
Once you hold a session reference, several methods reveal its lifecycle state:
isNew() returns true only on the very first request that created the session — before the client has sent back the session cookie. This is useful for detecting first-time visitors.
Configuring Timeout
The server invalidates an idle session once it has been inactive for maxInactiveInterval seconds. You can control this at three levels, from broadest to most specific:
- web.xml (application-wide default):
- Programmatically per session (seconds, not minutes):
- Spring Boot application.properties:
-1 in production unless the session holds no sensitive state — unbounded sessions accumulate on the heap until the server runs out of memory.
Explicit Invalidation
Relying solely on timeout is not enough. A user clicking "Log Out" must trigger immediate invalidation so that another person at the same computer cannot use the back button to regain access.
invalidate() on logout, and then clear the cookie. Invalidating the server-side session alone is not sufficient — the JSESSIONID cookie remains in the browser. While the server will reject it on the next request (the session no longer exists), there is a small window where a network attacker who already captured the token could try to race the server. Explicitly expiring the cookie closes that window.
Session Listeners
The Servlet specification provides a set of listener interfaces that let you react to session lifecycle events without modifying any servlet code. This is the correct way to implement cross-cutting concerns like audit logging, resource cleanup, and metrics.
HttpSessionListener — creation and destruction
sessionDestroyed fires for both explicit invalidate() calls and timeout-driven expiry, so it is the right hook for cleanup such as closing user-owned resources or writing a logout audit record.
HttpSessionAttributeListener — attribute changes
HttpSessionBindingListener — object self-aware binding
An object can implement HttpSessionBindingListener directly to receive notification when it is placed into or removed from a session — no separate listener class needed:
Using this pattern, when a session is invalidated and the container removes the UserPrincipal attribute, valueUnbound fires automatically — a clean, object-oriented way to release resources without any external wiring.
The Full Lifecycle in Practice
Bringing it all together: a session is created on first login, its timeout is tuned to the security requirements of the application, a listener keeps a live count for the admin dashboard, and logout explicitly invalidates it and purges the cookie. None of these steps requires polling or a background thread — the container drives the entire lifecycle, and your code hooks into the events it cares about.
Summary
- Use
getSession(false)to avoid creating unnecessary sessions. - Configure timeout globally in
web.xmlorapplication.properties; override per-session withsetMaxInactiveInterval(). - Always call
session.invalidate()on logout and expire the cookie. - Use
HttpSessionListenerfor creation/destruction hooks andHttpSessionAttributeListenerfor attribute-level auditing. - Implement
HttpSessionBindingListeneron domain objects that need to self-manage their resources.