Database retention policies don't work

Database retention policies don't work

avatar

Hi!

We configured database retention to delete logs older than 1 year, but the logs still stay in the database. It has been like this through multiple DVLS updates with no change. We are currently on 2026.1.24.0. For some tables, we have entries from 2019.

I have not clicked "Clean up now" yet, because I want to verify it works automatically.



I checked some of the "_Archive" tables, and none of them contain any entries.

Scheduler service is installed and running. Automatic backups work.

How to troubleshoot further?

Thank you!
Best regards, Daniel

e260a8a3-8638-4aba-b0fc-69924bdc848a.png

All Comments (12)

avatar

Hello,

Could you please verify in the server logs in DVLS to see if you might have some logs related to the failure of the cleanup?

The scheduler might be unable to delete or archive the logs because there might be too many for the first run.

Would it be possible to run a Disk usage by top table report in SSMS and share it with us through email at service@devolutions.net?

Best regards,

avatar

Hi!

I couldn't find anything in the logs. But I noticed the "Scheduler log path" is empty in the logging settings. Should there be a path configured (or used) by default? I don't recall we ever changed this.



I ran the report, I'll just share the top tables here:

Table             Record count
----------------- ------------
LogMessage_Old    763182
ConnectionLog     693600
ConnectionHistory 89717
LogMessage        47431
LoginHistory      17385
Connections       10654
LoginAttempt      9263
BackupLog         1995
...

c67bca15-8469-4b32-9b34-7e0108ebe415.png

avatar

I found log files in the scheduler's service account "%LocalAppData%\Temp" directory.

They contain entries like the following, but nothing that looks like an error

2026-08-19 10:29:20.502 +02:00 [DBG] Devolutions.Server.Service.Tasks.DatabaseCleanupStartStopTask.DoWork started
2026-08-19 10:29:20.503 +02:00 [DBG] Devolutions.Server.Service.Tasks.DatabaseCleanupStartStopTask.DoWork completed in 1 ms
avatar

Hello,

Thank you for the confirmation.

You do not have to need to configure the scheduler log path unless you are actively troubleshooting the scheduler service.

I think it is highly possible that the scheduler service in failing to run the cleanup because some tables are a bit too big. We would recommend cleaning up the tables manually first.

I will send you a direct message with a SQL query to do a first manual cleanup of the logs, and then the scheduler should be able to run it automatically afterwards.

Best regards,

avatar

Hi William!

I ran the manual cleanup for a longer retention period (2 years archive, 3 years delete instead of 1 year archive, 2 years delete)

The script you sent me had a problem though: It adds the retention time rather than subtracting it from the current date, so it would move/delete all the logs, not just old logs.

-- Define variables for retention periods
DECLARE @NumberOfMonthToArchive INT = 12
DECLARE @NumberOfYearToDelete INT = 10
DECLARE @ArchiveBefore DATETIME = DATEADD(MONTH, @NumberOfMonthToArchive, GETDATE());
DECLARE @DeleteBefore DATETIME = DATEADD(YEAR, @NumberOfYearToDelete, GETDATE());
 
-- For testing
SELECT @ArchiveBefore, @DeleteBefore

-- Output (executed on 2026-08-20):
-- 2036-08-20 09:45:53.923
-- 2027-08-20 09:45:53.923


I fixed the script before running it by adding minus signs

I also ran this query to get an overview before and after the manual cleanup:

Before:
be16dfaa-8c83-451a-a563-a0843115d903
After:
8a6ab679-55cd-4a4d-b7f0-90b93e467db7
I will wait some time and check if the automatic cleanup works now.

Do you think I should also manually clean up the LogMessage_Old table? It has the most (and oldest) records here.
There's also the ConnectionHistory table, which I forgot to include in the overview query. It also has over 89k entries, and should be included in the cleanup according to the settings GUI.

Thank you!

Best regards,
Daniel

8a6ab679-55cd-4a4d-b7f0-90b93e467db7.png

be16dfaa-8c83-451a-a563-a0843115d903.png

avatar

Hello,

Sorry about the issue with the script. Yes, I would suggest cleaning any table that has an _Archive version. My script was done some time ago and new tables were added to logs so it is possible that some might be missing from my original script. I will look at cleaning it up.

Best regards,

avatar

Thank you!

I have built a list of database table names based off the existing _Archive tables and the Log categories listed in the settings UI:

Logs
	Backup Logs
		BackupLog
		BackupLog_Archive

	Connection logs
		ConnectionLog
		ConnectionLog_Archive

	Login attempt
		LoginAttempt
		LoginAttempt_Archive

	Login history
		LoginHistory
		LoginHistory_Archive

	Message Logs (Log messages?)
		LogMessage
		LogMessage_Archive
		LogMessage_Old
		LogMessage_Old_Archive

	PAM logs
		PamLog
		PamLog_Archive

	User info history
		UserInfoHistory
		UserInfoHistory_Archive

PAM
	Checkout
		PamCheckout
		PamCheckout_Archive

	Heartbeat
		PamHeartbeat
		PamHeartbeat_Archive

Connections
	Connection history
		ConnectionHistory
		ConnectionHistory_Archive

