Sitemap

Oracle APEX — Increase Session Timeout (and Fix “Your Session Has Ended”)

Where the three timeout settings live on APEX 26.2, which one wins, the 24-hour ceiling where the forums say 12, what the warning dialog actually does, and the three other reasons a user sees “Your session has ended”. Every number here was read back from the APEX views.

--

How this was made: I wrote this with Claude Code. A Claude Code session on my Mac set every value in this post on a throwaway APEX 26.2 database, logged in to a sample app through scripted browsers, let the sessions expire, and read the results from the APEX views and the activity log. I made the calls; the test passwords were generated into a locked folder and never typed into the chat.

Press enter or click to view image in full size
Image generated by Gemini.

Someone types “oracle apex session timeout” into Google and gets Oracle’s documentation for the settings, then fifteen forum threads from APEX 3.2 to 24.2, most of them unresolved. A timeout that silently stops at 12 hours. Users thrown out while they are typing. A warning dialog that shows up at the moment the session dies.

I ran all of it on a fresh APEX 26.2 instance behind ORDS 26.3. Some of the old complaints are still true, some changed shape, and one of them is now a different number. This is what the engine does today, read from its own tables.

The short version

  • Three places set the timeout: instance, workspace, application. The application wins, then the workspace, then the instance. Defaults on a fresh 26.2: 8 hours of session length, 1 hour idle, a warning 3 minutes before the end.
  • Idle time is capped at 24 hours (86,400 seconds) at the instance, the workspace and the application. Anything higher is stored as you typed it and applied as 86,400. The 12-hour cap from the forum threads did not reproduce. The per-session API in Step 5 gets past it, but only to 99,999 seconds, under 28 hours.
  • Session length showed no cap in my tests: 7 days applied as 7 days, a year through the API. A value of 0 means 10 years.
  • The idle warning dialog only appears when the warning is shorter than the idle time; set it longer and there is no warning at all, just the ended page on the next click. The warning the forums saw “after the session had already ended” is the browser’s own Session Ended dialog, which is what the warning turns into when nobody clicks Extend.
  • APEX_UTIL.SET_SESSION_MAX_IDLE_SECONDS can lengthen a session's idle time but, in my tests, never shortened it. SET_SESSION_LIFETIME_SECONDS goes both ways.
  • Three other things put the same “ended” page, a login page or a page you forgot you configured in front of the user: the session length, a second login in the same browser, and a session timeout URL you set and forgot. The purge job is not one of them.

What you need

APEX 26.2 (the numbers may differ on other versions, and the 12-hour cap may have been real on older ones), a workspace developer login, and for the instance-level setting an Administration Services login. To read things back I used a SYSDBA connection; a user granted APEX_ADMINISTRATOR_READ_ROLE should see APEX_WORKSPACE_SESSIONS for every workspace, which is where every timeout in this post was checked.

Step 1: Find the three settings

Application. App Builder → your app → Shared Components → Security Attributes → Session Management. Two fields do the work: Maximum Session Length in Seconds and Maximum Session Idle Time in Seconds. Both are blank on a new app, and the help text under each tells you what blank currently means.

Press enter or click to view image in full size
The Session Management section of an APEX application’s security attributes, with the session length and idle time fields empty and help text showing the inherited values of 28800 and 3600 seconds.
The application level. Blank means the workspace or instance value applies, and the Builder tells you which number that is right now.

Workspace. Administration Services → Manage Workspaces → Existing Workspaces → the workspace → the Session Timeout section. Same two fields plus the warning. Blank by default.

Instance. Administration Services → Manage Instance → Security → Session Timeout. On a fresh 26.2 install this holds the only non-blank values: 28,800 seconds of session length, 3,600 seconds idle, and a 180-second warning.

Press enter or click to view image in full size
The Session Timeout section of APEX instance security settings showing Maximum Session Length 28800, Maximum Session Idle Time 3600 and Session Timeout Warning 180.
The instance level on a fresh 26.2 install: 8 hours, 1 hour, 3 minutes.

You can read the length and idle values at all three levels from SQL, which is faster than three browser tabs. The instance warning is not in APEX_INSTANCE_PARAMETERS; the other two levels expose theirs.

select name, value
from apex_instance_parameters
where name in ('MAX_SESSION_LENGTH_SEC', 'MAX_SESSION_IDLE_SEC');

select workspace, maximum_session_life_seconds, maximum_session_idle_seconds,
session_timeout_warn_seconds
from apex_workspaces;

