diff --git a/SAS/TMSS/backend/src/tmss/tmssapp/migrations/0001_initial.py b/SAS/TMSS/backend/src/tmss/tmssapp/migrations/0001_initial.py
index 5d3dbb98604d49b4a9aaf82dba99cc37bd3dcabe..4b979319b6d45e1b2ccd8faf40e8fdb075aea3ed 100644
--- a/SAS/TMSS/backend/src/tmss/tmssapp/migrations/0001_initial.py
+++ b/SAS/TMSS/backend/src/tmss/tmssapp/migrations/0001_initial.py
@@ -1,4 +1,4 @@
-# Generated by Django 3.0.9 on 2021-01-29 16:33
+# Generated by Django 3.0.9 on 2021-02-11 13:51
 
 from django.conf import settings
 import django.contrib.postgres.fields
@@ -131,9 +131,6 @@ class Migration(migrations.Migration):
                 ('size', models.BigIntegerField(help_text='Dataproduct size, in bytes. Used for accounting purposes. NULL if size is (yet) unknown (NULLable).', null=True)),
                 ('feedback_doc', django.contrib.postgres.fields.jsonb.JSONField(help_text='Dataproduct properties, as reported by the producing process.')),
             ],
-            options={
-                'abstract': False,
-            },
         ),
         migrations.CreateModel(
             name='DataproductArchiveInfo',
@@ -387,7 +384,6 @@ class Migration(migrations.Migration):
                 ('private_data', models.BooleanField(default=True, help_text='True if data of this project is sensitive. Sensitive data is not made public.')),
                 ('expert', models.BooleanField(default=False, help_text='Expert projects put more responsibility on the PI.')),
                 ('filler', models.BooleanField(default=False, help_text='Use this project to fill up idle telescope time.')),
-                ('archive_subdirectory', models.CharField(help_text='Subdirectory in which this project will store its data in the LTA. The full directory is constructed by prefixing with archive_location→directory.', max_length=1024)),
                 ('auto_pin', models.BooleanField(default=False, help_text='True if the output_pinned flag of tasks in this project should be set True on creation.')),
             ],
             options={
@@ -423,6 +419,12 @@ class Migration(migrations.Migration):
                 ('value', models.FloatField(help_text='Resource Quota value')),
             ],
         ),
