diff --git a/notifications/migrations/0002_notification_url_code.py b/notifications/migrations/0002_notification_url_code.py
new file mode 100644
index 0000000000000000000000000000000000000000..b8922d06cd68ebd87772913a30232203c46fe343
--- /dev/null
+++ b/notifications/migrations/0002_notification_url_code.py
@@ -0,0 +1,20 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.4 on 2018-12-04 19:11
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('notifications', '0001_initial'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='notification',
+            name='url_code',
+            field=models.CharField(blank=True, max_length=255),
+        ),
+    ]
diff --git a/submissions/admin.py b/submissions/admin.py
index 7b7a19e8e48d469d949d8059ed91b6ca4f809ae7..78df5387cad6306dcc075d99576e120b1f57b910 100644
--- a/submissions/admin.py
+++ b/submissions/admin.py
@@ -65,8 +65,9 @@ class SubmissionAdmin(GuardedModelAdmin):
         }),
         ('Versioning', {
             'fields': (
+                'thread_hash',
                 'is_current',
-                'is_resubmission',
+                '_is_resubmission',
                 'is_resubmission_of',
                 'list_of_changes'),
         }),
diff --git a/submissions/forms.py b/submissions/forms.py
index 67f6d5b4513a3e145021b8e7f7b1533ceb96bf57..47668d7bdfdb4fc1a2dbc28feb523506391c37ba 100644
--- a/submissions/forms.py
+++ b/submissions/forms.py
@@ -242,11 +242,12 @@ class SubmissionService:
         Submission.objects.filter(id=submission.id).update(
             open_for_reporting=True,
             open_for_commenting=True,
-            is_resubmission=True,
+            is_resubmission_of=self.latest_submission,
             visible_pool=True,
             refereeing_cycle=CYCLE_UNDETERMINED,
             editor_in_charge=self.latest_submission.editor_in_charge,
-            status=STATUS_EIC_ASSIGNED)
+            status=STATUS_EIC_ASSIGNED,
+            thread_hash=self.latest_submission.thread_hash)
 
         # Add author(s) (claim) fields
         submission.authors.add(*self.latest_submission.authors.all())
diff --git a/submissions/managers.py b/submissions/managers.py
index 64ac5791882c5a9f6daf3984e973e431afb793e6..dc73320955c2e4f1e1cc2c8578c6c7e0fd7f1a9a 100644
--- a/submissions/managers.py
+++ b/submissions/managers.py
@@ -17,6 +17,8 @@ now = timezone.now()
 class SubmissionQuerySet(models.QuerySet):
     def _newest_version_only(self, queryset):
         """
+        TODO: Make more efficient... with agregation or whatever.
+
         The current Queryset should return only the latest version
         of the Arxiv submissions known to SciPost.
 
@@ -157,7 +159,7 @@ class SubmissionQuerySet(models.QuerySet):
         (including subsequent resubmissions, even if those came in later).
         """
         identifiers = []
