First off, I had some fun with the AI generated images with this. I think silly images are the way to go.
Automatic seeding for Availability Groups is one of those features that’s fantastic when it works and incredibly frustrating when it doesn’t. When seeding is healthy, databases just show up on the secondary and life is good. When it’s not, you’re left staring at vague status messages, wondering whether anything is actually happening at all. I really hate how the GUI handles this, because if the seeding is working or not, you get no feedback whatsoever until its basically done.
Luckily, there are scripts to help here, but if you don’t have them handy, you aren’t getting any information.
The first place I always check is:
SELECT * FROM sys.dm_hadr_automatic_seeding;
This DMV tells you whether seeding started, whether it failed, how many retries have occurred, and whether SQL Server recorded an error code. If seeding failed outright, this is usually where you’ll see the first clue as to why.
Next:
SELECT * FROM sys.dm_hadr_physical_seeding_stats;
When things are healthy, this view can show progress and estimated completion. When things are not healthy, it can be empty, partially populated, or frozen in a state that never changes. So you can use that knowledge; if seeding is supposedly “in progress” but this DMV isn’t showing anything, something is wrong.
Check Whether Data Is Actually Moving (Secondary)
That gnawing question is almost answered. Is anything actually happening right now?
On the secondary replica, I use performance counters to answer that question. This script samples backup/restore throughput over a short window to see if seeding activity is occurring:
----- RUN ON SECONDARY ------
-- Test if there are processes for the seeding occurring right now
IF OBJECT_ID('tempdb..#Seeding') IS NOT NULL DROP TABLE #Seeding;
SELECT GETDATE() AS CollectionTime,
instance_name,
cntr_value
INTO #Seeding
FROM sys.dm_os_performance_counters
WHERE counter_name = 'Backup/Restore Throughput/sec';
WAITFOR DELAY '00:00:05';
SELECT LTRIM(RTRIM(p2.instance_name)) AS [DatabaseName],
(p2.cntr_value - p1.cntr_value)
/ DATEDIFF(SECOND, p1.CollectionTime, GETDATE()) AS ThroughputBytesSec
FROM sys.dm_os_performance_counters AS p2
INNER JOIN #Seeding AS p1
ON p2.instance_name = p1.instance_name
WHERE p2.counter_name LIKE 'Backup/Restore Throughput/sec%'
ORDER BY
ThroughputBytesSec DESC;
If you see throughput here, seeding is still moving data, even if the DMVs look suspicious. If you see nothing, seeding is probably broken.
Restarting Seeding (Without Restarting SQL)
When seeding is stuck, sometimes the fastest path forward is to effectively “kick” the process. On the primary replica, toggling the seeding mode can force SQL Server to restart the automatic seeding workflow:
-----*** RUN ON PRIMARY ******-----
-- Change to your AG name and server names
ALTER AVAILABILITY GROUP
MODIFY REPLICA ON 'SecondaryServer1'
WITH (SEEDING_MODE = AUTOMATIC);
ALTER AVAILABILITY GROUP
MODIFY REPLICA ON 'SecondaryServer2'
WITH (SEEDING_MODE = AUTOMATIC);
This isn’t magic, and it doesn’t fix underlying problems like permissions, disk space, or network throughput, but it often clears up cases where seeding simply stopped progressing for no obvious reason. I use these scripts all the time to verify that there is data movement happening on an AG that stopped syncing over night or after a patch.
A Cautionary Tale About “Helpful” AI
I like to test AI to see what it suggests on problems I’m troubleshooting. Lots of times it tells me what I already know, but one time an AI tool confidently suggested a SQL command that would “restart AG data movement.”
That sounded amazing. I got excited. This must be a new script I didn’t know about from a new release?
No…It didn’t exist. It was just a hallucination.
AI can be a great accelerator, but you still need to verify everything against reality. Especially when something sounds too good to be true.
Final Thoughts
AG seeding failures are rarely caused by one thing, and no single DMV tells the whole story. You have to look at:
- Seeding status and error codes
- Physical progress
- Data movement
- And sometimes, force SQL Server to reattempt the process
The good news is that with the right scripts and a little patience, most seeding issues can be diagnosed without guesswork. The bad news is that when things break, SQL Server is still not very good at telling you why unless you know exactly where to look.
Hopefully, scripts like these save you a little time the next time seeding decides to go wrong.