+        migrations.CreateModel(
+            name='ProjectQuotaArchiveLocation',
+            fields=[
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+            ],
+        ),
         migrations.CreateModel(
             name='ProjectRole',
             fields=[
@@ -1205,6 +1207,16 @@ class Migration(migrations.Migration):
             name='specifications_template',
             field=models.ForeignKey(help_text='Schema used for specifications_doc.', on_delete=django.db.models.deletion.CASCADE, to='tmssapp.ReservationTemplate'),
         ),
+        migrations.AddField(
+            model_name='projectquotaarchivelocation',
+            name='archive_location',
+            field=models.ForeignKey(help_text='Location of an archive LTA cluster.', on_delete=django.db.models.deletion.PROTECT, to='tmssapp.Filesystem'),
+        ),
+        migrations.AddField(
+            model_name='projectquotaarchivelocation',
+            name='project_quota',
+            field=models.ForeignKey(help_text='Project to wich this quota belongs.', on_delete=django.db.models.deletion.PROTECT, related_name='project_quota', to='tmssapp.ProjectQuota'),
+        ),
         migrations.AddField(
             model_name='projectquota',
             name='project',
@@ -1240,11 +1252,6 @@ class Migration(migrations.Migration):
             name='PUT',
             field=models.ManyToManyField(blank=True, related_name='can_PUT', to='tmssapp.ProjectRole'),
         ),
-        migrations.AddField(
-            model_name='project',
-            name='archive_location',
-            field=models.ForeignKey(help_text='Ingest data to this LTA cluster only (NULLable). NULL means: no preference.', null=True, on_delete=django.db.models.deletion.PROTECT, to='tmssapp.Filesystem'),
-        ),
         migrations.AddField(
             model_name='project',
             name='cycles',
@@ -1500,8 +1507,8 @@ class Migration(migrations.Migration):
             model_name='dataproductarchiveinfo',
             index=django.contrib.postgres.indexes.GinIndex(fields=['tags'], name='tmssapp_dat_tags_ebf2ef_gin'),
         ),
-        migrations.AddIndex(
+        migrations.AddConstraint(
             model_name='dataproduct',
-            index=django.contrib.postgres.indexes.GinIndex(fields=['tags'], name='tmssapp_dat_tags_5932a3_gin'),
+            constraint=models.UniqueConstraint(fields=('directory', 'filename'), name='dataproduct_unique_path'),
         ),
     ]
diff --git a/SAS/TMSS/backend/src/tmss/tmssapp/models/specification.py b/SAS/TMSS/backend/src/tmss/tmssapp/models/specification.py
index 49754c503cb1d43976076d337ec735753280c475..44ecd759f2e655652fabe4a6f922af9665826b13 100644
--- a/SAS/TMSS/backend/src/tmss/tmssapp/models/specification.py
+++ b/SAS/TMSS/backend/src/tmss/tmssapp/models/specification.py
@@ -269,41 +269,13 @@ class Project(NamedCommonPK):
     filler = BooleanField(default=False, help_text='Use this project to fill up idle telescope time.')
     project_category = ForeignKey('ProjectCategory', null=True, on_delete=PROTECT, help_text='Project category.')
     period_category = ForeignKey('PeriodCategory', null=True, on_delete=PROTECT, help_text='Period category.')
-    archive_location = ForeignKey('Filesystem', null=True, on_delete=PROTECT, help_text='Ingest data to this LTA cluster only (NULLable). NULL means: no preference.')
-    archive_subdirectory = CharField(max_length=1024, help_text='Subdirectory in which this project will store its data in the LTA. The full directory is constructed by prefixing with archive_location→directory.')
     auto_pin = BooleanField(default=False, help_text='True if the output_pinned flag of tasks in this project should be set True on creation.')
 
-    def save(self, force_insert=False, force_update=False, using=None, update_fields=None):
-        if self.archive_subdirectory and not self.archive_subdirectory.endswith('/'):
-            raise ValueError('directory value must end with a trailing slash!')
-        if self.archive_subdirectory and self.archive_subdirectory.startswith('/'):
-            raise ValueError('directory value must be a relative path (and not start with a slash)!')
-
-        super().save(force_insert, force_update, using, update_fields)
-
-    # JK, 29/07/20 - after discussion with Sander, it turns out that the ticket TMSS-277 was a misunderstanding.
-    #  'default' does not refer to 'default values' that are supposed to be filled in by the backend.
-    #  It was meant to be 'resource_types displayed in the frontend by default', where the other resource_types are
-    #  optionally added to the set of quota. These can then be customized in the frontend and are created by the
-    #  frontend in the backend, but no quota are intended to be added automatically. So nothing is really  needed in
-    #  the backend for this (apart from the set of predefined resource_types).
-    #  There was some open question on whether there may be a required subset of quota that have to be enforced. So
-    #  I'll leave this in for now, until that question is cleared up.
-    #
-    # # also create default project quotas when projects are created
-    # def save(self, force_insert=False, force_update=False, using=None, update_fields=None):
-    #     creating = self._state.adding  # True on create, False on update
-    #     super().save(force_insert, force_update, using, update_fields)
-    #     if creating:
-    #         # todo: review these defaults for being sensible
-    #         ProjectQuota.objects.create(resource_type=ResourceType.objects.get(name="lta_storage"), value=1024^4, project=self)
-    #         ProjectQuota.objects.create(resource_type=ResourceType.objects.get(name="cep_storage"), value=1024^4, project=self)
-    #         ProjectQuota.objects.create(resource_type=ResourceType.objects.get(name="cep_processing_time"), value=60*60*24, project=self)
-    #         ProjectQuota.objects.create(resource_type=ResourceType.objects.get(name="lofar_observing_time"), value=60*60*24, project=self)
-    #         ProjectQuota.objects.create(resource_type=ResourceType.objects.get(name="lofar_observing_time_prio_a"), value=60*60*12, project=self)
-    #         ProjectQuota.objects.create(resource_type=ResourceType.objects.get(name="lofar_observing_time_prio_b"), value=60*60*12, project=self)
-    #         ProjectQuota.objects.create(resource_type=ResourceType.objects.get(name="support_time"), value=60*60*6, project=self)
-    #         ProjectQuota.objects.create(resource_type=ResourceType.objects.get(name="number_of_triggers"), value=42, project=self)
+    @cached_property
+    def duration(self) -> datetime.timedelta:
+        '''return the overall duration of all tasks of this scheduling unit
+        '''
+        return self.relative_stop_time - self.relative_start_time
 
 
 class ProjectQuota(Model):
@@ -312,6 +284,28 @@ class ProjectQuota(Model):
     resource_type = ForeignKey('ResourceType', on_delete=PROTECT, help_text='Resource type.')  # protected to avoid accidents
 
 
+class ProjectQuotaArchiveLocation(Model):
+    project_quota = ForeignKey('ProjectQuota', null=False, related_name="project_quota", on_delete=PROTECT, help_text='Project to wich this quota belongs.')
+    archive_location = ForeignKey('Filesystem', null=False, on_delete=PROTECT, help_text='Location of an archive LTA cluster.')
+
+    def save(self, force_insert=False, force_update=False, using=None, update_fields=None):
+        if self.project_quota.resource_type.quantity.value != Quantity.Choices.BYTES.value:
+            raise ValueError("A ProjectQuotaArchiveLocation should have its project_quota defined in a 'bytes' quantity")
+        if not self.archive_location.cluster.archive_site:
+            raise ValueError("The archive_location of a ProjectQuotaArchiveLocation should be an archive site")
+        super().save(force_insert, force_update, using, update_fields)
+
+    @cached_property
+    def archive_subdirectory(self) -> str:
+        '''return name of the subdirectory where this project is stored. By default and convention this the the lower_case project name'''
+        return self.project_quota.project.name.lower()
+
+    @cached_property
+    def full_archive_uri(self) -> str:
+        '''return full uri where this project is stored. By default and convention this the the lower_case project name'''
+        return "%s/%s/" % (self.archive_location.directory.rstrip('/'), self.archive_subdirectory)
+
+
 class ResourceType(NamedCommonPK):
     quantity = ForeignKey('Quantity', null=False, on_delete=PROTECT, help_text='The quantity of this resource type.')
 
diff --git a/SAS/TMSS/backend/src/tmss/tmssapp/populate.py b/SAS/TMSS/backend/src/tmss/tmssapp/populate.py
index 1bab1d23a677f2a114c42c27ef601f41316da879..6eae000487adfd897cdfcc6a9491f9f343cf4d54 100644
--- a/SAS/TMSS/backend/src/tmss/tmssapp/populate.py
+++ b/SAS/TMSS/backend/src/tmss/tmssapp/populate.py
@@ -175,6 +175,10 @@ def populate_projects(apps, schema_editor):
         # for convenience, create a schedulingset for each project
         models.SchedulingSet.objects.create(**SchedulingSet_test_data(name="Test Scheduling Set", project=tmss_project))
 
+        project_quota = ProjectQuota.objects.create(project=tmss_project, value=1e12, resource_type=ResourceType.objects.get(name="lta_storage"))
+        sara_fs = Filesystem.objects.get(name="Lofar Storage (SARA)")
+        models.ProjectQuotaArchiveLocation.objects.create(project_quota=project_quota, archive_location=sara_fs)
+
 
 def populate_resources(apps, schema_editor):
     bytes_q = Quantity.objects.get(value=Quantity.Choices.BYTES.value)
diff --git a/SAS/TMSS/backend/src/tmss/tmssapp/serializers/specification.py b/SAS/TMSS/backend/src/tmss/tmssapp/serializers/specification.py
index d281087554ecbd86d4dd6c60753d9c977fab084e..6da77622176c08eec700950093c5a214a36c80bd 100644
--- a/SAS/TMSS/backend/src/tmss/tmssapp/serializers/specification.py
+++ b/SAS/TMSS/backend/src/tmss/tmssapp/serializers/specification.py
@@ -184,6 +184,18 @@ class ProjectQuotaSerializer(DynamicRelationalHyperlinkedModelSerializer):
         extra_fields = ['resource_type']
 
 
+class ProjectQuotaArchiveLocationSerializer(DynamicRelationalHyperlinkedModelSerializer):
+    queryset = models.ProjectQuotaArchiveLocation.objects.all()
+
+    # performance boost: select the related models in a single db call.
+    queryset = queryset.select_related('project_quota', 'archive_location')
+
+    class Meta:
+        model = models.ProjectQuotaArchiveLocation
+        fields = '__all__'
+        extra_fields = ['archive_subdirectory', 'full_archive_uri']
+
+
 class ResourceTypeSerializer(DynamicRelationalHyperlinkedModelSerializer):
     class Meta:
         model = models.ResourceType
diff --git a/SAS/TMSS/backend/src/tmss/tmssapp/viewsets/specification.py b/SAS/TMSS/backend/src/tmss/tmssapp/viewsets/specification.py
index b554ffdcef5395a2362c317718d75dc0946de8bf..506b44b8b18dc9b3969305d0c3ac1c326da23f54 100644
--- a/SAS/TMSS/backend/src/tmss/tmssapp/viewsets/specification.py
+++ b/SAS/TMSS/backend/src/tmss/tmssapp/viewsets/specification.py
@@ -296,7 +296,22 @@ class ProjectQuotaViewSet(LOFARViewSet):
             return queryset.filter(project=project)
 
         return queryset
-    
+
+
+class ProjectQuotaArchiveLocationViewSet(LOFARViewSet):
+    queryset = models.ProjectQuotaArchiveLocation.objects.all()
+    serializer_class = serializers.ProjectQuotaArchiveLocationSerializer
+
+    def get_queryset(self):
+        queryset = models.ProjectQuotaArchiveLocation.objects.all()
+
+        # query by project
+        project = self.request.query_params.get('project', None)
+        if project is not None:
+            return queryset.filter(project=project)
+
+        return queryset
+
 
 class ResourceTypeViewSet(LOFARViewSet):
     queryset = models.ResourceType.objects.all()
diff --git a/SAS/TMSS/backend/src/tmss/urls.py b/SAS/TMSS/backend/src/tmss/urls.py
index 8158bfc0267b5411129ebb7811160712f6a1b8f2..039b531a658e3bed589f131860f3d1193bfc3b39 100644
--- a/SAS/TMSS/backend/src/tmss/urls.py
+++ b/SAS/TMSS/backend/src/tmss/urls.py
@@ -149,6 +149,7 @@ router.register(r'cycle_quota', viewsets.CycleQuotaViewSet)
 router.register(r'project', viewsets.ProjectViewSet)
 router.register(r'resource_type', viewsets.ResourceTypeViewSet)
 router.register(r'project_quota', viewsets.ProjectQuotaViewSet)
+router.register(r'project_quota_archive_location', viewsets.ProjectQuotaArchiveLocationViewSet)
 router.register(r'setting', viewsets.SettingViewSet)
 router.register(r'reservation', viewsets.ReservationViewSet)