How to monitor backup and restore progress in SQL Server

By:   |   Updated: 2021-10-07   |   Comments (37)   |   Related: 1 | 2 | 3 | 4 | 5 | 6 | > Backup


Problem

My developers often ask me to create a database backup before any critical deployment or to restore a database to one of the test environments. They often ping me during the process to know the progress and when it will be completed. Sometimes the backup or restore is running through a SQL Agent job which looks hung and I want to know if it's actually doing something. In this tip I have tried to put forth a solution to monitor your backup and restore progress.

Solution

Normally we take a backup or restore a database either through SSMS or using a script. We might also schedule it using a SQL Agent job. Now let's see how to monitor progress in all the three cases.

Note about permissions: Backup database permissions default to members of the sysadmin fixed server role and the db_owner and db_backupoperator fixed database roles. For restore, if the database being restored does not exist on the server, then the user must have CREATE DATABASE permissions to be able to execute the RESTORE. If the database exists, RESTORE permissions default to members of the sysadmin and dbcreator fixed server roles and the owner (dbo) of the database.

SQL Backup Percentage Complete

There are several ways to get information about the percentage complete for a backup. 

SQL Backup Percentage Complete using SSMS GUI

Open SSMS, right click on a database then select Tasks > Back Up. A screen similar to the below image will open. After you select all of the backup options and click OK, you can monitor the progress on the lower left side of the GUI as shown in the below image. This will give you an idea of the status of the backup.

using ssms to monitor your backup/restore progress

SQL Backup Percentage Complete using T-SQL Script

Scripts can be also be used to do a backup and you can use the keyword STATS in the script to monitor progress.

When using STATS, the number equals the total processing into parts equal to the number. So if you use STATS = 1, this will give you percent completion from 1 to 100%.

Backup showing every 10% of progress

using t-sql to monitor your backup/restore progress

Backup showing every 1% of progress

using stats=1 will give you a percent by percent completion from 1 to 100%

SQL Restore Percentage Complete

There are also multiple ways to get restore percentage complete.

SQL Restore Percentage Complete using SSMS GUI

Open SSMS, right click on a database then select Tasks > Restore. A screen similar to the below image will open. After you select all of the restore options and click OK, you can monitor the progress on the lower left side of the GUI as shown in the below image. This will give you an idea of the status of the restore.

you can monitor the progress on the left side of the gui

SQL Restore Percentage Complete using T-SQL Script

The following screens shows how we can get restore percentage complete using scripts.

Restore showing every 10% of progress

using t-sql to show the restore progress

Restore showing every 1% of progress

showing every 1% of progress

Getting SQL Backup or SQL Restore Percentage Complete Using DMVs

If the backup or restore is running from a SQL Agent job or maybe someone kicked off the process from another machine, you can use DMV sys.dm_exec_requests to find the progress. I really thank Microsoft for introducing DMV's and making a DBA's life a lot easier.

You can run this script, which will give you output similar to the screenshot below. Here we can see the percent complete and estimated completion time. This script will work for any backup or restore that is currently running regardless of what method was used to run the backup or restore.

SELECT 
   session_id as SPID, command, a.text AS Query, start_time, percent_complete,
   dateadd(second,estimated_completion_time/1000, getdate()) as estimated_completion_time
FROM sys.dm_exec_requests r 
   CROSS APPLY sys.dm_exec_sql_text(r.sql_handle) a 
WHERE r.command in ('BACKUP DATABASE','RESTORE DATABASE') 

using dmv's if the backup/restore is running from a sql agent

If you wanted someone who is not a member of sysadmin role to check the backup or restore progress using this script, you can provide permission to them using the below command:

GRANT VIEW SERVER STATE TO [Login_name] 

SQL Restore Stuck at 100%

I would like to touch base upon one aspect of SQL Server which you will encounter while restoring databases. You may see that the restore is stuck at 100% or around 99.99% and is not moving further. Sometimes for databases that are very large, TB size databases, it may even take 5 hours for the recovery to complete. To understand this situation we need to understand the different phases that a restore goes through.

