Interview Question
"How do sessions and cookies work in Rails?"
The interview question that tests whether the candidate has actually thought about how state survives across stateless HTTP requests. The cookie store, signed vs encrypted, alternative session backends, and the production failure modes seniors have hit.
What the interviewer is actually checking
HTTP is stateless. Sessions are the layer that pretends otherwise. The question filters for whether the candidate knows where session data lives, who can read it, who can tamper with it, and what happens when the session grows past the default size limit.
The follow-ups extend into authentication, CSRF protection, secure cookie flags, and the trade-offs between the cookie store and server-side stores. A weak answer says "Rails handles it." A senior answer covers the mechanics, the security model, and at least one production gotcha.
The mid-level answer
"Sessions are how Rails remembers a user across requests. You set session[:user_id] = user.id in a controller, and on the next request the user is still logged in. Cookies are what the browser sends back to the server with each request."
Correct, but skips every interesting detail. The senior answer covers where the session data is stored (cookie store by default), how Rails prevents the user from forging session data, what the 4KB cookie limit means in practice, and the alternative stores.
The senior answer
The mechanism. "Rails's default session store is the cookie store. When you write session[:user_id] = 42, Rails serialises the entire session hash, encrypts it, signs it with a secret, base64-encodes the result, and sends it back as a _app_session cookie. The browser stores the cookie and sends it back with every subsequent request. The server decrypts, verifies the signature, deserialises, and the session hash is back in session."
Signed vs encrypted. "Pre-Rails 5, the cookie store signed the cookie but did not encrypt it. Anyone with the cookie could base64-decode and read the session contents (but not modify it without invalidating the signature). Rails 5 switched to encrypted-and-signed by default. The signing uses HMAC; the encryption uses AES-GCM. The signing key and encryption key both derive from Rails.application.secret_key_base."
The 4KB limit. "Browsers cap cookies at 4KB. The session payload (encrypted + base64-encoded) has to fit. For a session with a user_id and a flash message, that is plenty. For a session that accidentally accumulates large data (form-state-across-redirects, half-built objects, large attribute hashes), the cookie blows the limit and Rails raises ActionDispatch::Cookies::CookieOverflow. The senior fix is to keep the session small (ids, not objects) and use the flash for short-lived messages only."
The alternatives. "Rails ships three other session stores. The Active Record store puts sessions in a database table; right when sessions are large or when you need server-side invalidation. The cache store (Memcached or Redis) keeps sessions in-memory; right when sessions are large but ephemeral. The null store no-ops everything; useful for stateless APIs. Each is one config line in config/initializers/session_store.rb."
The cookie flags that matter
"Three flags Rails sets by default and a senior should be able to name."
HttpOnly: the cookie is not accessible to JavaScript. Mitigates session theft via XSS. Always on for session cookies; you have to opt-out explicitly.Secure: the cookie is sent only over HTTPS. Rails sets it in production automatically whenconfig.force_ssl = true.SameSite: controls when the cookie is sent on cross-origin requests. Defaults toLaxin Rails 7+.Strictfor higher-security apps;Noneonly when you genuinely need cross-site cookie sharing and pair it withSecure.
CSRF protection
"Sessions plus state-changing requests means CSRF risk. Rails handles this with the protect_from_forgery filter (on by default in ApplicationController). Every form rendered by Rails embeds an authenticity token; on POST/PUT/PATCH/DELETE, Rails verifies that the token in the request matches the one bound to the session. A request without a valid token raises ActionController::InvalidAuthenticityToken and the action is not run."
"The senior gotcha: API endpoints called from a different origin do not have a session cookie and do not need (or work with) CSRF tokens. The Rails default is protect_from_forgery with: :exception which raises on missing tokens. For API controllers, use skip_before_action :verify_authenticity_token and rely on a different auth mechanism (Bearer token, signed JWT, OAuth)."
The follow-ups
"How do you invalidate a session?" The right answer depends on the store. With the cookie store, you rotate the signing/encryption key, which invalidates every existing cookie. With the Active Record store, delete the row. With the cache store, evict the key. There is no "logout server-side" with cookie-store unless you keep a server-side blacklist or use short expirations.
"What's the difference between the session and cookies in Rails?" The right answer: session is one specific cookie that Rails owns, signs/encrypts, and treats as a hash. cookies is the general API for setting any cookie on the response. The session is built on top of the cookies API in the default store.
"How would you handle a logout that invalidates the session everywhere?" The right answer names the trade-off. With cookie-store, you cannot. Switch to a server-side store (AR or Redis) and delete the session row, or implement a token-based session in the cookie that gets revoked by id in a server-side blacklist on logout. Devise's "trackable" + "timeoutable" + a revocation strategy is the standard pattern.
"How big is the session payload in your app?" Bonus question. A senior should be able to estimate: an integer user_id plus a flash hash is under 200 bytes. Anything over 1KB suggests something is being put in the session that should not be.
The principle at play
The session is one cookie among many, with specific security properties Rails enforces. Knowing the mechanism (encrypted + signed, base64, browser sends it back) is the difference between "the session works by magic" and "I can debug why this user got logged out unexpectedly."
Most production session problems trace to one of three causes: the session got too big (CookieOverflow), the signing key rotated and old cookies became invalid (users logged out unexpectedly), or the session contains data that should have been stored server-side (security-sensitive flags, large object hashes). A senior who has hit any of these can describe the cause in one sentence.