Hero image for Scaling the Robot Army: High-Density Infrastructure for Enterprise RPA

Scaling the Robot Army: High-Density Infrastructure for Enterprise RPA

RPA Infrastructure Scaling DevOps UiPath

“We need 50 robots by Q2.”

Scaling from 2 robots to 50 isn’t just about buying more licenses; it’s an engineering challenge. You can’t just keep adding laptops under desks. You need a robust, server-grade infrastructure.


1. The Bottleneck: One User, One Machine?

In classical Windows architecture, a workstation runs one active user session at a time. This is inefficient for RPA.

The Old Way: 1 VM = 1 Robot

┌─────────────────────────────────────────────────────────────────┐
│              Standard Virtualization (Inefficient)               │
├─────────────────────────────────────────────────────────────────┤
│                                                                  │
│   ┌──────────────┐     ┌──────────────┐     ┌──────────────┐     │
│   │   VM 01      │     │   VM 02      │     │   VM 03      │     │
│   ├──────────────┤     ├──────────────┤     ├──────────────┤     │
│   │ OS: Windows  │     │ OS: Windows  │     │ OS: Windows  │     │
│   │ RAM: 8GB     │     │ Bot: 1       │     │ Bot: 1       │     │
│   │ Bot: 1       │     └──────────────┘     └──────────────┘     │
│   └──────────────┘                                               │
│                                                                  │
│   Resource Cost: High (3x OS overhead)                           │
│   Management: Painful (Patching 50 VMs)                          │
│                                                                  │
└─────────────────────────────────────────────────────────────────┘

2. High-Density Robots (HDR)

Modern RPA platforms (like UiPath) support High-Density Deployment on Windows Server.

Concept: Use Windows Server (2016/2019/2022) with RDS (Remote Desktop Services) enabled. This allows multiple users (robots) to log in to the same machine simultaneously, each in their own session.

┌─────────────────────────────────────────────────────────────────┐
│              High-Density Architecture (Efficient)               │
├─────────────────────────────────────────────────────────────────┤
│                                                                  │
│   ┌─────────────────────────────────────────────────────────┐    │
│   │                 High-Spec Server (VM)                   │    │
│   │             (Windows Server + RDS Enabled)              │    │
│   ├─────────────────────────────────────────────────────────┤    │
│   │                                                         │    │
│   │   ┌────────┐   ┌────────┐   ┌────────┐   ┌────────┐     │    │
│   │   │ Bot 1  │   │ Bot 2  │   │ Bot 3  │   │ Bot 4  │     │    │
│   │   │ Session│   │ Session│   │ Session│   │ Session│     │    │
│   │   └────────┘   └────────┘   └────────┘   └────────┘     │    │
│   │                                                         │    │
│   │   Shared OS Resources (CPU, Memory, Disk)               │    │
│   └─────────────────────────────────────────────────────────┘    │
│                                                                  │
│   Result: 1 Server runs 4-10 Robots                             │
│   Benefit: Less OS patching, lower cloud compute costs          │
│                                                                  │
└─────────────────────────────────────────────────────────────────┘

Constraints of HDR

  • Application Compatibility: Some legacy apps crash if opened twice on the same machine.
  • Resource Contention: One bot using 100% CPU slows down all others on that server.

3. Orchestration & Load Balancing

When you have 50 bots, you don’t assign tasks to specific machines. You assign them to a Machine Template.

Modern Queues architecture

  1. Orchestrator holds the queue of 1,000 invoices.
  2. Floating Robots on any available machine ask: “Do you have work?”
  3. Dynamic Allocation: If Server A goes down, Server B picks up the work automatically.

4. Disaster Recovery (DR) & HA

For mission-critical bots (e.g., payroll, banking transactions), you need High Availability.

┌─────────────────────────────────────────────────────────────────┐
│              High Availability (HA) Setup                        │
├─────────────────────────────────────────────────────────────────┤
│                                                                  │
│       User / API Trigger                                         │
│               │                                                  │
│         ┌─────▼──────┐       (Load Balancer)                     │
│         │     F5     │─────────────────────────┐                 │
│         └─────┬──────┘                         │                 │
│               │                                │                 │
│       ┌───────▼────────┐             ┌─────────▼───────┐         │
│       │ Orchestrator 1 │◄──Sync───►  │ Orchestrator 2  │         │
│       │    (Active)    │             │    (Active)     │         │
│       └───────┬────────┘             └─────────┬───────┘         │
│               │                                │                 │
│         ┌─────▼────────────────────────────────▼─────┐           │
│         │            SQL Server AlwaysOn             │           │
│         │          (Database Cluster)                │           │
│         └────────────────────────────────────────────┘           │
│                                                                  │
└─────────────────────────────────────────────────────────────────┘
  • Multi-Node Orchestrator: Run at least 2 instances behind a Load Balancer.
  • SQL AlwaysOn: The database is the brain. If DB dies, robots die. Use Active-Passive clustering.
  • Geo-Redundancy: If the East Coast data center floods, spin up bots in the West Coast.

