Migration of Citrix databases

With the latest Citrix Virtual Apps & Desktops (CVAD) LTSR version, older SQL Server versions have been discontinued. If you want to keep your environment stable and supportable, there is no way around migrating the Citrix databases (site, logging, monitoring) to modern SQL servers (2019/2022). Whether cluster, always on or mirroring – the procedure remains essentially the same. In this article, I will show you step by step how to migrate securely.

1. Prerequisites

  • Complete backups of all Citrix databases
  • Backups/VM snapshots of the delivery controllers (DDCs)
  • New SQL Server (Cluster, Always On or Mirror)
  • Same SQL version on Principal and Mirror

1.1 Create backups

Before you start the migration, the most important thing comes first: clean, verified backups.
Sounds trivial, but anyone who has ever had to restore a Citrix site without a working backup knows why this step is crucial.

Create complete database backups of all Citrix databases:

  • Monitoring database (e.g. CitrixMonitoring)
  • Site database (e.g. CitrixSite)
  • Logging database (e.g. CitrixLogging)

1.1.1 Step-by-step in SSMS (GUI)

  • Start SQL Server Management Studio (SSMS) and connect to the source SQL (Windows/SQL-Auth)
  • Select the first DB in the Object Explorer (e.g. CitrixLogging)
  • Right-click on the DB → Tasks Backup…
  • Set backup type to Full
  • Under Destination, remove entries if necessary, then select Add… → File, e.g. D:BackupsCitrixLogging_Full_YYYYYMMDDHHmm.bak
  • Media Options tab
  • Backup Options tab
  • Click OK → Wait for success message
  • Repeat the whole process for Site-DB and Monitoring-DB (CitrixSite, CitrixMonitoring or similar)
  • Create transaction log backups (Recovery Model Full!):
  • Copy backup files to a share that the new SQL server can read

1.1.2 T-SQL Alternative

2. Database recovery

After the backup, the actual migration step follows: restoring the Citrix databases to the new SQL server.
It doesn’t matter whether you use a standalone instance, a cluster or Always On – the procedure is essentially the same.

2.1.1 Restore to new principal (GUI)

  • Connect to the new SQL server in SSMS
  • Object Explorer: Right-click DatabasesRestore Database…
  • Source = DeviceAdd… → Select Full-Backup *.bak
  • Files tab: Adapt paths to new drives if necessary
  • Options tab:
  • OK → Success message. Then import the last log backup if necessary (only if you want to go to T time)

2.1.2 Restore for T-SQL

2.2 Logins & authorizations

After the restore, the Delivery Controller (DDC) machine accounts must be given access to the new databases again.
As SQL server logins are server-wide, they are not copied during the backup/restore – so you have to create them manually.

Then assign the appropriate roles in each Citrix database (site, logging, monitoring):

2.3 Optional: Seeding for always on / mirroring

If you want to operate your Citrix databases with high availability, you can integrate them into an Always On Availability Group or classic database mirroring.

At Always On, the following applies:
All replicas involved must have identical databases that were restored with NORECOVERY.
This is called seeding – i.e. the initial filling of the secondary replicas.

Then perform the same steps for logging and monitoring database.
As soon as all DBs are in the RESTORING state, you can add them to the availability group.

If you are still working with classic SQL mirroring, the procedure is similar:
Here too, the secondary database must be restored with NORECOVERY.

Then on the Principal:

And on the mirror:

As soon as the “Synchronized” status is reached, you can add the other Citrix databases identically.

3. Prepare delivery controller

Before you can set the new database connections, the delivery controllers (DDCs) must be prepared.
The aim is to cleanly disconnect all existing connections to the old SQL environment, temporarily deactivate logging and monitoring and thus prevent Citrix services from writing incorrect data during the migration phase.

3.1 Deactivate monitoring & logging

First of all, all telemetry and logging services should be paused.
This prevents unnecessary write operations during the change of database connections.

This will temporarily deactivate both Citrix Monitoring and Configuration Logging.
As soon as the migration is complete, reactivate both functions.

3.2 Disconnect old DB connections

Now the old DB connections of the controllers must be resolved.
The Citrix services (Broker, Config, Logging, Monitoring, etc.) each have their own SQL connection strings, which you must set to zero individually.

