Also published on the product site: profile-user-journey-then-scale-citratest-vu.aspx
CitraTest VU load testing for Citrix, RDS, and cloud VDI – encode the on-the-glass journey with WaitForImage and StartTimer/StopTimer first, then scale concurrent virtual users.
Direct answer: Do not ramp concurrency against a vague script. CitraTest VU® load-tests Citrix, Microsoft RDS, AVD, and cloud multi-user sessions from the glass – but the honest sequence is profile the user journey first, then scale the VUs. Encode real mouse and keyboard steps, sync with WaitForImage, time moments of truth with StartTimer / StopTimer, prefer static bitmaps, reserve OCR for dynamic text (OCR is not a wait). Only after that definition of success is stable do you raise concurrent virtual users.
Teams that start with "how many users can we push?" often skip the harder question: what does a single successful user journey look like on screen? If the script sleeps for three seconds, checks a Workspace URL, or stops at "ICA connected," concurrency only amplifies the wrong clock. A thousand virtual users with a bad journey is not capacity planning – it is noise at scale.
This post is about that sequencing for CitraTest VU load testing: encode the journey on the glass, then scale. It is not a production continuous-watch guide (that is CitraTest APM Publish → Scenario → SLA) and not a how-to for splitting automated regression scripts into login-storm vs sustained-path builds (that is Control Plane ≠ Farm for automated testing). For why control-plane green is not farm proof under load – and how login storm differs from density/sustain as ramp phases – see The Control Plane Is Not the Farm. Same glass contract; this article is the order of operations.
Why ramp-first fails
Concurrency is a multiplier. It multiplies whatever your script already treats as "done."
- Protocol-ready is not user-ready. HDX and RDP can be up while the published app, chart, or order line is still painting.
- Fixed sleeps hide variance. A three-second pause that works for one calm session collapses under a Monday morning rush – or falsely passes when the glass was ready in half a second.
- URL / control-plane checks stop at the front door. They do not prove the business step completed on screen under load.
- Unnamed timers cannot guide SKU decisions. If every step dumps into one stopwatch, you cannot tell whether broker spin-up or in-session work broke first.
Profile the journey until a single VU (or a small interactive playback) proves the same moments of truth a real user would recognize. Then scale.

Illustrative / method diagram – not Tevron customer results. Control-plane indices can remain "healthy" while glass-level response climbs with concurrency.
Profile the journey on the glass
Per CitraTest User Guide / Quick Start measurement guidance, an on-the-glass journey uses one contract:
- Scripts encode the workflow on a Windows desktop.
- Playback sees the UI with bitmap images (and OCR when text is dynamic).
- Playback acts with real mouse and keyboard.
- WaitForImage synchronizes and verifies expected screen state before the next step.
- StartTimer / StopTimer capture on-screen response: StartTimer immediately after the initiating action; StopTimer immediately after WaitForImage confirms completion.
Walk the path a shift cannot skip – for example login-to-shell, published-app first paint, then one or two in-session steps (open chart, submit order, post invoice). Name each timer after what the user sees, not after a protocol hop label. Keep baseline images small and unique; match display properties (resolution, color depth, theme, font smoothing) between capture and playback so "image not found" failures are real application delays, not environment drift.

Illustrative method diagram – not customer results. That pipeline is the measurement contract inside the journey you will later scale.
Bitmaps for sync; OCR only for dynamic text
While you profile – and later under VU concurrency – keep OCR in its lane:
- Prefer static bitmaps for sync cues that do not change (toolbar icons, window chrome, confirmation glyphs).
- Reserve OCR for values that are unknown ahead of time (IDs, MRNs, order numbers, timestamps).
- OCR is not a wait/sync. Confirm readiness with image functions first (
WaitForImage,ClickOnImage), then OCR. Under VU, OCR calls have no timeout for wait/sync; flaky "OCR problems" are usually sync problems in disguise.
Related: Advanced OCR for Automated Testing.
Then scale: CitraTest VU concurrency
Once the journey is honest in interactive playback, scale it with CitraTest VU. Per the CitraTest User Guide (Chapter 11) and Quick Start VU overview:
- A dedicated VU load server (Windows Server with Remote Desktop Services) hosts many localhost RDP "CitraTest VU Sessions."
- Each session runs the profiled CitraTest script and opens its own client connection to the environment under test – Citrix, RDS, or cloud – just as a group of real users would.
- Scripts continue to drive the desktop with real mouse and keyboard, sync with bitmaps, and optionally use OCR for dynamic text.
- Separate measurement machines record response timers under load; results land in a results database and VU Results Console.
Nothing invasive is required on the session hosts for the glass path: the load is client-side. You change ramp, concurrency, and think time – not the definition of success. Success remains: the image-confirmed UI state appeared within the timer threshold under the load you claim to support.

