In a web framework, when is a session object actually created, and why does lazy creation matter?
answer
- the session is created, not always present
- first write, not first read
- no attribute stored, no identifier cookie
- eager creation grows with traffic, not users
basics
~20 sMost frameworks create a session lazily: the identifier, the store entry and the identifier cookie appear only once a handler uses the session, typically on its first write. Eager creation instead gives every anonymous visitor an entry and a cookie.
solid answer
~40 sThree things make up a session: an identifier for the client, an entry in the store holding the attributes, and a response header telling the client to send the identifier back. Under lazy creation none of them exists until a handler writes an attribute, so a visitor who only reads anonymous pages leaves nothing behind. Under eager creation the framework allocates on every request, and the store then grows with raw traffic including crawlers. Frameworks differ on the exact trigger: some allocate on the first write, others on the first access to the session object even when the handler only reads. The usual production bug is a hook that stamps a value into the session on every request, quietly turning a lazy framework into an eager one.
go deeper
Remember that a session is created, not always there. Nothing exists until your handler stores something, and that is when the client receives the identifier it will send back.
Be able to name the three pieces that must appear at creation time — identifier, store entry, response cookie — and explain what lazy versus eager creation does to store size on an anonymous page.
Show you can find the accidental write. Reproduce with a cookie-free request, bisect the hooks on the path, and connect store growth curves to traffic rather than to sign-ins.
Frame it as a cost and capacity question: eager creation makes store size a function of raw traffic, which changes eviction policy, sizing and what an upstream shared cache may keep.
## What "this request has a session" actually means A session is a server-side bag of named values belonging to one client and surviving across that client's requests. Three separate things must exist before a request genuinely has one: - an **identifier** minted for this client and unique to it; - an **entry in the store** holding the attributes under that identifier — in process memory, in a shared data store, in a database table; - a **response header telling the client to keep the identifier** and send it back on the next request, which in practice is a cookie. None of the three is free, so the interesting question is what triggers them. Frameworks answer it in one of two ways, and the answer is usually configurable. ## Lazy creation: born on the first write Under lazy creation the request is routed and reaches the handler with **nothing allocated**. The handler may ask the framework for the session object and read from it; if the incoming request carried no identifier, those reads return nothing and still allocate nothing. The moment the handler **stores** an attribute, the framework mints an identifier, creates the store entry, and arranges for the identifier cookie to be sent with the response. The consequence is that a visitor who browses anonymous pages and never causes a write leaves no trace in the store and receives no identifier. Only the first request that genuinely needs to remember something pays for the machinery. Frameworks differ on the precise trigger. Some treat the first *write* as the creation point; others create as soon as the handler touches the session object at all, on the argument that a read implies the handler intends to participate. Knowing which one you are on matters, because a read-only page under the second rule is a writing page. ## Eager creation and what it costs | | Lazy creation | Eager creation | |---|---|---| | Trigger | first attribute stored | every request that reaches the handler | | Anonymous visitor | no entry, no identifier cookie | one entry and one cookie each | | Store growth | tracks users who did something | tracks raw traffic, crawlers included | | Empty session means | not created yet | created and empty | | Cost per anonymous hit | none | one write, one eviction later | Eager creation is not automatically wrong — it makes the session unconditionally present, which simplifies code that would otherwise branch — but on a public endpoint the store then grows with traffic rather than with users, and automated clients that discard cookies mint a fresh entry on every single hit. ## How eager behaviour sneaks into a lazy framework Configuration is rarely the culprit; a forgotten write usually is: 1. a hook running before every handler that stamps a visit counter, a correlation value or a first-seen timestamp into the session; 2. a "read with a default" helper that implements the default by writing it back; 3. a value generated for every rendered page and stashed so the next request can compare it; 4. a message-passing helper used for something that is not a one-off message. Each of these converts an anonymous read path into a write path, and the store fills with entries whose only attribute is the one the hook wrote. ## Diagnosing which behaviour you have - Send a request carrying **no** cookie to an anonymous page and read the response headers. An identifier cookie coming back means something wrote. - Compare live store entries against the number of people who signed in over the same window. Orders of magnitude apart means entries are being created for visitors who did nothing. - Watch the ratio during a crawl. A client that does not retain cookies creates a new entry per request, so eager creation turns one crawl into thousands of short-lived entries. Two further consequences are worth carrying. A response that sets an identifier cookie is client-specific by construction, which constrains what an upstream shared cache may store. And an identifier handed to a visitor who never returns is pure cost: the entry occupies the store until it expires. ## Why interviewers ask it It is the cheapest way to find out whether a candidate thinks of the session as an ambient property of every request or as a resource with a lifecycle. The follow-up is operational: the store is full, eviction is churning, and the fix is not a larger store — it is finding the write that should never have happened.
- How would you prove, from outside the process, that an anonymous page is creating sessions?Send a request with no cookies at all and inspect the response headers. If an identifier cookie comes back, something on that path wrote to the session. Repeat with the suspicious hooks disabled to bisect which one did it, and watch store entry count while replaying anonymous traffic.
- A crawler with no cookie jar hits an eagerly-creating endpoint a million times. What happens in the store?Every request looks like a brand-new client, so each one mints an identifier and an entry. A million short-lived entries accumulate until expiry or eviction removes them, inflating memory or row count and possibly evicting real users' entries. Lazy creation would have written none of them.
- Does lazy creation mean a session can be lost between two requests of the same user?No. Once created, the entry persists under its identifier until it expires or is destroyed, and the client keeps sending the identifier. Lazy only governs the moment of birth, not the lifetime afterwards.
saying these in an interview costs you the question
- Says every incoming request already has a session attached
- Thinks the identifier cookie goes out before anything is stored
- Believes lazy creation means the session is discarded between requests
- Stamps a value into the session in a global hook, then blames traffic for store growth
- Assumes the store holds only logged-in users, whatever created the entries