Privileged sessions monitoring
	Remote sessions
		RemoteSession
		RemoteSession_Archive

	Traffic events
		TrafficEvent
		TrafficEvent_Archive


But with some tables (most importantly ConnectionHistory) I'm not sure which field to use to compare the "DeleteBefore" timestamps
Currently I'm looking at the following fields, but I'm not sure they are the correct ones:

BackupLog.StartDate, BackupLog_Archive.StartDate, ConnectionLog.CreationDate, ConnectionLog_Archive.CreationDate, LoginAttempt.CreationDate, LoginAttempt_Archive.CreationDate, LoginHistory.CreationDate, LoginHistory_Archive.CreationDate, LogMessage.CreationDate, LogMessage_Archive.CreationDate, LogMessage_Old.CreationDate, LogMessage_Old_Archive.CreationDate, PamLog.DateTime, PamLog_Archive.DateTime, UserInfoHistory.ModifiedDate, UserInfoHistory_Archive.ModifiedDate, PamCheckout.CheckoutDateTime, PamCheckout_Archive.CheckoutDateTime, PamHeartbeat.HeartbeatDateTime, PamHeartbeat_Archive.HeartbeatDateTime, ConnectionHistory.ModifiedDate, ConnectionHistory_Archive.ModifiedDate, RemoteSession.StartDateTime, RemoteSession_Archive.StartDateTime, TrafficEvent.ConnectedAt, TrafficEvent_Archive.ConnectedAt


These tables have multiple datetime fields for example:

  • BackupLog.StartDate, BackupLog.EndDate
  • ConnectionHistory.ModifiedDate, ConnectionHistory.CreationDate,
  • TrafficEvent.ConnectedAt, TrafficEvent.DisconnectedAt, TrafficEvent.CreatedAt


By the way, I think "Message Logs" should be changed to "Log messages" in the UI

Here's an overview of our log table usage currently:

Best regards,
Daniel

7430b1e4-de14-45f1-9f64-89799eb92689.png

avatar

Hello,

I sent you a revised script with everything needed to run a test and the full cleanup.

Please let me know if this new version helps.

Best regards,

avatar

It worked!

Your new script's output from Step 2:

ARCHIVE LogMessage -> LogMessage_Archive : 0 rows moved
PURGE   LogMessage_Archive : 0 rows deleted (older than 36 months)
ARCHIVE LogMessage_Old -> LogMessage_Old_Archive : 696062 rows moved
PURGE   LogMessage_Old_Archive : 654813 rows deleted (older than 36 months)
ARCHIVE BackupLog -> BackupLog_Archive : 0 rows moved
PURGE   BackupLog_Archive : 0 rows deleted (older than 36 months)
ARCHIVE ConnectionLog -> ConnectionLog_Archive : 222 rows moved
PURGE   ConnectionLog_Archive : 0 rows deleted (older than 36 months)
ARCHIVE ConnectionHistory -> ConnectionHistory_Archive : 81781 rows moved
PURGE   ConnectionHistory_Archive : 76883 rows deleted (older than 36 months)
ARCHIVE LoginAttempt -> LoginAttempt_Archive : 0 rows moved
PURGE   LoginAttempt_Archive : 0 rows deleted (older than 36 months)
ARCHIVE LoginHistory -> LoginHistory_Archive : 1 rows moved
PURGE   LoginHistory_Archive : 0 rows deleted (older than 36 months)
ARCHIVE UserInfoHistory -> UserInfoHistory_Archive : 0 rows moved
PURGE   UserInfoHistory_Archive : 0 rows deleted (older than 36 months)
ARCHIVE PamLog -> PamLog_Archive : 0 rows moved
PURGE   PamLog_Archive : 0 rows deleted (older than 36 months)
ARCHIVE PamHeartbeat -> PamHeartbeat_Archive : 0 rows moved
PURGE   PamHeartbeat_Archive : 0 rows deleted (older than 36 months)
Archive + purge done.


It ran for about 6 minutes.

Here's my summary after the manual cleanup:


Entries older than 2 years were moved to _Archive tables, Entries older than 3 years were permanently deleted.

I'll check tomorrow if the automatic cleanup works now.

Thank you!

f7a314a8-4ac7-4dc3-b82e-6985ceb981ab.png

avatar

Hello,

Thank you for the confirmation.

For the Archived logs, I would suggest archiving earlier than 2 years. Archived logs are still accessible but they will only be loaded when required instead of being loaded when you open a vault.

When you open a vault, you are loading the entries and all logs attached to these entries that are not archived. By archiving these logs (let's say older than 1 month as an example), we can accelerate the process of opening vaults. Then when you open the log tab on an entry and select a filter that contains logs older than 1 month, then archived logs will be loaded for that specific entry only.

Best regards,

avatar

OK, good to know! Thank you!

btw I also completed Step 3 from the script (Shrinkfile + Index rebuild)

avatar

Hello,

Thank you for the confirmation.

Now we just need to keep an eye out to see if the automatic cleanup runs normally. I would suggest capturing the number of rows in the Archived tables and see if the number changes in a couple of days.

Best regards,