State and stateless
“What is a stateless class, and why should shared services be stateless?”
What an object remembers between one method call and the next, and why shared code should remember nothing.
See it
In plain words
State is what an object remembers between one call and the next. A loan remembers its rate, so car.Emi() gives a different answer after the rate changes. A stateless class remembers nothing: works only from what you pass in, so the same inputs always give the same answer. Nothing remembered means nothing to mix up, so one copy can serve every user at once.
- State is the data in an object's fields that lasts from one method call to the next.
- A stateful object's results depend on its history: changes what returns.
- A stateless type keeps no fields that change, so each call depends only on its arguments and its own local variables.
- That makes it predictable, easy to unit test, and to share.
- Stateless does not mean static: a normal class with no changing fields, created once and shared, is just as safe.
- So shared services, like singletons in DI, should be stateless, and per-user data belongs in entities or objects.
In the lending API
The stateless calculator and two tests: one shows state changing an answer, one shows no state at all. Press Next line to walk through them.
Lending.sln · where these 3 files sit
- src/Domain/Common/
- tests/Domain.UnitTests/
- Servicing/
- Common/
- Servicing/
What they ask next
Interviewers check that you can explain every line. Tap a question to open it.
Explain this lineAre local variables like
rstate?No. A local lives only while one call runs, and each call gets its own. State is fields: data that outlives the call.
Why does this matter in a web app?
A web app handles many at once, on many . A stateless object can be shared by all of them safely. A stateful one shared the same way leaks one user's data into another user's request. later asks this exact question of every service: does it keep state?
So is stateful bad?
No. A Loan must remember its rate and balance; that is its job. The rule is where state lives: in objects that belong to one user or one request, never in a service everyone shares.
How would a bug like that look in production?
Rarely in tests, because tests run one user at a time. Under load, a customer sees another customer's numbers now and then, and nobody can reproduce it on their machine. walks through one.
What about a field set in the constructor?
If it never changes after the , like a setting or another stateless service, every call sees the same thing, so the object is still safe to share. Careful: only stops the field pointing at a different object. A
readonly List<Loan>can still have items added, and that is state.Is a stateless method always thread-safe?
Only if it touches nothing shared. If it writes to a static field, a file or a shared list, it has state, just stored somewhere else. writes only to its own locals.
What is a pure function?
A method whose result depends only on its inputs and that changes nothing outside itself. is one. Pure functions need no setup and no mocks to test. Stateless is not always pure: a stateless service that reads the database or the clock can give a different answer tomorrow, without keeping any field.
Is a REST API stateless? Why does that help it scale?
Yes, by design: each request carries everything the server needs, and session data lives in a database or a cache like Redis, not in the server's memory. So any server can answer any request, and you add servers when load grows.
Traps
- Don't say
Stateless means the class has no data at all.SayStateless means nothing is kept between calls. Parameters, local variables and fixed settings are fine, as long as nothing they hold can change. - Don't say
The field is private, so sharing the object is safe.Say hides the field from other code, not from other requests. If the field changes, every request sharing the object sees the change. - Don't say
Stateless and static mean the same thing.SayStatic is where a member lives. Stateless is whether anything is remembered. A normal object can be stateless, and a static field that changes is state.
An AI tool can add a "handy" field to a shared service, like remembering the last loan it worked on. It compiles and passes a one-user test. Interviews now include reviewing and explaining AI-written code, and "this field makes a shared service stateful" is the catch they expect.