Next-Gen App & Browser Testing Cloud
Trusted by 2 Mn+ QAs & Devs to accelerate their release cycles

Appium tests run slow or time out mainly because of inefficient locators (deep XPath), excessive implicit and explicit waits, session startup overhead, underpowered emulators, network latency, and an untuned newCommandTimeout — and every one of these is fixable. The biggest wins come from replacing XPath with accessibility id or id locators, swapping hard-coded sleeps for explicit WebDriverWait, tuning your capabilities, and running on real hardware instead of a slow local emulator.
Below we walk through each cause and its concrete fix, with short Appium code you can copy into your existing suite.
Appium is a client-server tool. Your test sends each command over HTTP to the Appium server, which forwards it to a platform automation engine (UiAutomator2 on Android, XCUITest on iOS) running on the device. Every interaction therefore crosses several layers, and slowness can creep in at any of them. Understanding where the time goes is the first step to fixing it.
The most common contributors to slow or timing-out Appium tests are:
XPath is the single biggest performance killer in Appium. Unlike on the web, mobile automation engines do not have a native XPath query engine, so Appium serializes the full UI hierarchy to XML and evaluates the expression against it — on every lookup. A complex, deeply nested XPath on a busy screen can take several seconds by itself.
The fix is to prefer fast, indexed locator strategies in this order: accessibility id (cross-platform and the fastest portable option), then id / resource-id on Android, then platform-native selectors such as UiSelector or iOS predicate/class-chain. Reserve XPath for the rare cases where nothing else can target the element.
// SLOW — deep XPath walks the whole UI tree on every call
driver.findElement(By.xpath("//android.widget.LinearLayout/android.widget.FrameLayout[2]//android.widget.Button"));
// FAST — accessibility id is portable and indexed
driver.findElement(AppiumBy.accessibilityId("loginButton"));
// FAST — resource-id on Android
driver.findElement(AppiumBy.id("com.example.app:id/login_button"));
// FAST — native Android UiSelector
driver.findElement(AppiumBy.androidUIAutomator(
"new UiSelector().resourceId(\"com.example.app:id/login_button\")"));Ask your developers to add stable accessibility labels and resource IDs to interactive elements. It is the most durable performance and reliability improvement you can make, and it also makes locators far less brittle than position-based XPath.
Two anti-patterns dominate slow suites: scattered Thread.sleep() calls and a large global implicit wait. A Thread.sleep(5000) always burns five full seconds even if the element appears in 200ms. A large implicit wait silently slows every findElement, and when it overlaps with an explicit wait the two can stack into long, unpredictable pauses.
Replace both with targeted explicit waits using WebDriverWait and ExpectedConditions. An explicit wait polls for a specific condition and returns the instant it is met, so you wait exactly as long as needed and no longer. Keep the implicit wait small (a couple of seconds) or zero to avoid stacking.
// AVOID — fixed dead time on every run
Thread.sleep(5000);
driver.findElement(AppiumBy.accessibilityId("submit")).click();
// PREFER — explicit wait returns the moment the element is ready
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
WebElement submit = wait.until(
ExpectedConditions.elementToBeClickable(AppiumBy.accessibilityId("submit")));
submit.click();
// Keep the implicit wait small so it does not stack with explicit waits
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(2));As a rule, never mix a large implicit wait with explicit waits, and remove every Thread.sleep() you can. This one change often cuts double-digit percentages off total run time. For syntax and patterns, see our deep dive on Selenium WebDriverWait, which uses the same wait model Appium inherits from WebDriver.
One wait anti-pattern deserves special attention: asserting that an element is absent. A check like "verify element is NOT present" cannot short-circuit — Appium has to wait out the full timeout on every such assertion before it can conclude the element is gone. If you must verify absence, drop the timeout to a low value first with a short scoped wait (for example ExpectedConditions.invisibilityOfElementLocated), then restore it, so a single negative check does not silently add seconds to every run.
A surprising amount of time is lost before your first assertion even runs. Creating a session boots the automation engine and reinstalls the app, which can take 30–60 seconds each time. Timeouts here often surface as a session creation timeout or as the session dying mid-test. Tune these capabilities to fix both:
UiAutomator2Options options = new UiAutomator2Options();
options.setPlatformName("Android");
options.setDeviceName("Pixel_7");
options.setApp("/path/to/app.apk");
// Performance and stability tuning
options.setNewCommandTimeout(Duration.ofSeconds(120)); // longer flows won't time out
options.setNoReset(true); // keep app state, skip reinstall
options.setFullReset(false); // avoid slow uninstall/reinstall
options.setAutoGrantPermissions(true);
AppiumDriver driver = new AndroidDriver(
new URL("http://127.0.0.1:4723"), options);If you only need login once, log in in a setup step and reuse the session across tests instead of recreating it. Combining noReset with session reuse removes most of the repeated startup cost that makes a suite feel sluggish.
Even with perfect locators and waits, the hardware underneath sets a hard floor on speed. Local emulators render the UI in software on your CPU, so animations, scrolling, and screenshots are noticeably slower than on real hardware. An underpowered laptop running an emulator plus the Appium server plus your IDE will choke under the load.
Two levers help here:
If you cannot scale real hardware locally, a real device cloud removes the local boot and resource bottleneck entirely. For more on this trade-off, see how real device testing improves reliability versus emulators and simulators.
Locator and wait fixes shrink the time per test, but the next big lever is running tests in parallel on fast, well-maintained hardware. That is hard to do locally — you would need a rack of devices, all kept charged, updated, and booted. A cloud removes that burden and lets a suite that took an hour serially finish in minutes by fanning out across many devices at once.
With TestMu AI, you can run the same Appium tests across 3000+ real browsers and devices on a real device cloud, with no local emulator overhead and built-in parallelization. Because the devices are real hardware sitting close to the grid, you avoid the software-rendering slowdown and high local network latency that drag down emulator runs. Pair it with mobile app testing and automation testing to scale coverage without slowing your pipeline.
// Point your existing Appium test at the real device cloud
MutableCapabilities caps = new MutableCapabilities();
caps.setCapability("platformName", "Android");
caps.setCapability("deviceName", "Galaxy S23");
caps.setCapability("platformVersion", "14");
caps.setCapability("app", "lt://APP_ID"); // app uploaded to the cloud
MutableCapabilities ltOptions = new MutableCapabilities();
ltOptions.setCapability("newCommandTimeout", 120);
ltOptions.setCapability("isRealMobile", true);
caps.setCapability("lt:options", ltOptions);
AppiumDriver driver = new AndroidDriver(
new URL("https://USERNAME:[email protected]/wd/hub"), caps);
// The same accessibility-id locators and explicit waits now run on real devicesFor a wider view of how platforms handle this, see how leading automation testing platforms handle mobile app testing.
Slow and timing-out Appium tests are almost never a single mysterious problem — they are the sum of fixable inefficiencies. Profile first to find where the time goes, then attack the big four: replace XPath with accessibility id and id locators, swap sleeps and large implicit waits for explicit WebDriverWait, tune newCommandTimeout with noReset and fullReset, and move off slow emulators onto real, parallelized hardware. Apply these in order and a suite that crawled and timed out becomes fast and reliable.
The most common causes are deep XPath locators, hard-coded Thread.sleep() calls, large implicit waits, session creation overhead, and underpowered emulators. Switching to accessibility id or id locators and replacing sleeps with explicit WebDriverWait usually gives the biggest single speed gain.
newCommandTimeout is the number of seconds Appium waits for a new command before assuming the client is gone and ending the session. The default is 60 seconds. If a long step exceeds it, the session is killed; raise it for slow flows or set it to 0 to disable the timeout while debugging.
Prefer explicit waits with WebDriverWait and ExpectedConditions. Large implicit waits silently slow every findElement call and can stack with explicit waits, causing long unpredictable pauses. Use a small or zero implicit wait and target specific conditions with explicit waits.
Session creation timeouts usually mean the emulator or device was not booted in time, the app failed to install, or capabilities such as appPackage and appActivity are wrong. Boot the emulator first, increase newCommandTimeout or the server timeout, and verify the app path and capabilities.
Real devices typically run app interactions faster and more accurately than emulators because they use real hardware and GPUs rather than virtualized CPU rendering. A real device cloud also removes local boot overhead and lets you run many sessions in parallel for faster overall suite execution.
Profile to find the slow steps, then replace XPath with accessibility id or resource-id locators, swap Thread.sleep and large implicit waits for targeted explicit waits, set noReset true with fullReset false to skip reinstalls, avoid element-not-present checks with long timeouts, and run in parallel on real devices instead of local emulators.
Appium wraps the native engines (UiAutomator2/XCUITest) behind an HTTP WebDriver layer, so every command is a network round trip rather than an in-process call. That overhead makes Appium several times slower than native frameworks like Espresso or XCUITest, but the trade-off buys cross-platform, multi-language tests, and most of the gap is recoverable with tuning.
KaneAI - Testing Assistant
World’s first AI-Native E2E testing agent.

TestMu AI forEnterprise
Get access to solutions built on Enterprise
grade security, privacy, & compliance