Session Management
Session Table
Sessions contain id, token, userId, expiresAt, ipAddress, userAgent, createdAt, and updatedAt.
When secondary_storage is configured, Better Auth can store sessions outside the database. Use session.store_session_in_database when you also want a database copy.
Session Expiration
Configure session lifetime with session.expires_in.
auth = BetterAuth.auth(
secret: ENV.fetch("BETTER_AUTH_SECRET"),
session: {
expires_in: 60 * 60 * 24 * 7,
update_age: 60 * 60 * 24,
fresh_age: 60 * 5
}
)Disable Session Refresh
Pass disableRefresh or disable_refresh to get_session when you do not want the session updatedAt refreshed.
auth.api.get_session(
headers: {"cookie" => cookie},
query: {disableRefresh: true}
)Defer Session Refresh
Ruby refreshes according to update_age. Use disableRefresh for requests that should only read session state.
Session Freshness
Sensitive endpoints require a fresh session. Configure the age window with fresh_age.
session: {
fresh_age: 60 * 10
}Endpoints such as password changes, password setting, account unlinking, and user deletion use freshness checks where required.
Session Management
Get Session
auth.api.get_session(headers: {"cookie" => cookie})Use Session
Rails controllers can use helpers:
class ApplicationController < ActionController::Base
include BetterAuth::Rails::ControllerHelpers
end
class DashboardController < ApplicationController
before_action :require_better_auth_session!
def show
@session = better_auth_session
@user = better_auth_user
end
endList Sessions
auth.api.list_sessions(headers: {"cookie" => cookie})Revoke Session
auth.api.revoke_session(
headers: {"cookie" => cookie},
body: {token: session_token}
)Revoke Other Sessions
auth.api.revoke_other_sessions(headers: {"cookie" => cookie})Revoke All Sessions
auth.api.revoke_sessions(headers: {"cookie" => cookie})Update Session
Update declared session fields:
auth.api.update_session(
headers: {"cookie" => cookie},
body: {activeOrganizationId: "org_123"}
)The field must exist in session schema or additional fields.
Revoking Sessions On Password Change
auth.api.change_password(
headers: {"cookie" => cookie},
body: {
currentPassword: "old-password",
newPassword: "new-password",
revokeOtherSessions: true
}
)Session Caching
Cookie Cache
Enable cookie cache to avoid a database or secondary-storage read on every session lookup.
session: {
cookie_cache: {
enabled: true,
max_age: 60 * 5
}
}Cookie Cache Strategies
Use the configured cookie cache strategy for your deployment. The cache stores session/user data in Better Auth cookies and is refreshed as sessions refresh.
Sessions In Secondary Storage
Configure secondary storage to store sessions outside the database.
auth = BetterAuth.auth(
secret: ENV.fetch("BETTER_AUTH_SECRET"),
secondary_storage: redis_storage
)Storing Sessions In The Database
session: {
store_session_in_database: true
}Preserving Sessions
session: {
preserve_session_in_database: true
}This keeps database session rows after the secondary-storage record is deleted.
Stateless Session Management
Basic Stateless Setup
Use database: nil when your app relies on cookie-backed session state and plugin behavior that does not require persistent adapter writes.
auth = BetterAuth.auth(
secret: ENV.fetch("BETTER_AUTH_SECRET"),
database: nil,
session: {
cookie_cache: {
enabled: true
}
}
)Understanding refreshCache
Refresh behavior is controlled by session expiration, update age, and cookie cache settings.
Versioning Stateless Sessions
When rolling out stateless sessions, rotate secrets carefully and keep old secrets configured long enough for existing cookies to expire.
Stateless With Secondary Storage
Secondary storage can be combined with cookie cache to share sessions between processes while reducing database reads.
Customizing Session Response
Use session additional fields or the custom session plugin to shape session data.
auth = BetterAuth.auth(
secret: ENV.fetch("BETTER_AUTH_SECRET"),
session: {
additional_fields: {
activeOrganizationId: {
type: "string",
required: false
}
}
}
)Caveats On Customizing Session Response
Only expose fields that are safe for clients. Avoid adding secrets, raw provider tokens, password hashes, or internal authorization state to session responses.