Sessions
How long Ploy Auth sessions last, how active sessions are extended, the maximum session age, and the session cookie cache.
Sessions
Signing in creates a session and sets the ploy_session cookie. The session is checked against your auth database on every request, so signing out or revoking it takes effect immediately, unless you turn on the cookie cache.
- Session tokens are signed with your project's secret and stored only as SHA-256 hashes, so a leaked database does not leak usable sessions.
- The
ploy_sessioncookie isHttpOnly,SameSite=Lax, andSecureon HTTPS. - Signing out revokes the session server-side, not just the cookie. Changing or resetting a password signs out the user's other sessions.
Settings
Open Auth in the dashboard, select your project, and go to Settings → Sign-ups and sessions. Only organization owners and admins can change them.
| Setting | Default | Description |
|---|---|---|
| Session lifetime | 7 days | How long a session lasts after it was last extended, or after sign-in when sessions are not extended. 5 minutes to 90 days. |
| Extend active sessions | On | Extend a session to the full lifetime again when it is used. |
| Refresh interval | 24 hours | How long after the last extension a session is extended again. Must be shorter than the session lifetime. |
| Maximum session age | 400 days | Sign users out this long after sign-in, however active. At least the session lifetime, at most 400 days. |
| Session cookie cache | Off | Answer /_ploy/auth/me from a signed cookie for up to 10 minutes instead of reading the database. |
The same settings are available with ploy api auth update: --session-expiry, --session-update-age, --session-max-lifetime, and --session-cookie-cache, all in seconds. A refresh interval of 0 keeps sessions at a fixed expiry; a maximum age of none removes the optional lower cap, not the 400-day signing-token limit. The API and CLI allow idle lifetimes from 300 to 7,776,000 seconds and positive refresh intervals of at least 1 second, strictly shorter than that lifetime. A configured maximum age must be from 3,600 to 34,560,000 seconds and at least the idle lifetime. The dashboard uses fractional days for lifetimes and fractional hours for refresh intervals. When an API or CLI update shortens the idle lifetime without specifying a refresh interval, an interval that would reach or exceed the new lifetime is adjusted to half that lifetime (up to 24 hours). Explicit invalid intervals are rejected.
Extend active sessions
With Extend active sessions on, users who keep using your app stay signed in. When a session is used and it was last extended more than the refresh interval ago, Ploy Auth moves its expiry to the session lifetime from now and sends the ploy_session cookie again with the new lifetime.
With the defaults, a due renewal sets expiry to 7 days from that check. Daily session checks keep it alive until its signing token expires, at most 400 days after sign-in. Checks inside the 24-hour refresh interval do not move expiry, so the remaining time after the last check can be up to 24 hours shorter than the full 7-day lifetime. Expiry writes are throttled by the refresh interval rather than every request; overlapping requests may attempt the same renewal.
Sessions are extended whenever the session is checked:
- Browser requests to
/_ploy/auth/*, such as/mefrom the React components, renew the cookie directly. PLOY_AUTH.getUser()andverifyToken()extend the session in the database. They can't set cookies, so for apps that only read the session on the server, the Next.js middleware passes the renewed cookie on to the browser.- API clients that send
Authorization: Bearerkeep the same token; its session is extended in the database.
Turn Extend active sessions off to stop further extensions. New sessions end one session lifetime after sign-in; existing sessions retain the expiry they already reached.
Ploy Auth sets a ploy_session_fresh cookie next to ploy_session that expires when the session is next due for a refresh. Middleware uses it to avoid repeated /_ploy/auth/me checks until refresh is due. If older host-only cookies overlap a shared session, middleware synchronizes them even while a freshness marker is present.
Maximum session age
The maximum session age caps how long extending can keep a session alive. A user who signs in on Monday with a maximum age of 30 days must sign in again 30 days later, even if they used the app every day. Without a maximum age, sessions can be extended for up to 400 days.
Lowering the maximum age stops existing sessions from being extended past it, but does not shorten an expiry already stored in the database. Raising it cannot extend an existing signing token; sign in again to receive the longer limit.
Existing sessions
Sessions created before sliding sessions was enabled keep their original signing-token expiry, even if their database expiry is extended. They cannot gain the new 400-day limit without signing in again. Existing projects whose idle lifetime is 24 hours or less start with a refresh interval of half their idle lifetime, rather than the unusable 24-hour default. Local emulator settings are adjusted the same way. Changing the idle lifetime or refresh interval applies to subsequent database checks; it does not rewrite existing tokens or immediately revoke existing sessions.
With sessions across subdomains, refreshes preserve the token's signed cookie scope. Session, cache, and freshness cookies all use that scope. A host-only session remains host-only after sharing is enabled; sign in again to get a shared session. Disabling or changing a shared domain invalidates its signed sessions, including cached ones.
Session cookie cache
With the session cookie cache on, a successful /_ploy/auth/me sets a signed ploy_session_data cookie with the user for the cache duration. Until it expires, /me answers from that cookie without rereading the auth session or user rows, which makes frequent session checks from the browser cheaper and faster.
A cached session is not checked against the database until the cache expires. Signing out on another device, changing the password elsewhere, or revoking the session takes up to the cache duration to take effect for a browser holding the cache. Signing out in that browser clears its cache immediately. Keep the duration short. Reducing it does not shorten an already issued cache cookie; disabling the cache makes subsequent requests check the database.
The cache covers /_ploy/auth/me only. Shared-domain eligibility is still validated on every request, including cache hits; a revoked or changed domain does not get the cache's revocation grace period. Changing account data such as the password clears the cache in the browser that made the change. PLOY_AUTH.getUser(), verifyToken(), and every other endpoint always check the database. While a session is served from the cache it is not extended. The cache expires no later than the next refresh deadline or session expiry, so it cannot hide a due extension until the session has already expired.
How is this guide?
Last updated on
Emails, sign-in links and passwords
Verify users' email addresses, sign them in with a one-time email link or code, let them reset or change their password, customize the emails, and choose the address Ploy Auth sends from.
React components
Drop-in sign-in, sign-up, and account components for React with @meetploy/auth-react.