Pravinraj Vincent, UiPath Solutions Engineer
Who this is for
This paper is for platform leads, solution architects and COE owners who already run unattended robots in production. It isn't a build guide. It covers the decisions above individual workflows: machines and folders, runtime capacity, where retries live, what you measure, and how changes reach production.
Every product behavior below is taken from UiPath documentation, linked inline. Where I give an opinion, I mark it as my recommendation and say which facts it rests on.
Thesis
Most unattended failures I see on the forum aren't bugs in the business logic. They come from the platform around it: a session that can't be created after patching, a browser policy pushed by another team, a runtime pool sized for the average day, a retry policy that counts the same invoice twice. Reliability at scale is mostly an operating model problem. The platform team's job is to name the failure domains, give each an owner, and design so a failure in one domain stays there.
The failure domains
| Domain | What breaks | Documented example |
|---|---|---|
| Windows session | The robot can't log on or can't reach the desktop | Logon policies such as "Display information about previous logons during user logon" block session creation with error 0x80070520 (session troubleshooting) |
| Host configuration | Same package behaves differently per machine | Resolution and scaling differ between an RDP session and a local one (execution troubleshooting) |
| Browser policy | Extension or selectors stop working after a policy change |
ProcessIsolationEnabled affects selectors outside the HTML content; DeveloperToolsAvailability settings limit the extension (Chrome group policies) |
| Office dependency | Excel steps fail where Excel isn't installed or set up | Modern and classic Excel activities need Excel installed; Workbook activities don't (Excel package) |
| Capacity | Jobs sit in Pending | Runtimes are drawn from the tenant pool per connected host (unattended concepts) |
| Work distribution | Items processed late, twice, or never | Queue trigger scheduling can over- or under-schedule depending on a tenant setting (queue triggers) |
| Change | A new version breaks production | Pending jobs pick up an edited process version, running jobs don't (managing processes) |
My recommendation: give each row a named owner. The session and browser rows usually belong to the desktop or VDI team, not the RPA team, and the fastest fix is a shared change calendar with them.
Machine and folder strategy
Machine templates are UiPath's recommended machine type for unattended work. One template lets many hosts connect with a single key or client credential pair, regardless of hostname (unattended concepts). The docs attach conditions to that: hosts under one template should share the same applications, installed at the same paths and versions, and every robot account in a folder needs a matching account on every machine in that template, because Orchestrator can start a job on any valid account and machine pair.
That turns template design into a blast-radius decision.
| Option | Choose it when | Trade-off |
|---|---|---|
| One broad template for a pool | Hosts are built from one image and all processes need the same apps | Simplest capacity math; one bad image change affects every process on the pool |
| Templates split by application stack (for example SAP hosts vs browser-only hosts) | Processes need different software or different access rights | Smaller blast radius; runtimes are split across pools, so idle capacity in one can't help another |
| Templates split by environment (non-production vs production) | You want image changes to land somewhere safe first | Needs a second set of hosts; gives you a natural canary |
UiPath also recommends non-persistent VDI to keep host configuration consistent, and installing the Robot in Service Mode for unattended work (how unattended automation is performed). A User Mode robot can't run unattended automations (execution troubleshooting). For images, the CLI supports UiRobot.exe connect with --url plus either --key or --clientID and --clientSecret (Robot CLI). My recommendation is to run that at first boot rather than baking a connected robot into the golden image, so each clone registers under its own final hostname.
Robot accounts assigned to a parent folder inherit access to its subfolders, and inherited roles can't be removed lower down (unattended concepts). I'd design the folder tree around ownership and access boundaries first and around org charts second, because that inheritance rule makes over-broad parent assignments hard to undo.
Capacity and licensing
The runtime rules, from unattended concepts:
- Runtimes are assigned to a machine object, and that number applies to each host connected to it. Three runtimes on a template with three connected hosts means up to nine concurrent automations.
- Runtimes come from the tenant pool when a host connects and go back when it disconnects.
- A host can run many background processes but only one foreground process at a time. UiPath's own example: 10 background processes plus 1 foreground process need 11 runtimes but only one host. A second simultaneous foreground process needs a second host.
So capacity has two dimensions: runtimes and foreground slots. My recommendation is to model them separately. Background-heavy portfolios are runtime-bound; UI-heavy portfolios are host-bound, and adding runtimes alone won't clear the queue.
For Cloud Robot - Serverless, consumption is per minute by machine size (Small 1 RU per minute, Standard 2, Medium 4, Large 10), and if the size is too small the process times out but still consumes robot units for the time it ran (managing processes). Undersizing to save units can cost more.
Queue and retry design
Queues are where reliability is either designed in or bolted on. A few documented behaviors drive the design:
- Auto retry has separate options for Failed items and Abandoned items, with a Max # of retries field that takes a value from 1 to 50. Manual retries don't count toward that maximum (managing queues).
- Only items failed with an Application exception are retried (automation best practices). Business exceptions aren't.
- An item that stays In Progress for a long time (approx. 24 hours) without being processed becomes Abandoned (queue item statuses).
- Each retry is a new item. The
Keyfield holds the GUID of the first item in the chain,RetryNumbercounts automatic retries, and manual retries are tracked separately inManualRetryNumber(managing queues). - Retried and deleted items don't take part in unique reference checks, so UiPath advises against deleting the first item in a retry chain.
| Retry layer | Scope | Use it for |
|---|---|---|
Activity-level retry in a Global Exception Handler (result = Retry) |
One activity | Rare, attended or simple linear processes. Not available in libraries (GEH) |
| Framework retry inside the job | One transaction | Transient system errors you can recover from in-session |
| Queue auto retry | One item, new job possible | Failures that need a fresh session or machine |
| Manual retry by a reviewer | One item | Failures that need a human decision |
My recommendation: pick one automated layer per failure type and write it down. The layers multiply. A GEH that retries an activity, inside a framework that retries the transaction, on a queue that retries the item, can turn one bad record into many attempts, and each queue retry shows up as a new item in reporting.
On triggers, the docs say queue triggers are optimized for processes that loop through all available items before exiting, there's one queue trigger per queue, and a periodic check (30 minutes by default, configurable down to 10) restarts work for postponed or unprocessed items. They also warn that this check can tie up resources outside business hours if items are left over (queue triggers). The "Enable pending jobs strategy" tenant setting changes the capacity formula: on, it may over-schedule; off, it may under-schedule, with the periodic check catching up. I'd treat that setting as an architecture decision, not a default, and record why you chose it.
Graceful control
Orchestrator's Stop is a soft stop. The job is marked Stopping and the robot is notified, but execution continues. The workflow has to check for it with Should Stop and exit on its own; if it never acts on the signal, the job runs to the end and finishes as Successful. Kill forcefully stops the job and marks it Stopped (managing jobs). The Robot guide adds that Kill first sends a Cancel request, which lets Finally blocks run cleanup, before it forces termination (stopping a process, Robot 2023.10). UiPath recommends Stop over Kill (automation best practices). The same Robot page notes that a stopped or cancelled transaction can be recorded as successful if status is set in the wrong block, and advises setting Successful only in the Try block and Failed only in the Catch block.
This matters because machine maintenance mode offers three choices: wait for running jobs to finish (the default, which issues no stop command), stop all running jobs and wait, or kill them now. UiPath notes that jobs only shut down gracefully if the automation is built to handle stop requests. Maintenance is set per session (machine plus hostname), and pending jobs keep their status until another machine, or the same one once it's back, picks them up (managing machines). If your processes honor Should Stop, "stop and wait" becomes a safe patch-night tool. If they don't, you're left choosing between waiting indefinitely and killing.
Observability and SLOs
Orchestrator gives you several building blocks:
- Queue SLAs. SLA predictions per queue, with an optional Risk SLA buffer, up to 90 days (managing queues).
- Notifications. Subscribable events include unattended robot unresponsive or disconnected, trigger automatically disabled, job execution failed, jobs pending, transaction failed with application exception, and queue SLA error (notifications).
- Job recording. Recording of failed jobs, failed queue transactions, or all jobs. The maximum duration depends on the plan: 3 minutes for non-entitled cloud tenants, up to 15 on Enterprise or Advanced (managing processes).
Two documented limits shape how far you can lean on these. Transaction-failure notifications are deduplicated to 10 per queue per 60 minutes, with an hourly summary (notifications). And by default a trigger is disabled automatically after 10 failed launches if it hadn't launched successfully in the last day (managing triggers). That second one is quiet: work just stops arriving.
My recommendation is to define SLOs on business outcomes, not job status: share of business items finished inside the queue SLA, counted once per Key, plus time from item creation to final status. Job success rate alone hides the stopped-but-successful case above and double counts retries. Treat "trigger automatically disabled" and "unattended robot disconnected" as page-worthy, since both stop throughput without a failed job to show for it.
Governance and change control
Automation Ops policies can restrict which package feeds Studio can use, enforce Workflow Analyzer rules, and require projects to pass analysis before running or publishing. Robot policies add Runtime Analyzer rules that block listed apps, URLs, or email recipients at runtime. Policies deploy at tenant, group, or user level (governance).
For infrastructure change, take the browser. UiPath documents that DeveloperToolsAvailability = 2 breaks the Chromium API input method unless the allowlist and blocklist policies are both set for the UiPath extension ID, and that DisableScreenshots on Chrome 154 and later breaks Chromium API input and Inject Js Script (Chrome group policies). Those are security team decisions. My recommendation is to register the robot pool as a stakeholder in browser and GPO change, and to route those changes through a non-production template first.
Release and rollback
| Option | Choose it when | Trade-off |
|---|---|---|
| Manual publish and process update in Orchestrator | Small estate, few releases | No enforced tests or approval |
| Automation Ops Pipelines | You want UiPath-native CI/CD from GitHub or Azure DevOps | Pipeline jobs run on an unattended robot, so it needs a dedicated folder, a robot account, and a machine or serverless robot to run on (Pipelines) |
| UiPath CLI, Azure DevOps extension, or Jenkins plugin | You already run an enterprise CI/CD system (CI/CD) | You own the pipeline code |
Built-in pipeline templates include "Update with tests" and "Build and promote with approval," which adds an approval step before promoting to a second environment (Pipelines).
Rollback is a process setting: Edit Process lets you pick a version or select Rollback to return to the previous one, and UiPath recommends keeping at least one old version for that purpose (managing processes, automation best practices). Running jobs keep the version they started with, while pending jobs and new triggers use the updated one. My recommendation: release when the queue is drained or the trigger is paused, so you know which version touched which items.
Cost and risk
The cheapest reliability work is usually removing a dependency rather than hardening it. Two examples from the docs. Workbook activities read and write Excel files without Excel installed (Excel package), which takes Office setup out of the robot's failure domain when you don't need the Excel UI. And the Microsoft 365 Download File activity fetches a OneDrive or SharePoint file through a connection into a local path, with an explicit "if a file already exists" choice (Download File). My recommendation is to stage inputs that way instead of relying on a per-user sync client being caught up when a robot session starts. With Sites.Selected, browsing lists nothing, so you enter the file URL or ID.
On risk, the trade-off to state openly is concentration: one big shared pool uses runtimes efficiently and also turns one image or policy change into a tenant-wide incident.
Maturity model
This is my own framing, not a UiPath model.
| Level | Characteristics |
|---|---|
| 1. Reactive | Per-VM machines, jobs on schedules, failures found by business users |
| 2. Standardized | Machine templates on a common image, Service Mode robots, queues with set statuses, one retry layer per failure type |
| 3. Observed | Queue SLAs, subscribed notifications for robot, trigger, and transaction events, outcome-based SLOs counted per Key
|
| 4. Governed | Automation Ops policies, CI/CD with tests and approval, documented rollback, robot pool included in GPO and browser change |
| 5. Engineered | Non-production template as canary, capacity modeled on runtimes and foreground slots, dependencies removed where possible, maintenance via graceful stop |
One-page checklist
Failure domains
- [ ] Each domain (session, host, browser, Office, capacity, distribution, change) has a named owner
- [ ] Logon and RDS session policies on robot hosts match UiPath's session troubleshooting guidance
Machines and folders
- [ ] Unattended hosts use machine templates and Service Mode robots
- [ ] Hosts under a template share apps, paths, and versions
- [ ] Every robot account in a folder exists on every host in its templates
Capacity
- [ ] Runtimes sized for peak overlap across all folders on a template
- [ ] Foreground slots (hosts) modeled separately from runtimes
Queues
- [ ] One automated retry layer per failure type, documented
- [ ] Reporting counts business items by
Key, not by queue item - [ ] First items in retry chains are never deleted
- [ ] Pending jobs strategy chosen deliberately
Control and observability
- [ ] Processes honor Should Stop; status set only in Try and Catch
- [ ] Queue SLAs and Risk SLAs set
- [ ] Alerts on robot disconnected, trigger auto-disabled, job failed, queue SLA error
Change
- [ ] Automation Ops policies for feeds and analyzer rules
- [ ] CI/CD with tests and approval
- [ ] At least one previous process version kept for rollback
- [ ] Browser and GPO changes tested on a non-production template first
I post short UiPath fixes from real forum questions on my YouTube channel, RPA Simplified.
Top comments (0)