5. Licensing: Attended vs. Unattended vs. Testing

License TypeMeaningBest For
AttendedBot assists a human (runs on their PC).Call Centers, “Co-pilot”
UnattendedRuns on a server, scheduled, no human seeing it.Batch jobs, heavy processing
TestingFor QA environments only. Cheaper.Non-production pipelines
Non-ProductionUnattended for Dev/Test.Development

Summary

Scaling isn’t linear. The complexity jumps when you cross user sessions and server boundaries.

  1. Use High-Density (Windows Server) to save compute costs.
  2. Treat robots like cattle, not pets. Use floating bots and machine templates.
  3. SQL Server is your single point of failure—protect it.

Credential & Security Management

Enterprise RPA handles sensitive data. Security isn’t optional.

Where to Store Credentials

┌─────────────────────────────────────────────────────────────────┐
│                    Credential Storage Options                    │
├─────────────────────────────────────────────────────────────────┤
│                                                                  │
│   OPTION                 SECURITY    MANAGEMENT    BEST FOR     │
│   ──────                 ────────    ──────────    ────────     │
│                                                                  │
│   Orchestrator Assets    ★★★★★       Easy          Production    │
│   (Credential type)      Encrypted   Central       All bots     │
│                          RBAC        Audited                    │
│                                                                  │
│   Windows Credential     ★★★★        Medium        Attended      │
│   Manager                OS-level    Per-machine   Single user  │
│                                                                  │
│   Config.xlsx            ★           Poor          NEVER        │
│   (Plain text)           None        No audit      (Don't do)   │
│                                                                  │
│   Azure Key Vault        ★★★★★       Complex       Enterprise    │
│   / HashiCorp Vault      Best-in-class Central    Multi-system │
│                                                                  │
└─────────────────────────────────────────────────────────────────┘

Orchestrator Assets: The Standard

Creating a Credential Asset:

  1. Orchestrator → Assets → Add Asset
  2. Type: Credential
  3. Enter username and password
  4. Set folder/robot permissions

Retrieving in Workflow:

' Get Credential activity
credential = GetCredential("SAP_ServiceAccount")
username = credential.Username           ' SecureString
password = credential.Password           ' SecureString
passwordPlain = credential.GetNetworkCredential().Password

Service Account vs User Account

AspectUser AccountService Account
Tied toIndividual personRole/function
Password expiryFrequent (90 days)Long or never
Risk of lockoutEmployee leavesLower (not personal)
Audit trail”John ran the bot""Bot Account ran”
Best practiceAttended onlyUnattended bots

Rule: Every unattended bot should use a dedicated service account, never a personal account.

API Keys and Secrets

For external APIs (not Windows credentials):

' Store as Text Asset (with Per-Robot value if needed)
apiKey = GetAsset("ExternalAPI_Key")

' Better: Use Credential asset with dummy username
cred = GetCredential("ExternalAPI")
apiKey = cred.Password  ' Store the key as "password"

Compliance Considerations

StandardRequirementRPA Implementation
SOC 2Access controls, audit logsOrchestrator RBAC + logs
ISO 27001Information security managementEncrypted credentials, access review
GDPRData protectionNo PII in logs, encryption
HIPAAHealthcare data protectionPHI never in plain text logs

Security Best Practices Checklist

CategoryChecklist Item
Credentials☐ All credentials in Orchestrator Assets
☐ No passwords in code or Config.xlsx
☐ Service accounts for unattended bots
☐ Regular credential rotation schedule
Logging☐ No sensitive data in log messages
☐ Mask PII in logs (last 4 digits only)
☐ Log access is restricted
Access☐ Least-privilege robot permissions
☐ Folder-based access control
☐ Regular access reviews
Network☐ Bots on segregated network (if possible)
☐ Firewall rules limit outbound access
☐ VPN for remote Orchestrator access

Handling Sensitive Data in Logs

Bad (Exposes data):

Log.Info($"Processing credit card: {cardNumber}")

Good (Masked):

maskedCard = "****-****-****-" & cardNumber.Substring(cardNumber.Length - 4)
Log.Info($"Processing credit card: {maskedCard}")