Session Idle Timeout and Access Token Interactions

I want to double check my understanding of how session idle timeout works.

Using the api.session.setIdleExpiresAt to expire in 15 minutes, my session is correctly terminated if the SPA app requests a new access token after 15 minutes.

However, from the user’s perspective, they have been busy interacting with the application using their access token that has a 1-hour lifespan. They would be surprised to learn they were logged out because they were inactive.

I can force interactions with the Auth Servier (Auth0) more frequently if I set the lifespan of the access token to 15 minutes, then the api.session.setIdleExpiresAt will run again presumably a few seconds before the expires time is reached and so the new token will be issued. But it is probably best to make the access token lifespan a safe age under 15 minutes.

For a 15 minute session idle time, does Auth0 recommend a 10 minute access token? This would ensure an active user would trigger an interaction with Auth0 before the 15 minute session expiration is reached. Is there concern that the traffic load on Auth0 would increase appreciably should a 10 minute access token become the norm?

Hi @ptidwell

Welcome back to the Auth0 Community!

You want to verify your understanding of how Auth0 session idle timeout works. You are using api.session.setIdleExpiresAt() to set a 15-minute session idle timeout, but your access token has a 1-hour lifespan. This creates a mismatch: users can continue using the application with a valid access token, but their Auth0 session expires after 15 minutes of inactivity, causing them to be logged out unexpectedly when they request a new token.

Auth0 recommends setting your access token lifetime to 10 minutes when using a 15-minute session idle timeout. This ensures active users trigger token refresh before the session expires. Short-lived access tokens (below 30 minutes) are standard practice, and the increased traffic from more frequent token refreshes is negligible.

Root Cause:

Session idle timeout and access token expiration are independent mechanisms:

  1. Session Idle Timeout β€” Tracks inactivity at the Auth0 Authorization Server level. The session expires if the user does not interact with Auth0's /authorize endpoint within the specified time (15 minutes in your case).
  2. Access Token Expiration β€” Tracks the validity of the token itself. Your application can use the token to call APIs until it expires (1 hour in your case).

The problem occurs because:

  • A user can be actively using your SPA with a valid 1-hour access token
  • But if they don't request a new token from Auth0 within 15 minutes, their Auth0 session expires
  • When the access token finally expires and the SPA tries to refresh it, Auth0 rejects the request because the session is no longer active
  • The user is forced to log in again, even though they were actively using the application

Solution:

Step 1: Align access token lifetime with session idle timeout

Set your access token lifetime to a value shorter than your session idle timeout. Auth0 recommends:

  • Session Idle Timeout: 15 minutes
  • Access Token Lifetime: 10 minutes

This ensures that active users will request a new token before the session expires, automatically extending the session.

Configure in Auth0 Dashboard:

  1. Navigate to Applications β†’ Your Application β†’ Settings
  2. Scroll to Token Expiration (Seconds)
  3. Set to 600 seconds (10 minutes)

Step 2: Understand the interaction between tokens and session

When your SPA requests a new access token via getAccessTokenSilently() (or similar), it makes a request to the /authorize endpoint. This request:

  • Extends the session idle timeout β€” The 15-minute inactivity timer resets
  • Issues a new access token β€” Valid for 10 minutes
  • Preserves user experience β€” The user is not prompted to log in again

Step 3: Verify your SPA is configured for token refresh

Ensure your SPA SDK is configured to refresh tokens automatically:

React SDK example:

import { Auth0Provider } from "@auth0/auth0-react";

<Auth0Provider
  domain="your-tenant.auth0.com"
  clientId="your-client-id"
  redirectUri={window.location.origin}
  useRefreshTokens={true}  // Enable refresh tokens
  cacheLocation="localstorage"  // Persist tokens
>
  <App />
</Auth0Provider>

Step 4: Verify tenant session settings

Navigate to Auth0 Dashboard β†’ Settings β†’ General.

Verify:

  • Inactivity Timeout: 15 minutes (or your desired idle timeout)
  • Require login after: Set to an appropriate value (e.g., 7 days for maximum session duration)

Step 5: Test the flow

  1. User logs in β€” Access token issued (valid 10 minutes), session created (idle timeout 15 minutes)
  2. User actively uses app β€” At ~9 minutes, SPA automatically refreshes token via getAccessTokenSilently()
  3. Token refresh succeeds β€” New 10-minute token issued, session idle timer resets to 15 minutes
  4. User remains logged in β€” No unexpected logout

Why 10 Minutes for a 15-Minute Timeout?

The 5-minute buffer ensures:

  1. Token refresh happens before session expiration β€” Even if there's a slight delay in the refresh request, the session will still be active
  2. Active users never hit the idle timeout β€” Continuous activity keeps both the token and session fresh
  3. Inactive users are properly logged out β€” If a user stops interacting, the session expires after 15 minutes of true inactivity

Traffic Impact: Negligible

Auth0 confirms that short-lived access tokens (below 30 minutes) are standard practice. The increased traffic from more frequent token refreshes is:

  • Expected by the platform β€” Auth0's infrastructure is designed for this pattern
  • Negligible in impact β€” Token refresh requests are lightweight and cached by the SDK
  • Worth the security and UX benefits β€” Short-lived tokens reduce the window of exposure if a token is compromised

Important Clarification: Refresh Tokens vs. Session Interaction

A critical distinction:

  • Refresh token exchanges do NOT extend the session idle timeout β€” Calling /oauth/token to exchange a refresh token for a new access token does not reset the 15-minute inactivity timer
  • Only /authorize requests extend the session β€” Silent authentication (via getAccessTokenSilently()) calls /authorize with prompt=none, which DOES reset the idle timeout

This is why configuring your SPA to use getAccessTokenSilently() (which calls /authorize) is essential, not just relying on refresh token exchanges.

Kind Regards,
Nik

Nik, thanks for confirming my understanding and providing reassurance that our approach is the correct one.