select application_id, maximum_session_life_seconds, maximum_session_idle_seconds,
session_timeout_warn_seconds, session_idle_time_exceeded_url
from apex_applications
where application_id = 100;

Which one wins. Head to head: with the workspace at 1,800 idle and the instance dropped to 900, a new session got 1,800; with the workspace cleared, 900; with the application at 120 and the workspace back at 1,800, 120; and after changing the application to 90, 90 on the very next login. Application beats workspace beats instance, and a change in the Builder applies to the next session created, with no cache to wait out.

The row that tells you what a session actually got:

select apex_session_id, user_name, session_created,
session_max_idle_sec,
round((session_idle_timeout_on - session_created) * 86400) as idle_sec,
round((session_life_timeout_on - session_created) * 86400) as life_sec
from apex_workspace_sessions
where user_name = 'TUTOR'
order by session_created desc;

Step 2: Make it fail on purpose

Set the application’s idle time to 60 seconds, log in to the app, do nothing for 70 seconds, click a menu entry. The page that comes back is the one your users are reporting.

Press enter or click to view image in full size
An APEX error page with a red stop icon and the text Your session has ended. Sign In again to create a new session, with an OK button.
Idle 60 seconds, clicked at 71. The page behind it never loaded.

What the engine recorded, from APEX_WORKSPACE_ACTIVITY_LOG: the home page after login at 11:21:17, then one row at 11:22:28 for the Products page with ERROR_MESSAGE = "Your session has ended." That column tells you whether the engine ended the session (the idle clock, the session length and the timeout URLs all log the same text) or whether something else happened: the second-login case in Step 6 logs no error row at all. The error number behind the message, if you see it in a trace, is ORA-20987.

select view_timestamp, apex_session_id, page_id, page_name, error_message
from apex_workspace_activity_log
where application_id = 100
and error_message is not null
order by view_timestamp desc;

What is left behind: the session was gone from APEX_WORKSPACE_SESSIONS right after the failing click, because the engine decides at request time by comparing the clock to SESSION_IDLE_TIMEOUT_ON and clears the row itself. An expired session that nobody touches stays in the view with that column in the past. The hourly purge job (ORACLE_APEX_PURGE_HOURLY), run by hand, left both a live and an expired session alone, so disabling it, which two of the forum threads tried, cannot help.

Step 3: Raise it, and the ceiling you will hit

To lengthen one application’s sessions, set the two fields in Step 1 at the application. To lengthen everything, set them at the instance and leave the applications blank. Both took effect on the next session created in my tests.

Get syan zen’s stories in your inbox

Join Medium for free to get updates from this writer.

The forum threads from APEX 5.0.4 and 20.2 report that values above 43,200 seconds (12 hours) are stored but ignored. On 26.2 I set the instance, then the workspace, then the application, and read back what each new session got.

  • 43,200 (12 hours) for both, at the instance: idle 43,200, length 43,200.
  • 86,400 (24 hours) for both, at the instance: idle 86,400, length 86,400.
  • 172,800 (48 hours) for both, at the instance: idle 86,400, length 172,800.
  • 172,800 for both, at the workspace: idle 86,400, length 172,800.
  • 172,800 idle, at the application: idle 86,400.
  • 86,401 idle with 604,800 (7 days) length, at the instance: idle 86,400, length 604,800.
  • 0 for both, at the instance: idle 3,600 (the default, not unlimited), length 315,360,000 (10 years).

So the ceiling exists, and it is 24 hours, not 12, and it applies to idle time only. Session length will take a week. A 0 for session length means ten years, which matches the “0 means indefinitely” line in the instance documentation, but a 0 for idle time does not mean unlimited: the session got the 3,600-second default.

The practical reading: if your users’ complaint is “I came back the next morning and had to log in again”, that is the idle time, and 24 hours is as far as any of the three settings will push it. The per-session call in Step 5 adds under four hours on top; anything longer needs a different design (persistent authentication, which is a separate switch at the instance and a separate conversation).

Step 4: The warning dialog

Session Timeout Warning in Seconds says how long before the idle deadline the user gets a dialog. With the application at 120 idle and 60 warning, it was not there at 30 seconds and was there at 65. The dialog names the deadline itself: 7:32:59 PM, local time, the session’s idle timeout.

Press enter or click to view image in full size
An APEX dialog over the Brookstrut sample app home page reading Your session will end at 7:32:59 PM. Would you like to extend it? with Cancel and Extend buttons.
Idle 120, warning 60. Extend makes a request, which is all an idle timer needs.