The three phases are Data Copy phase, Redo phase and Undo phase.

  • While you may see the restore is 100% complete it's actually only the Data Copy phase that is complete and then SQL proceeds to subsequent phases before the recovery is totally complete.
  • In the Redo phase, all the committed transactions present in the transaction log when the database was being backed up are rolled forward.
  • In the Undo phase, all the uncommitted transactions in the transaction log while the database was being backed up are rolled back.

If the database is being restored with NORECOVERY, the Undo phase is skipped.

Unfortunately SQL Server does not show the progress during the Redo and Undo phases as it does in the Data Copy phase. So, depending upon the activity in the database at the time it was getting backed up will decide the overall total recovery time.

Next Steps
  • The same DMV can be used to monitor DBCC shrink commands progress as well.
  • Efficient backup strategy is the backbone of disaster recovery and no other high availability solution can replace it.
  • Backups and restores take considerable amount of resources, so you need to plan the backup strategy and timings accordingly.
  • A backup file retention policy should also be created.
  • Keep critical database backups safe using data encryption which was first introduced in SQL Server 2008.


sql server categories

sql server webinars

subscribe to mssqltips

sql server tutorials

sql server white papers

next tip



About the author
MSSQLTips author Nitansh Agarwal Nitansh Agarwal is a lead with 4+ years of extensive experience in database administration where he handles large critical databases.

This author pledges the content of this article is based on professional experience and not AI generated.

View all my tips


Article Last Updated: 2021-10-07

Comments For This Article




Tuesday, July 12, 2022 - 7:36:05 AM - Gary Mazzone Back To Top (90249)
This is the query I use to get Pct complete for either backup or restores:

SELECT
session_id as SPID,
command,
a.text AS Query,
start_time,
percent_complete,
CAST(((DATEDIFF(s,start_time,GETDATE()))/3600) AS VARCHAR) + ' hour(s), '
+ CAST((DATEDIFF(s,start_time,GETDATE())%3600)/60 AS VARCHAR) + 'min, '
+ CAST((DATEDIFF(s,start_time,GETDATE())%60) AS VARCHAR) + ' sec' AS running_time,
CAST((estimated_completion_time/3600000) AS VARCHAR) + ' hour(s), '
+ CAST((estimated_completion_time %3600000)/60000 AS VARCHAR) + 'min, '
+ CAST((estimated_completion_time %60000)/1000 as VARCHAR) + ' sec' AS est_time_to_go,
DATEADD(SECOND,estimated_completion_time/1000, GETDATE()) AS estimated_completion_time
FROM sys.dm_exec_requests r
CROSS APPLY sys.dm_exec_sql_text(r.sql_handle) a
WHERE r.command IN ('BACKUP DATABASE','RESTORE DATABASE', 'BACKUP LOG','RESTORE LOG')

Friday, June 25, 2021 - 6:49:31 AM - Nic B Back To Top (88893)
Thanks for the info about the three phases of restores. Exactly the info I was looking to learn about!

Thursday, December 31, 2020 - 3:12:41 PM - Srinivas Sunkara Back To Top (87992)
Very nice.
Thanks a lot.

Friday, May 22, 2020 - 3:28:47 AM - Ellie Back To Top (85721)

Very, very helpful. Lifesaver and now I have new tools in the toolbox.


Thursday, February 27, 2020 - 5:10:25 AM - Alex Back To Top (84818)

Amazing article! 
Thanks a lot!


Wednesday, June 26, 2019 - 7:58:45 AM - Rui Back To Top (81593)

Thanks for this article! I can finally "see" how far the backup verification is... 😊


Wednesday, October 24, 2018 - 5:52:39 PM - Rod Back To Top (78048)

 

update: the 100% status lasted ~5 minutes after a 45 minute restore then finished


Tuesday, October 23, 2018 - 11:52:02 PM - Rod Back To Top (78038)

Though, interestingly, the query now shows 100% complete, but the estimated finish time keeps adjusting to the CURRENT time and the command hasn't finished yet. Not sure what's going on here.


Tuesday, October 23, 2018 - 11:48:02 PM - Rod Back To Top (78037)

 

