July 30, 2026DBA

Contained Availability Groups: Fixing the Instance-Level Metadata Headache

Contained Availability Groups finally solve the long-standing synchronization issues for logins, jobs, and linked servers in SQL Server HA environments.

The Traditional AG Synchronization Nightmare

For years, SQL Server DBAs have lived with a specific, recurring pain point: Availability Groups (AGs) only replicate user databases. If you created a login, a SQL Agent job, or a linked server on the primary replica, it didn't magically appear on the secondary.

We solved this with manual scripts, SSIS packages, or third-party tools like dbatools to sync master and msdb metadata. If you forgot to sync a login and a failover occurred, your application went down with a 'Login failed' error. Contained Availability Groups, introduced in SQL Server 2022, are the engineering solution to this architectural gap.

What are Contained Availability Groups?

A Contained Availability Group extends the concept of a contained database to the entire group. When you create a Contained AG, the system creates specialized versions of the master and msdb databases specifically for that AG.

These system databases are replicated along with your user databases. When you connect to the AG via its listener, you aren't looking at the instance's main master database; you are looking at the AG's contained master. This means your logins and jobs are now part of the replication stream.

The Problems They Solve

1. Orphaned Users: In a standard AG, you have to ensure SIDs (Security Identifiers) match across all replicas. In a Contained AG, the login is created in the AG-contained master, meaning the SID is identical across all nodes by default.

2. Job Synchronization: No more manual export/import of SQL Agent jobs. If a job is created while connected to the listener, it resides in the contained msdb and is active wherever the AG is primary.

3. Simplified Migrations: Moving an AG to a new cluster becomes significantly easier when the security and scheduling metadata are packed inside the group itself.

When It Fits (and When It Doesn't)

Best Fit:

  • True Multi-tenant Environments: If you are hosting multiple customers and each needs their own set of isolated logins and jobs.
  • High-Velocity Environments: Environments where logins and jobs change frequently, and manual synchronization is a risk to RTO/RPO.
  • Simplified DR: If you want a 'push-button' failover experience where the application environment is identical on the target side.

When to Skip:

  • Instance-Level Dependencies: If your application relies on objects that cannot be contained (like certain server-level configurations or certificates not stored in the contained DB), you'll still have manual work.
  • Cross-AG Communication: If you have multiple AGs on the same instance that need to share metadata, the isolation of Contained AGs might actually become a barrier.
  • Legacy Versions: You must be on SQL Server 2022 or later. There is no backporting this feature.

A Simple Setup Example

To create a Contained AG, you use the CONTAINED keyword during the CREATE AVAILABILITY GROUP command. Note that you cannot easily convert an existing 'regular' AG to a contained one; this is a creation-time decision.

CREATE AVAILABILITY GROUP [ContainedProdAG]
WITH (CONTAINED)
FOR DATABASE [SalesData]
REPLICA ON 
'SQL-NODE-01' WITH (
    ENDPOINT_URL = 'TCP://SQL-NODE-01.local:5022',
    FAILOVER_MODE = AUTOMATIC,
    AVAILABILITY_MODE = SYNCHRONOUS_COMMIT
),
'SQL-NODE-02' WITH (
    ENDPOINT_URL = 'TCP://SQL-NODE-02.local:5022',
    FAILOVER_MODE = AUTOMATIC,
    AVAILABILITY_MODE = SYNCHRONOUS_COMMIT
);
GO

Once created, you will see ContainedProdAG_master and ContainedProdAG_msdb in your system databases. To manage the metadata, you must connect via the Listener. If you connect to the node's local instance name, you are still interacting with the local instance's master database.

Practical Opinion: Is it Worth it?

If you are starting a new greenfield deployment on SQL Server 2022, there is almost no reason not to use Contained AGs. The overhead is negligible compared to the massive reduction in operational risk. The biggest hurdle is the mental shift for DBAs: you have to stop RDPing into nodes to create jobs and start using the Listener for all administrative tasks. Once you make that shift, you'll wonder why we did it the old way for twenty years.


← All posts

Keep reading