diff --git a/beat/web/experiments/migrations/0002_scheduler_addons.py b/beat/web/experiments/migrations/0002_scheduler_addons.py
index 9c7507834e537a78504cd91cedfa3d44d430e6f3..a1f462385b995661ad68608a03f82773c712bfb2 100644
--- a/beat/web/experiments/migrations/0002_scheduler_addons.py
+++ b/beat/web/experiments/migrations/0002_scheduler_addons.py
@@ -31,6 +31,19 @@ from __future__ import unicode_literals
 from django.db import migrations, models
 
 
+def move_result_to_cache(apps, schema_editor):
+    '''Moves the result association from the block to the related cache file'''
+
+    Result = apps.get_model("experiments", "Result")
+
+    total = Result.objects.count()
+    if total: print('')
+    for i, r in enumerate(Result.objects.order_by('-id')):
+        print("Resetting result (%d) %d/%d..." % (r.id, i+1, total))
+        r.cache = r.block.hashes.first()
+        r.save()
+
+
 class Migration(migrations.Migration):
 
     dependencies = [
@@ -44,8 +57,5 @@ class Migration(migrations.Migration):
             field=models.ForeignKey(related_name='results',
               to='experiments.CachedFile', null=True),
         ),
-        migrations.AlterUniqueTogether(
-            name='result',
-            unique_together=set([('cache', 'name')]),
-        ),
+        migrations.RunPython(move_result_to_cache),
     ]
diff --git a/beat/web/experiments/migrations/0003_scheduler_addons_2.py b/beat/web/experiments/migrations/0003_scheduler_addons_2.py
index 65e9b37bd9492f256eae25ca4c36a8e3050004ab..3d72f2965b2e05e7e19b4621e2cfd9ecd967248d 100644
--- a/beat/web/experiments/migrations/0003_scheduler_addons_2.py
+++ b/beat/web/experiments/migrations/0003_scheduler_addons_2.py
@@ -31,30 +31,28 @@ from __future__ import unicode_literals
 from django.db import migrations
 
 
-def move_result_to_cache(apps, schema_editor):
-    '''Moves the result association from the block to the related cache file'''
+def dedup_resuls(apps, schema_editor):
+    '''Deletes duplicated results (older ones)'''
 
     Result = apps.get_model("experiments", "Result")
 
-    total = Result.objects.count()
-    if total: print('')
-    for i, r in enumerate(Result.objects.order_by('id')):
-        print("Resetting result (%d) %d/%d..." % (r.id, i+1, total))
-        older = Result.objects.filter(name=r.name, cache=r.block.hashes.first()).exclude(id=r.id).first()
+    for i, r in enumerate(Result.objects.order_by('-id')):
+        older = Result.objects.filter(name=r.name, id__lt=r.id,
+            cache=r.block.hashes.first())
         if older:
             print("Cache %s already contains Result `%s' - keeping " \
-                "newest..." % (older.cache.hash, older.name))
+                "newest (out of %d)..." % (r.block.hashes.first().hash, r.name,
+                  older.count()+1))
             older.delete()
-        r.cache = r.block.hashes.first()
-        r.save()
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
         ('experiments', '0002_scheduler_addons'),
+        ('search', '0002_scheduler_addons'),
     ]
 
     operations = [
-        migrations.RunPython(move_result_to_cache),
+        migrations.RunPython(dedup_resuls),
         ]
diff --git a/beat/web/experiments/migrations/0004_scheduler_addons_3.py b/beat/web/experiments/migrations/0004_scheduler_addons_3.py
index fcd721050bb330959635ac692e8059660b85af9d..77c7dba1e2d79608edc5e76ee303de67f280d31b 100644
--- a/beat/web/experiments/migrations/0004_scheduler_addons_3.py
+++ b/beat/web/experiments/migrations/0004_scheduler_addons_3.py
@@ -216,6 +216,10 @@ class Migration(migrations.Migration):
     ]
 
     operations = [
+        migrations.AlterUniqueTogether(
+            name='result',
+            unique_together=set([('cache', 'name')]),
+        ),
         migrations.RemoveField(
             model_name='result',
             name='block',
diff --git a/beat/web/search/migrations/0002_scheduler_addons.py b/beat/web/search/migrations/0002_scheduler_addons.py
new file mode 100644
index 0000000000000000000000000000000000000000..f269a5f4a1b220cadd5f6abe5862d667daba5abc
--- /dev/null
+++ b/beat/web/search/migrations/0002_scheduler_addons.py
@@ -0,0 +1,65 @@
+#!/usr/bin/env python
+# vim: set fileencoding=utf-8 :
+
+###############################################################################
+#                                                                             #
+# Copyright (c) 2016 Idiap Research Institute, http://www.idiap.ch/           #
+# Contact: beat.support@idiap.ch                                              #
+#                                                                             #
+# This file is part of the beat.web module of the BEAT platform.              #
+#                                                                             #
+# Commercial License Usage                                                    #
+# Licensees holding valid commercial BEAT licenses may use this file in       #
+# accordance with the terms contained in a written agreement between you      #
+# and Idiap. For further information contact tto@idiap.ch                     #
+#                                                                             #
+# Alternatively, this file may be used under the terms of the GNU Affero      #
+# Public License version 3 as published by the Free Software and appearing    #
+# in the file LICENSE.AGPL included in the packaging of this file.            #
+# The BEAT platform is distributed in the hope that it will be useful, but    #
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY  #
+# or FITNESS FOR A PARTICULAR PURPOSE.                                        #
+#                                                                             #
+# You should have received a copy of the GNU Affero Public License along      #
+# with the BEAT platform. If not, see http://www.gnu.org/licenses/.           #
+#                                                                             #
+###############################################################################
+
+
+from __future__ import unicode_literals
+
+from django.db import migrations
+
+
+def reset_ranks(apps, schema_editor):
+    '''Reset ranks before older results can be deleted'''
+
+    Result = apps.get_model("experiments", "Result")
+    Rank = apps.get_model("search", "Rank")
+
+    total = Result.objects.count()
+    if total: print('')
+    for i, r in enumerate(Result.objects.order_by('-id')):
+        older = Result.objects.filter(name=r.name, id__lt=r.id,
+            cache=r.block.hashes.first())
+        for old in older:
+            # check if any leaderboard ranks require updates
+            for rank in Rank.objects.filter(result__in=(old,)):
+                print("Rank %d for search `%s/%s' uses old Result `%d' - " \
+                    "resetting to newer Result `%d'..." % \
+                    (rank.id, rank.leaderboard.search.author.username,
+                      rank.leaderboard.search.name, old.id, r.id))
+                rank.result.remove(old)
+                rank.result.add(r)
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('search', '0001_initial'),
+        ('experiments', '0002_scheduler_addons'),
+    ]
+
+    operations = [
+        migrations.RunPython(reset_ranks),
+        ]