Thanks for this great information. Like other commenters I was in the middle of a long restore and progress information was very helpful.


Sunday, September 9, 2018 - 1:19:26 PM - RAJA Back To Top (77477)

NICE ARTICLE


Thursday, May 17, 2018 - 11:57:38 AM - KC Back To Top (75968)

Great read thanks. That Using DMVs tip is a gamechanger. I am in the middle of restoring a HUGE database and have absolutely no clue of how far it's progressing. Now i know. Thanks!

 


Wednesday, April 4, 2018 - 12:04:33 PM - Hiram Back To Top (75608)

Found this clause to work better since backup operation might be doing a verify as well. ie. restore header...

SELECT session_id as SPID, command, a.text AS Query, start_time, percent_complete, dateadd(second,estimated_completion_time/1000, getdate()) as estimated_completion_time 

FROM sys.dm_exec_requests r CROSS APPLY sys.dm_exec_sql_text(r.sql_handle) a 

WHERE r.command like 'BACKUP%'

or r.command like 'RESTORE%'

Thx,

Hiram


Wednesday, October 25, 2017 - 5:11:14 PM - MD FAIYAZ AHMED Back To Top (68787)

Q)T-SQL Script to check how much percent restore 

SELECT r.session_id,r.command,CONVERT(NUMERIC(6,2),r.percent_complete)

AS [Percent Complete],CONVERT(VARCHAR(20),DATEADD(ms,r.estimated_completion_time,GetDate()),20) AS [ETA Completion Time],

CONVERT(NUMERIC(10,2),r.total_elapsed_time/1000.0/60.0) AS [Elapsed Min],

CONVERT(NUMERIC(10,2),r.estimated_completion_time/1000.0/60.0) AS [ETA Min],

CONVERT(NUMERIC(10,2),r.estimated_completion_time/1000.0/60.0/60.0) AS [ETA Hours],

CONVERT(VARCHAR(1000),(SELECT SUBSTRING(text,r.statement_start_offset/2,

CASE WHEN r.statement_end_offset = -1 THEN 1000 ELSE (r.statement_end_offset-r.statement_start_offset)/2 END)

FROM sys.dm_exec_sql_text(sql_handle)))

FROM sys.dm_exec_requests r WHERE command IN ('RESTORE DATABASE','BACKUP DATABASE') 

 


Wednesday, June 28, 2017 - 8:13:11 AM - alpert Back To Top (58488)

thanks 

 


Saturday, March 11, 2017 - 12:53:09 AM - Nagarjuna Back To Top (48809)
  1. Hi nitansh
  2. Thanks for ur tips
  3. It was very helpful.
  4. Thanks for ur Time

Monday, February 27, 2017 - 11:25:36 AM - pappu Back To Top (46735)

Thanks for this article. 

 


Wednesday, December 28, 2016 - 1:14:47 AM - Jeff Moden Back To Top (45056)

 Nice tip, Nitansh.  I'm especially appreciative of the "Note about restores" section.  I appreciate the time you took to write this post. 


Monday, October 3, 2016 - 7:46:38 AM - Andre Back To Top (43479)

 Nice post! But... Can't make it work when using the SSMS 2016 with a SQL Server 2014. The script returns: 

 

Msg 102, Level 15, State 1, Line 2

Incorrect syntax near '.'.

 


Monday, September 19, 2016 - 12:53:42 PM - Mike Back To Top (43354)

As mentioned in the section labeled "Notes about Restores", there can be issues with the dmv. The record returned by dm_exec_requests may disappear before the database is fully restored when restoring WITH NORECOVERY. I experience this when I restore from a network location. I have code that checks for a restore to be completed on a secondary Availability Group replica in my staging envinroment before joining the database to the AG. The join fails with error 927 "database is in the middle of a restore". I currently have no reliable way to check for this. So, usually sys.dm_exec_requests is very useful. Just be aware that it is not perfect.

 


Monday, April 4, 2016 - 3:49:33 AM - krishna mutyala Back To Top (41129)

Good.

Q)how to find backup running status without using stats in sql server

select * from sys.dm_exec_requests where command in ('BACKUP DATABASE')

