Hero Background

Next-Gen App & Browser Testing Cloud

Trusted by 2 Mn+ QAs & Devs to accelerate their release cycles

Next-Gen App & Browser Testing Cloud

Why Are Appium Tests Running Slow or Timing Out?

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.

Why Appium Tests Get Slow

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:

  • Inefficient locators — deep or relative XPath forces the engine to walk the entire UI tree, which is expensive on every findElement.
  • Bad wait strategy — hard-coded Thread.sleep() and large implicit waits add fixed dead time and stack unpredictably.
  • Session startup overhead — installing the app and booting the automation engine on every test wastes minutes across a suite.
  • Underpowered emulators — software-rendered emulators are far slower than real hardware, especially for animations and scrolling.
  • Network latency — a slow link between client, server, and device adds round-trip time to every single command.
  • Untuned newCommandTimeout — when a step takes longer than this value, Appium ends the session and you see a timeout error.

Cause and Fix 1 - Slow Locators

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.

Cause and Fix 2 - Wait Strategy

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.

Cause and Fix 3 - Session and Capabilities Tuning

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:

  • newCommandTimeout — seconds Appium waits for a new command before ending the session (default 60). Raise it for long flows, or set 0 to disable while debugging.
  • noReset: true — skips reinstalling and clearing app data between sessions, saving large startup time when a fresh state is not required.
  • fullReset: false — avoids the slow uninstall/reinstall cycle; only enable full reset when you genuinely need a clean install.
  • autoLaunch: true — lets Appium install and launch the app at session start; set it false when you want to control launch timing yourself.
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.

Cause and Fix 4 - Emulator vs Real Device and Network

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:

  • Give the emulator more resources — allocate adequate RAM and CPU cores, enable hardware/GPU acceleration (HAXM, KVM, or Hyper-V), and use an x86/ARM image that matches your host architecture so it is not emulating instructions in software.
  • Cut network round trips — keep the Appium server close to the device, avoid VPN hops, and remember that every command is an HTTP round trip, so a high-latency link multiplies across hundreds of steps.
  • Prefer real devices for critical paths — real hardware uses the actual GPU and sensors, so interactions run at production speed and surface real-world performance issues an emulator hides.

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.

Common Mistakes and Troubleshooting

  • Timeout on findElement — usually a slow XPath or an element that is not yet rendered. Switch to accessibility id and wrap the lookup in an explicit WebDriverWait for presenceOfElementLocated.
  • Session creation timeout — the emulator or device was not booted in time, the app failed to install, or appPackage/appActivity are wrong. Boot the device first, raise newCommandTimeout, and verify the app path and capabilities.
  • Stale or dead sessions — the session ended because a step exceeded newCommandTimeout. Increase the value for long flows, or keep the session active and avoid unbounded sleeps.
  • Implicit + explicit waits stacking — long, inconsistent pauses point to a large implicit wait colliding with explicit waits. Set the implicit wait to a small value or zero.
  • Reinstalling the app every testfullReset left on, or noReset off. Enable noReset and disable fullReset unless a clean install is genuinely required.

Real Device Cloud for Speed and Scale

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 devices

For a wider view of how platforms handle this, see how leading automation testing platforms handle mobile app testing.

Conclusion

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.

Frequently Asked Questions

Why are my Appium tests so slow?

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.

What is newCommandTimeout in Appium?

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.

Should I use implicit or explicit waits in Appium?

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.

Why does Appium throw a session creation timeout?

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.

Are real devices faster than emulators for Appium?

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.

How can I make my Appium tests run faster?

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.

Why is Appium slower than Espresso or XCUITest?

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.

Related Questions

Test Your Website on 3000+ Browsers

Get 100 minutes of automation test minutes FREE!!

Test Now...

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

  • Advanced access controls
  • Advanced data retention rules
  • Advanced Local Testing
  • Premium Support options
  • Early access to beta features
  • Private Slack Channel
  • Unlimited Manual Accessibility DevTools Tests