Illustrative architecture based on User Guide Ch 11 / Quick Start VU overview – not a performance result chart.

Illustrative method diagram – not customer results. Encode the journey, then raise concurrent VUs against the same WaitForImage timers.
After the journey is honest: storm vs density (brief)
Scaling is not one blunt ramp. Once the glass journey is profiled, Tevron’s 2026 Citrix / RDS / cloud method guidance still separates two load phases – with the same scripts and the same moments of truth:
| Phase | What you change | What you learn |
|---|---|---|
| Login storm | Steep concurrent logons (broker, profile, session spin-up) | Can the farm absorb the rush to first useful glass? |
| Density / sustain | Hold concurrency; exercise the profiled multi-step work | Sessions-per-host, glass latency, SKU and autoscale truth |
Do not invent a second definition of success for each phase. Change how many VUs arrive and how long they stay busy. For the deeper control-plane-vs-farm framing under load, see The Control Plane Is Not the Farm and Logon storm vs density.

Illustrative method diagram – not customer results. Apply the same split after the journey is profiled for Citrix, Microsoft RDS, and cloud VDI / DaaS.
Sizing note (after the journey, before the big run)
Current User Guide Chapter 1 and Quick Start align on:
8 GB baseline + 8 GB additional RAM per 200 VU sessions, quad CPU minimum, 200 GB disk minimum, RDS configured per Chapter 11.
Also operational: do not minimize VU RDP windows during a run – RDP can blank the display, and scripts need a visible desktop to see. Profile with a visible desktop; scale with a visible desktop.
How this sits next to APM and automated testing (brief)
One glass definition of success travels across Tevron products without turning this article into those playbooks:
- CitraTest VU – profile the journey, then size it under concurrency (this post).
- CitraTest – build regression scripts with the same WaitForImage / timer contract; see Control Plane ≠ Farm (automated testing) when login-storm and sustained-path need separate encodings.
- CitraTest APM – schedule the same class of glass transaction in production (Publish → Scenario → SLA).
Related: What is CitraTest VU?, How to load test Citrix.
Closing: encode truth, then raise concurrency
Profile the user journey on the glass until WaitForImage and StartTimer/StopTimer name the moments a real shift would recognize. Prefer bitmaps for static sync; reserve OCR for dynamic text; never treat OCR as a wait. Then scale CitraTest VU concurrent sessions against that same definition of success – login storm and density/sustain as ramp shapes, not as new guesses about what "ready" means. Capacity numbers only earn trust when the journey they multiply was honest at one user.
FAQ
Why profile the user journey before scaling CitraTest VU concurrent users?
Concurrency amplifies whatever the script already measures. If the journey is vague – protocol hops, sleeps, or URL checks instead of on-screen readiness – a thousand VUs only produce a louder wrong answer. Encode WaitForImage sync and StartTimer/StopTimer for moments of truth first, then ramp.
What does profiling an on-the-glass journey mean in CitraTest VU?
A CitraTest script drives the real client GUI with mouse and keyboard, syncs with WaitForImage on static bitmaps, optionally uses OCR for dynamic text after image sync, and places StartTimer immediately after each initiating action and StopTimer after WaitForImage confirms the screen state users care about.
Can OCR be used as a wait or sync under CitraTest VU?
No. VU OCR calls have no timeout for wait/sync. Confirm readiness with image functions first (WaitForImage, ClickOnImage), then OCR. Prefer bitmaps for static UI cues; reserve OCR for dynamic text.
How does this post differ from the control-plane-is-not-the-farm VU article?
The front-door / control-plane article explains why Workspace green is not farm proof and how login storm differs from density/sustain under load. This article is the sequencing method: profile and encode the glass journey first, then scale concurrent VUs with that honest definition of success.
Do you need agents on session hosts for CitraTest VU?
No. For the glass path, load is client-side from VU sessions on a dedicated load server. Nothing invasive is required on the session hosts themselves.
When you need that glass path without agents on production session hosts — schedule a demo. Product pages: CitraTest VU, CitraTest APM, and the Tevron.com blog.
Citrix, HDX, ICA, StoreFront, Workspace, Microsoft, Remote Desktop Services, RemoteApp, Azure Virtual Desktop, and related marks are trademarks of their respective owners. Tevron is not affiliated with those vendors. Names are used for identification only.