diff --git a/src/org/thoughtcrime/securesms/database/MmsDatabase.java b/src/org/thoughtcrime/securesms/database/MmsDatabase.java
index 23b7fc63a9..12cb25ca17 100644
--- a/src/org/thoughtcrime/securesms/database/MmsDatabase.java
+++ b/src/org/thoughtcrime/securesms/database/MmsDatabase.java
@@ -486,10 +486,11 @@ public class MmsDatabase extends MessagingDatabase {
     return result;
   }
 
-  public void setTimestampRead(SyncMessageId messageId) {
-    MmsAddressDatabase addressDatabase = DatabaseFactory.getMmsAddressDatabase(context);
-    SQLiteDatabase     database        = databaseHelper.getWritableDatabase();
-    Cursor             cursor          = null;
+  public List<Pair<Long, Long>> setTimestampRead(SyncMessageId messageId, long expireStarted) {
+    MmsAddressDatabase     addressDatabase = DatabaseFactory.getMmsAddressDatabase(context);
+    SQLiteDatabase         database        = databaseHelper.getWritableDatabase();
+    List<Pair<Long, Long>> expiring        = new LinkedList<>();
+    Cursor                 cursor          = null;
 
     try {
       cursor = database.query(TABLE_NAME, new String[] {ID, THREAD_ID, MESSAGE_BOX}, DATE_SENT + " = ?", new String[] {String.valueOf(messageId.getTimetamp())}, null, null, null, null);
@@ -503,11 +504,19 @@ public class MmsDatabase extends MessagingDatabase {
             String theirAddress = canonicalizeNumberOrGroup(context, storedAddress);
 
             if (ourAddress.equals(theirAddress) || GroupUtil.isEncodedGroup(theirAddress)) {
-              long id       = cursor.getLong(cursor.getColumnIndexOrThrow(ID));
-              long threadId = cursor.getLong(cursor.getColumnIndexOrThrow(THREAD_ID));
+              long id        = cursor.getLong(cursor.getColumnIndexOrThrow(ID));
+              long threadId  = cursor.getLong(cursor.getColumnIndexOrThrow(THREAD_ID));
+              long expiresIn = cursor.getLong(cursor.getColumnIndexOrThrow(EXPIRES_IN));
 
-              database.execSQL("UPDATE " + TABLE_NAME + " SET " + READ + " = 1 WHERE " + ID + " = ?",
-                               new String[] {String.valueOf(id)});
+              ContentValues values = new ContentValues();
+              values.put(READ, 1);
+
+              if (expiresIn > 0) {
+                values.put(EXPIRE_STARTED, expireStarted);
+                expiring.add(new Pair<>(id, expiresIn));
+              }
+
+              database.update(TABLE_NAME, values, ID_WHERE, new String[]{String.valueOf(id)});
 
               DatabaseFactory.getThreadDatabase(context).updateReadState(threadId);
               notifyConversationListeners(threadId);
@@ -521,6 +530,8 @@ public class MmsDatabase extends MessagingDatabase {
       if (cursor != null)
         cursor.close();
     }
+
+    return expiring;
   }
 
   public void setAllMessagesRead() {
diff --git a/src/org/thoughtcrime/securesms/database/SmsDatabase.java b/src/org/thoughtcrime/securesms/database/SmsDatabase.java
index 2a303bf9b1..d9483a54bd 100644
--- a/src/org/thoughtcrime/securesms/database/SmsDatabase.java
+++ b/src/org/thoughtcrime/securesms/database/SmsDatabase.java
@@ -348,12 +348,13 @@ public class SmsDatabase extends MessagingDatabase {
     return results;
   }
 
-  public void setTimestampRead(SyncMessageId messageId) {
-    SQLiteDatabase database     = databaseHelper.getWritableDatabase();
-    Cursor         cursor       = null;
+  public List<Pair<Long, Long>> setTimestampRead(SyncMessageId messageId, long expireStarted) {
+    SQLiteDatabase         database = databaseHelper.getWritableDatabase();
+    List<Pair<Long, Long>> expiring = new LinkedList<>();
+    Cursor                 cursor   = null;
 
     try {
-      cursor = database.query(TABLE_NAME, new String[] {ID, THREAD_ID, ADDRESS, TYPE},
+      cursor = database.query(TABLE_NAME, new String[] {ID, THREAD_ID, ADDRESS, TYPE, EXPIRES_IN},
                               DATE_SENT + " = ?", new String[] {String.valueOf(messageId.getTimetamp())},
                               null, null, null, null);
 
@@ -363,11 +364,18 @@ public class SmsDatabase extends MessagingDatabase {
           String ourAddress   = canonicalizeNumber(context, cursor.getString(cursor.getColumnIndexOrThrow(ADDRESS)));
 
           if (ourAddress.equals(theirAddress)) {
-            long threadId = cursor.getLong(cursor.getColumnIndexOrThrow(THREAD_ID));
+            long id        = cursor.getLong(cursor.getColumnIndexOrThrow(ID));
+            long threadId  = cursor.getLong(cursor.getColumnIndexOrThrow(THREAD_ID));
+            long expiresIn = cursor.getLong(cursor.getColumnIndexOrThrow(EXPIRES_IN));
 
             ContentValues contentValues = new ContentValues();
             contentValues.put(READ, 1);
 
+            if (expiresIn > 0) {
+              contentValues.put(EXPIRE_STARTED, expireStarted);
+              expiring.add(new Pair<>(id, expiresIn));
+            }
+
             database.update(TABLE_NAME, contentValues, ID_WHERE, new String[] {cursor.getLong(cursor.getColumnIndexOrThrow(ID)) + ""});
 
             DatabaseFactory.getThreadDatabase(context).updateReadState(threadId);
@@ -380,6 +388,8 @@ public class SmsDatabase extends MessagingDatabase {
     } finally {
       if (cursor != null) cursor.close();
     }
+
+    return expiring;
   }
 
   public void setAllMessagesRead() {
diff --git a/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java b/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java
index 8dc3355b7c..230ec3f0b3 100644
--- a/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java
+++ b/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java
@@ -151,7 +151,7 @@ public class PushDecryptJob extends ContextJob {
 
         if      (syncMessage.getSent().isPresent())    handleSynchronizeSentMessage(masterSecret, envelope, syncMessage.getSent().get(), smsMessageId);
         else if (syncMessage.getRequest().isPresent()) handleSynchronizeRequestMessage(masterSecret, syncMessage.getRequest().get());
-        else if (syncMessage.getRead().isPresent())    handleSynchronizeReadMessage(masterSecret, syncMessage.getRead().get());
+        else if (syncMessage.getRead().isPresent())    handleSynchronizeReadMessage(masterSecret, syncMessage.getRead().get(), envelope.getTimestamp());
         else                                           Log.w(TAG, "Contains no known sync types...");
       }
 
@@ -295,11 +295,24 @@ public class PushDecryptJob extends ContextJob {
   }
 
   private void handleSynchronizeReadMessage(@NonNull MasterSecretUnion masterSecret,
-                                            @NonNull List<ReadMessage> readMessages)
+                                            @NonNull List<ReadMessage> readMessages,
+                                            long envelopeTimestamp)
   {
     for (ReadMessage readMessage : readMessages) {
-      DatabaseFactory.getSmsDatabase(context).setTimestampRead(new SyncMessageId(readMessage.getSender(), readMessage.getTimestamp()));
-      DatabaseFactory.getMmsDatabase(context).setTimestampRead(new SyncMessageId(readMessage.getSender(), readMessage.getTimestamp()));
+      List<Pair<Long, Long>> expiringText = DatabaseFactory.getSmsDatabase(context).setTimestampRead(new SyncMessageId(readMessage.getSender(), readMessage.getTimestamp()), envelopeTimestamp);
+      List<Pair<Long, Long>> expiringMedia = DatabaseFactory.getMmsDatabase(context).setTimestampRead(new SyncMessageId(readMessage.getSender(), readMessage.getTimestamp()), envelopeTimestamp);
+
+      for (Pair<Long, Long> expiringMessage : expiringText) {
+        ApplicationContext.getInstance(context)
+                          .getExpiringMessageManager()
+                          .scheduleDeletion(expiringMessage.first, false, envelopeTimestamp, expiringMessage.second);
+      }
+
+      for (Pair<Long, Long> expiringMessage : expiringMedia) {
+        ApplicationContext.getInstance(context)
+                          .getExpiringMessageManager()
+                          .scheduleDeletion(expiringMessage.first, true, envelopeTimestamp, expiringMessage.second);
+      }
     }
 
     MessageNotifier.updateNotification(context, masterSecret.getMasterSecret().orNull());