select percent_complete from sys.dm_exec_requests where command in ('BACKUP DATABASE')


Monday, March 21, 2016 - 2:42:42 AM - Saravanan A Back To Top (41011)

Monitor the progress of backup database script(DMV) is very useful.

Thankyou very much. 

 


Tuesday, March 24, 2015 - 2:53:44 AM - enno Back To Top (36650)

Thanx for DMVs script.  Very useful!!


Monday, February 23, 2015 - 5:21:02 AM - Rodrigo Back To Top (36314)

Thank you for the post. The DMV query is very useful.


Friday, September 19, 2014 - 2:24:58 PM - Zach Back To Top (34631)

This worked perfectly!!!  A backup was taking longer than seven hours.  I ran this and saw that it was 95% done.  Saved me from rebooting out of what I thought was a hung server.

Thank you!

Zach


Friday, January 10, 2014 - 1:56:59 PM - Israel Greß Back To Top (28014)

Thank you for the example, it was very useful!

Greetings from Mexico


Thursday, May 30, 2013 - 11:46:08 AM - Tim Back To Top (25203)

I've run the script (thx) and it seems that my percent_complete is not changing (67.14183) while the estimated_completion_time keeps marching forward in time.


Friday, May 24, 2013 - 3:09:51 AM - Yuri Back To Top (25118)

Hello, Nitansh.

Is there a way to increase progress precision up to 1% while using GUI (SSMS)?


Tuesday, April 23, 2013 - 8:28:42 AM - Sreerag Back To Top (23509)

Here is the actual code..

SELECT session_id as SPID, command, a.text AS Query, start_time, percent_complete, dateadd(second,estimated_completion_time/1000, getdate()) as estimated_completion_time
FROM sys.dm_exec_requests r CROSS APPLY sys.dm_exec_sql_text(r.sql_handle) a
WHERE r.command in ('BACKUP LOG')


Sunday, March 3, 2013 - 6:55:53 PM - Jorge Rivera Back To Top (22539)

Thanks for sharing your tip.  It will help a lot, specially when running the script.


Friday, August 3, 2012 - 2:54:20 AM - dinesh Back To Top (18897)

SELECT session_id as SPID, command, a.text AS Query, start_time, percent_complete, dateadd(second,estimated_completion_time/1000, getdate()) as estimated_completion_time
FROM sys.dm_exec_requests r CROSS APPLY sys.dm_exec_sql_text(r.sql_handle) a
WHERE r.command in ('BACKUP DATABASE','RESTORE DATABASE')   this not giving nothing...

What is meaning of it ??

 


Thursday, May 31, 2012 - 8:40:32 AM - Sagar Patel Back To Top (17745)

Hello Nitansh,

 

i faced the problem of restoring the database from live server to test server for the testing purpose but i found the error PERMISSION DENIED, so if i want to give RESTORATION rights oif the database to some user , how will i give rights ?

 

Sagar Patel

 

 


Tuesday, January 17, 2012 - 8:26:12 AM - Nitansh Back To Top (15678)

Thank you Shashi.




Tuesday, January 17, 2012 - 12:32:22 AM - Shashi Back To Top (15673)

Nitansh,

Thank you very much, This is really helpful and you have done a great job!!


Thursday, April 28, 2011 - 9:26:49 PM - Nitansh Back To Top (13716)

Thanks Michael.


Thursday, April 28, 2011 - 6:40:07 AM - Michael D Back To Top (13709)

Great article, thanks for sharing. 


Tuesday, March 29, 2011 - 10:44:46 AM - Nitansh Back To Top (13368)

Thanks Manuel. 


Tuesday, March 29, 2011 - 8:52:25 AM - Manuel A. Rodriguez Back To Top (13367)

Hello Nitansh,

I would like to thank you for this very good information. I am asked by our R&D department to restore production databases to our development environment frequently. Most of the databases that they use are very small but occasionally they will ask for one of our larger production databases. The examples that you have presented will help greatly in the process. Once again, thank you for your generous contribution.

Manuel A. Rodriguez















get free sql tips
agree to terms