In Appium, what does `appium:newCommandTimeout` do to an idle session?
answer
- silence between commands, not element waiting
- measured in seconds, core capability
- any command restarts the countdown
- server ends the session, never waits
basics
~20 sappium:newCommandTimeout is a silence timer, not a wait. If the Appium server receives no command on a session for that many seconds, it ends the session, so the next command arrives at a session that no longer exists.
solid answer
~40 s`appium:newCommandTimeout` sets, in seconds, how long the Appium server will tolerate silence on a session. It is a core capability declared by the base driver, so the Android drivers and the XCUITest driver all honour it, and every command the client sends to that session restarts the countdown. When the countdown reaches zero the server does not wait for the app and does not retry anything: it shuts the session down the same way `DELETE /session/:sessionId` would. The next command then fails because that session is gone, which in a report reads like an unrelated element failure. It is the one Appium timer that punishes a *test* for being slow rather than an *app*, so its value has to cover the longest legitimate gap between two commands in the suite.
code
json · 11 lines{
"capabilities": {
"alwaysMatch": {
"platformName": "Android",
"appium:automationName": "UiAutomator2",
"appium:appPackage": "com.example.rooftopsolar",
"appium:newCommandTimeout": 300
},
"firstMatch": [{}]
}
}go deeper
Be ready to say what the number measures, which is seconds of silence between commands, and that the server ends the session instead of waiting when it runs out.
Explain that the countdown lives in Appium's core base driver, restarts on every command sent to that session, and is completely blind to what the device or the app is doing.
Show how you spot the symptom in a report: one long quiet step, then every later step failing on the session rather than an element, and how you size the value against the suite's real gaps.
Own the fleet trade-off. A generous idle timeout protects legitimate long pauses but lets a wedged run sit on a device much longer, so pair it with an outer run-level cap.
## What the timer measures `appium:newCommandTimeout` is a **session-idle timer**, and the thing it measures is silence. Its value is a number of **seconds**: how long the Appium server will keep a session open while the client sends it nothing. It is not a wait for an element, not a wait for a page, and not a wait for the screen to settle — no part of it looks at the device at all. It is declared by Appium's own base driver rather than by any one platform driver, which is why its behaviour is uniform. A session driven on Android by the UiAutomator2 driver and a session driven on an Apple device by the XCUITest driver get the same countdown from the same code, and neither driver has to implement it. It is not one of the W3C standard capability names, so it travels with the vendor prefix — `appium:newCommandTimeout` — inside `alwaysMatch` on the `POST /session` request, or nested under `appium:options`. ## What restarts the countdown, and what does not The countdown restarts whenever the server receives a command **for that session**. It does not matter which command, and it does not matter whether the command succeeds. | During a quiet stretch | Restarts the countdown? | |---|---| | Any WebDriver command sent on that session | Yes | | A find that fails, or an assertion that fails | Yes — a request still arrived | | The app under test working in the background | No | | An animation still running on screen | No | | The test polling a backend, or waiting on a person | No | The rule behind the table is that the timer hears HTTP, not the phone. Anything the test does that produces no request against that session id is, from the server's point of view, indistinguishable from a test process that has died. ## What happens when it fires - The server ends the session, down the same shutdown path a `DELETE /session/:sessionId` takes. - The driver runs its normal teardown, so the device is handed back rather than held. - Nothing is retried and nothing is re-sent; the timer is not a recovery mechanism. - No error reaches the test at the moment it happens, because the test is not asking the server anything and there is nowhere to deliver one. - The failure surfaces on the **next** command, which names a session the server no longer knows. - Every remaining step in that test then fails the same way, because they all address the same dead session. Those last two points are the practical signature. A run killed by the idle timer does not look like a timing bug in one step; it looks like one long quiet step followed by a cliff, with the rest of the test failing on the session rather than on any element. ## Choosing a value - Size it from the longest legitimate **gap between two commands**, not from the longest test. A twenty-minute test that never goes quiet for more than a few seconds needs nothing generous. - Remember the unit is seconds. Most other numbers handed to Appium are milliseconds, and this one is not. - Count the gaps the framework creates as well as the ones the test writes: setup that talks to a backend, a fixture that seeds data, a breakpoint on a developer's machine. - Treat a very large value as a trade rather than a free win. The timer is also what reclaims a device when a run wedges with a session still open, so the more silence you tolerate, the longer a stuck run keeps its hardware. ## Where it sits among the session's other timing knobs An Appium session also carries the W3C timeout set — `script`, `pageLoad` and `implicit` — which can be set when the session starts or changed later through `POST /session/:sessionId/timeouts`. Those govern how long a single command may run or keep looking, and when one expires the result is a failed command and a session that is still perfectly usable. `appium:newCommandTimeout` is the odd one out on both counts: it is the only one that measures the **client's** behaviour rather than the app's, and the only one whose expiry destroys the session instead of failing a command. That is why it is worth knowing as a distinct mechanism rather than as one more number in a capability map. Every other timer in the session answers *how long do I keep trying?*; this one answers *how long do I stay?*
- Does anything happening on the device itself reset an Appium session's idle timer?No. The timer counts silence on the session, not device activity. A long animation, an app crunching a quote in the background, or a person staring at the screen all leave the server with nothing to hear, so the countdown keeps running. Only a command sent on that session — any command, successful or not — restarts it.
- If a session dies from its idle timeout, what does the next command look like to the test?It fails on the session, not on the element. The server has already torn the session down, so the next request names a session id that no longer exists and comes back as a session-not-found failure rather than a find failure. The give-away is that every remaining step fails identically and the server log shows the shutdown happening during the quiet period.
It is the receptionist who ends a call that has gone quiet. The line is not busy, it is silent, and after a set number of seconds the desk closes it.
saying these in an interview costs you the question
- Thinks newCommandTimeout is how long Appium waits for an element to appear
- Believes device or app activity keeps the session alive during a quiet stretch
- Reads the resulting failure as a flaky locator instead of a dead session
- Assumes the value is in milliseconds like most other Appium timeouts
- Sets one value suite-wide without checking the longest legitimate gap