To do this, first load the Citrix module:

Then delete all existing connections:

After these commands, there are no longer any active SQL connections between the Citrix services and the old database environment.

  • Carry out these steps on all Delivery Controllers (DDC01, DDC02, DDC03 etc.).
  • In a running cluster, the order does not matter – you can switch controllers individually.
  • If you want to be sure, run Get-BrokerServiceStatus beforehand to check whether the services are running properly.

All controllers are now disconnected from the old database, logging & monitoring is paused.

The environment is now ready to set the new connections to the new SQL server in the next step.

4. Configure new connections

After the old database connections have been disconnected, the new connection strings can now be set on the delivery controllers.
This step reconnects the Citrix services to their respective databases – but now on the new SQL server.

First define the target SQL server and the new database names.
Make sure that the SQL server name points either directly to the new server or – in the case of Always On – to the listener.

If you use Always On, be sure to use the listener name (e.g. SQL-LISTENER.DOMAIN.LOCAL) so that your controllers remain connected even in the event of a failover without you having to adjust connection strings later.

4.1 Set Site-DB

Now establish the connection to the new site database.
This is the core of your Citrix environment and must be set first.

All central Citrix services (Broker, Config, Prov, Hyp, etc.) are thus reconnected to the Site DB.

4.2 Logging & Monitoring set

Next come the two secondary databases:
Configuration, Logging and Monitoring.

This sequence ensures that both services point cleanly to the new databases and that no old connection strings are active.

4.3 Check connection

After setting the new connections, a short function test is mandatory.
Check the status of all Citrix services:

All services should return the status OK and point to the new SQL server.

If you have several delivery controllers, repeat these steps on all nodes. Then use Get-LogDBConnection and Get-MonitorDBConnection to check whether all controllers really use the same connection strings. Different connection strings often lead to synchronization problems between the services later on.

4.4 Reactivate logging & monitoring

Once all connections have been successfully set, you can reactivate the previously deactivated services:

The Citrix site is now fully functional and ready for production again.

5. Conclusion

Migrating Citrix databases is not rocket science – but it does require discipline, a clean approach and an understanding of the internal dependencies of Citrix services.
If you “simply restore” without a plan, you risk faulty connections, defective logging databases or interrupted monitoring sessions.
With the structured process described above, however, the migration remains transparent, secure and reproducible.

The most important thing is:

  • Check backups before you start.
  • Restore databases in the correct order.
  • Disconnect and reset controller connections in a controlled manner.
  • Finally, test all services – it is better to test too much than too little.

Especially in productive enterprise environments, it is advisable to simulate the steps beforehand in a test farm and document the connection strings.

This prevents errors in the live system and you can roll back at any time if problems occur.

Those who also use Always On or SQL mirroring benefit from genuine high availability and ensure that their Citrix site continues to work even in the event of SQL failures without users noticing.

In short:
A clean Citrix database migration is less of a technical challenge than a question of preparation and care.
If you have mastered the steps, you not only have a stable system, but also the perfect template for future updates or SQL changes.