-        for sub in self.filter(is_resubmission=False,
+        for sub in self.filter(is_resubmission_of__isnull=True,
                                submission_date__range=(from_date, until_date)):
             identifiers.append(sub.preprint.identifier_wo_vn_nr)
         return self.filter(preprint__identifier_wo_vn_nr__in=identifiers)
diff --git a/submissions/migrations/0047_auto_20181204_2011.py b/submissions/migrations/0047_auto_20181204_2011.py
new file mode 100644
index 0000000000000000000000000000000000000000..15fe0d2cb0de419eb07beb1d6f8954efdf8a3bfc
--- /dev/null
+++ b/submissions/migrations/0047_auto_20181204_2011.py
@@ -0,0 +1,25 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.4 on 2018-12-04 19:11
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('submissions', '0046_auto_20181130_1013'),
+    ]
+
+    operations = [
+        migrations.RenameField(
+            model_name='submission',
+            old_name='is_resubmission',
+            new_name='_is_resubmission',
+        ),
+        migrations.AlterField(
+            model_name='submission',
+            name='submission_type',
+            field=models.CharField(blank=True, choices=[('Letter', 'Letter (broad-interest breakthrough results)'), ('Article', 'Article (in-depth reports on specialized research)'), ('Review', 'Review (candid snapshot of current research in a given area)')], max_length=10),
+        ),
+    ]
diff --git a/submissions/migrations/0048_submission_thread_hash.py b/submissions/migrations/0048_submission_thread_hash.py
new file mode 100644
index 0000000000000000000000000000000000000000..ddf50c99d378afb379eedca6278da7bf875a29b6
--- /dev/null
+++ b/submissions/migrations/0048_submission_thread_hash.py
@@ -0,0 +1,21 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.4 on 2018-12-04 19:37
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import uuid
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('submissions', '0047_auto_20181204_2011'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='submission',
+            name='thread_hash',
+            field=models.UUIDField(default=uuid.uuid4),
+        ),
+    ]
diff --git a/submissions/migrations/0049_auto_20181204_2040.py b/submissions/migrations/0049_auto_20181204_2040.py
new file mode 100644
index 0000000000000000000000000000000000000000..bbcd903d8ecd1538e68965795fcfce6a74be4305
--- /dev/null
+++ b/submissions/migrations/0049_auto_20181204_2040.py
@@ -0,0 +1,35 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.4 on 2018-12-04 19:40
+from __future__ import unicode_literals
+
+import uuid
+
+from django.db import migrations
+
+
+def get_thread_ids(parent, submissions_list=[]):
+    successor = parent.successor.first()
+    if not successor:
+        return submissions_list
+
+    submissions_list.append(successor.id)
+    return get_thread_ids(successor, submissions_list)
+
+
+def populate_thread_hashes(apps, schema_editor):
+    Submission = apps.get_model('submissions', 'Submission')
+
+    for original_submission in Submission.objects.filter(is_resubmission_of__isnull=True):
+        children_ids = get_thread_ids(original_submission, [original_submission.id])
+        Submission.objects.filter(id__in=children_ids).update(thread_hash=uuid.uuid4())
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('submissions', '0048_submission_thread_hash'),
+    ]
+
+    operations = [
+        migrations.RunPython(populate_thread_hashes, reverse_code=migrations.RunPython.noop),
+    ]
diff --git a/submissions/models.py b/submissions/models.py
index 19e17e177442c13e6017c7ab265fc9e01982c0fa..f7348cfb610ade1639421d2518b357eb5885d74e 100644
--- a/submissions/models.py
+++ b/submissions/models.py
@@ -4,6 +4,7 @@ __license__ = "AGPL v3"
 
 import datetime
 import feedparser
+import uuid
 
 from django.contrib.postgres.fields import JSONField
 from django.contrib.contenttypes.fields import GenericRelation
@@ -77,7 +78,8 @@ class Submission(models.Model):
     visible_pool = models.BooleanField("Is visible in the Pool", default=False)
     is_resubmission_of = models.ForeignKey(
         'self', blank=True, null=True, related_name='successor')
-    is_resubmission = models.BooleanField(default=False)
+    thread_hash = models.UUIDField(default=uuid.uuid4)
+    _is_resubmission = models.BooleanField(default=False)
     refereeing_cycle = models.CharField(
         max_length=30, choices=SUBMISSION_CYCLES, default=CYCLE_DEFAULT, blank=True)
 
@@ -196,6 +198,10 @@ class Submission(models.Model):
         """Return url of the Submission detail page."""
         return reverse('submissions:submission', args=(self.preprint.identifier_w_vn_nr,))
 
+    @property
+    def is_resubmission(self):
+        return self.is_resubmission_of is not None
+
     @property
     def notification_name(self):
         """Return string representation of this Submission as shown in Notifications."""
@@ -232,13 +238,12 @@ class Submission(models.Model):
     def original_submission_date(self):
         """Return the submission_date of the first Submission in the thread."""
         return Submission.objects.filter(
-            preprint__identifier_wo_vn_nr=self.preprint.identifier_wo_vn_nr).first().submission_date
+            thread_hash=self.thread_hash, is_resubmission_of__isnull=True).first().submission_date
 
     @property
     def thread(self):
         """Return all (public) Submissions in the database in this ArXiv identifier series."""
-        return Submission.objects.public().filter(
-            preprint__identifier_wo_vn_nr=self.preprint.identifier_wo_vn_nr).order_by(
+        return Submission.objects.public().filter(thread_hash=self.thread_hash).order_by(
                 '-preprint__vn_nr')
 
     @cached_property
@@ -253,8 +258,7 @@ class Submission(models.Model):
 
     def get_other_versions(self):
         """Return queryset of other Submissions with this ArXiv identifier series."""
-        return Submission.objects.filter(
-            preprint__identifier_wo_vn_nr=self.preprint.identifier_wo_vn_nr).exclude(pk=self.id)
+        return Submission.objects.filter(thread_hash=self.thread_hash).exclude(pk=self.id)
 
     def count_accepted_invitations(self):
         """Count number of accepted RefereeInvitations for this Submission."""