diff --git a/include/class.cron.php b/include/class.cron.php
index e545c5afb7acddf48a97f6e9c0b05b252c5ac116..232d6bf2bee90bad3824e238ee77812ee411a187 100644
--- a/include/class.cron.php
+++ b/include/class.cron.php
@@ -51,6 +51,11 @@ class Cron {
         AttachmentFile::deleteOrphans();
     }
 
+    function CleanExpiredSessions() {
+        require_once(INCLUDE_DIR.'class.ostsession.php');
+        DbSessionBackend::cleanup();
+    }
+
     function MaybeOptimizeTables() {
         // Once a week on a 5-minute cron
         $chance = rand(1,2000);
@@ -100,6 +105,7 @@ class Cron {
         self::MailFetcher();
         self::TicketMonitor();
         self::PurgeLogs();
+        self::CleanExpiredSessions();
         // Run file purging about every 10 cron runs
         if (mt_rand(1, 9) == 4)
             self::CleanOrphanedFiles();
diff --git a/include/class.ostsession.php b/include/class.ostsession.php
index dbb5cf6312551abc4e24e4eb905eca53e0a74188..51f8bd2fc5e934dd2b67e95518999959fdbedb30 100644
--- a/include/class.ostsession.php
+++ b/include/class.ostsession.php
@@ -158,6 +158,10 @@ abstract class SessionBackend {
         return $this->update($id, $i['touched'] ? session_encode() : $data);
     }
 
+    function cleanup() {
+        $this->gc(0);
+    }
+
     abstract function read($id);
     abstract function update($id, $data);
     abstract function destroy($id);
@@ -220,6 +224,10 @@ extends SessionBackend {
         return SessionData::objects()->filter(['session_id' => $id])->delete();
     }
 
+    function cleanup() {
+        self::gc(0);
+    }
+
     function gc($maxlife){
         SessionData::objects()->filter([
             'session_expire__lte' => SqlFunction::NOW()