10 thoughts on “Migration of Citrix databases”

  1. Great article, thank you! Curious, I took over an environment where all 3 datastore are in one database. Is there an easy way to split them apart without losing any of the monitoring or logging data?
     

    1. No — there’s no “official” or easy way to split them in place while keeping all existing data.
      Citrix Studio and the PowerShell cmdlets (Set-*-DBConnection) assume distinct database names for each service.

      You basically have two safe options:

      Option 1 – The clean migration (recommended)

      1. Create three new databases on your SQL Server:
      – CitrixSite
      – CitrixLogging
      – CitrixMonitoring

      2. Recreate the structure for each using Studio or use Set-LogDBConnection / Set-MonitorDBConnection to point to empty DBs.

      3. Restore only what you need:
      – The Site DB you can’t split — it has to be rebuilt from config (Controllers, Catalogs, Delivery Groups, etc.).
      – The Logging DB can be archived — you can back up the old combined DB and keep it for compliance, then start fresh.
      – The Monitoring DB is usually the biggest. It can’t be “split” but can be recreated (you’ll lose historic performance data but the farm stays functional).

      4. Update your Delivery Controllers:

      Option 2 – Archive & rebuild

      If you absolutely must preserve historical data:
      – Keep the original combined DB read-only as an archive (CitrixLegacyCombined).
      – Create fresh empty DBs for new Logging/Monitoring going forward.
      You’ll lose historic graphs in Director, but the environment becomes compliant — and faster.

      Don’t try to export individual schemas or manually detach parts of the DB.
      The dependencies between dbo.Broker, Logging, and MonitorData objects make that a nightmare.

      Don’t attempt Generate Scripts from SSMS — Citrix services won’t recognize them as valid.

  2. Thanks for the informative guide. How much downtime would you say is required and how much would I negotiate with stakeholders to be safe?

  3. If Local Host Cache (LHC) is enabled and healthy, your actual downtime for end users is effectively zero — as long as you plan the sequence correctly.

    In LHC mode:
    – Existing user sessions stay active
    – New connections can still be brokered
    – Citrix Studio is unavailable
    – Director data (monitoring) pauses
    – No configuration changes possible

    If you have:
    – 2+ Delivery Controllers
    – LHC verified as “Ready” (Get-BrokerLocalHostCache shows Active = True)
    – Each DDC synced recently (LastSuccessfulSyncTime recent)

    Then you can confidently plan:
    Expected impact:
    – No interruption to user sessions
    – No new configuration changes during the window
    – Director & Studio temporarily unavailable (~30 minutes)

    Duration: 1-hour maintenance window
    Risk: Low – LHC ensures continuity even if SQL connectivity is lost
    Rollback: Revert DB connection strings to the previous SQL server

    1. But LHC won’t support for pooled non persistent VDI desktops right so there is downtime right?

      1. Short answer: yes, there can be downtime for pooled non-persistent VDIs when the SQL DB is unavailable, even with Local Host Cache.

        Long answer:
        LHC allows the Delivery Controller to continue brokering if the SQL database is down, but it uses a local snapshot of the Site DB. That snapshot does not contain everything.

        Works in LHC:
        – Existing VDAs that are already registered
        – Users launching sessions on already running machines
        – Reconnect to existing sessions

        Problematic / limited in LHC:
        – Power management
        – Machine creation
        – New VDA registrations in some scenarios
        – Some non-persistent workflows

        With pooled non-persistent desktops:
        1. User logs in
        2. Controller powers on VM
        3. VM boots
        4. VDA registers
        4. Session starts

        During LHC mode:
        – Controllers cannot query SQL for power actions
        – Machines cannot be dynamically started
        – If no idle VMs are already running and registered, the user cannot get a desktop

        To avoid downtime during SQL work:
        – Pre-power a pool of VDIs (enough for expected logins)
        – Disable autoscale/power management
        – Wait until all VDAs are registered
        – Then perform SQL cutover

        That way LHC can broker from the already running machines.

  4. Thank you for the guide.

    In de the step: “Create transaction log backups (Recovery Model Full!)”
    Is this for all the 3 databaes?
    You screenshots shows the logging database and in the SQL T commands is it only shows the site database command.

    Also can these steps be used to move from a standalone SQL server configuration to a AlwaysOn database configuration?

    1. Is this for all the 3 databases?
      Yes the Recovery Model Full is for all three dbs.

      Can you use these steps to move from standalone SQL to AlwaysOn?
      Yes — conceptually it’s the same migration pattern (backup → restore → repoint controllers), but with an AlwaysOn twist:

      1. Back up all relevant CVAD DBs (full + log backups) on the old standalone SQL.
      2. Restore them onto the intended primary replica (or restore on one node and then add to AG).
      3. Add the DBs to the Availability Group (and seed secondaries).
      4. Update the CVAD controllers’ DB connection strings to point to the AG Listener, not the old server name. Citrix provides PowerShell cmdlets/scripts to change/clear/set DB connection strings (e.g., Set-ConfigDBConnection, and equivalents for Monitor/Logging).

      If you want the no-drama rule of thumb:

      – Move to new standalone SQL: restore DBs → repoint.
      – Move to AlwaysOn: restore DBs → put them in AG

Leave a Reply

Your email address will not be published. Required fields are marked *

* I consent to having this website store my submitted information so they can respond to my inquiry.