Extend made one request to the server and moved the session’s SESSION_IDLE_TIMEOUT_ON a full 120 seconds from the click, not from the original login. Left to run out, the dialog changed to one titled “Session Ended”, with Cancel and Sign In Again. That one is drawn by the browser from the timers it holds, and it is the dialog the forum threads call a warning that came too late; the server page in Step 2 is what you get when no warning was running.

Then the case from the forums. With the warning set longer than the idle time (120 warning, 60 idle) there was no warning and no Session Ended dialog, just a page that would get the Step 2 response on its next click. A blank warning on a 120-second idle gave no dialog either, whether because the instance’s 180 was inherited and could not fit, or because blank means none. An application with a short idle time needs its own warning value, shorter than the idle time.

The session-length warning in Step 6 behaves differently and still came for a 60-second length. The forum report of a late warning at 7,200 seconds idle I did not test; in every run here the idle dialog either came on time or never came.

Step 5: A longer session for one user, from PL/SQL

APEX_UTIL.SET_SESSION_MAX_IDLE_SECONDS and APEX_UTIL.SET_SESSION_LIFETIME_SECONDS change the current session only, so you can give a long-running data-entry page, or an administrator, more time without touching the application setting. Run from a page process or an application process:

begin
apex_util.set_session_max_idle_seconds(p_seconds => 14400, p_scope => 'SESSION');
apex_util.set_session_lifetime_seconds(p_seconds => 43200);
end;

What the session table showed, a fresh session at the 3,600 / 28,800 defaults for each call:

  • Idle 1,800, 3,599 or 3,601: the row stayed at 3,600. The call did not lower the idle time, and did not nudge it by a second either.
  • Idle 43,200: applied. 86,401: applied as 86,401, so the 24-hour ceiling from Step 3 is enforced when a session is created, not by this call.
  • Idle 99,999: applied. 100,000: ORA-06502: number precision too large. Something in the call is declared with five digits.
  • Lifetime 30 seconds: applied. 31,536,000 (one year): applied. The lifetime call goes both ways.

Step 6: The other three reasons it says “ended”

Two of these end a session with the idle time nowhere near expiry; the third is the same two clocks wearing a different face.

Session length. The session-length clock does not reset on activity. I set the application length to 60 seconds with the warning blank and clicked roughly every 25 seconds. By 32 seconds a dialog titled “Session Expiry Warning” sat over the page: “Your session will end at 7:41:53 PM and cannot be extended”. The page still worked behind it at 33 seconds. The click at 59 seconds got the Step 2 page, and the activity log has “Your session has ended.” at 63 seconds after the session was created. If users report being thrown out while working, check the length before the idle time.

A second login in the same browser. Log in to the app in one tab, open the app’s URL in a second tab and log in again there: the first tab’s next click lands on the login page with a brand-new session id, and then the second tab’s does the same. The activity log shows no error row for either; the engine saw a request whose session did not match the cookie and quietly started over. One browser, one application, one session.

A session timeout URL. Session Idle Timeout URL on the same Builder page redirects instead of showing the Step 2 page. With it set to an external page and idle at 60, the click after expiry went straight to that page, no message, no Sign In link. Session Timeout URL next to it does the same for the session length. The browser still draws its own Session Ended dialog first, since those timers run in the page; the URL only replaces what the server sends back. If a user reports “it dumped me on some other page”, look here before the timeouts.

Not tested here, because one container cannot simulate it: a load balancer without sticky sessions in front of several ORDS instances. The forum threads that blame it are plausible and I have no evidence either way.

What to keep

The setting that ends most support tickets is the application’s Maximum Session Idle Time, raised to the longest gap a real user has between two clicks on that app, with the warning set to a minute or two so Extend gets a chance. The instance setting is the default for every app that says nothing, and 24 hours is the top of what the idle settings will do.

Session length is a security setting and should be set once, at the application, with the reason written in the application’s comments, and not nudged upward each time someone complains. That is the rule I keep for every security attribute, and it is one of the decisions in the book below.

Two other APEX posts of mine run against the same throwaway database: Oracle APEX — Connect Claude Code to Your Database with the SQLcl MCP Server and Oracle APEX — Export and Import an App from the Command Line with SQLcl 26.3.

This article shows the settings. The decisions behind APEX, one standard, one decision rule and one gotcha for every layer, are in Opinionated APEX: $19, or $17 for Medium readers through that link.

--

--