diff --git a/backend/src/main/java/fr/inra/urgi/faidare/web/site/SiteController.java b/backend/src/main/java/fr/inra/urgi/faidare/web/site/SiteController.java
index 971c97d302d6c36687130ef2c69dc559325878f5..c28705adcb4ebeb98a2bcb3c1afc0dec9ae9e61c 100644
--- a/backend/src/main/java/fr/inra/urgi/faidare/web/site/SiteController.java
+++ b/backend/src/main/java/fr/inra/urgi/faidare/web/site/SiteController.java
@@ -74,16 +74,19 @@ public class SiteController {
         );
     }
 
-    @GetMapping(value = "/sitemap.txt")
+    @GetMapping(value = "/sitemap-{index}.txt")
     @ResponseBody
-    public ResponseEntity<StreamingResponseBody> sitemap() {
+    public ResponseEntity<StreamingResponseBody> sitemap(@PathVariable("index") int index) {
+        if (index < 0 || index >= Sitemaps.BUCKET_COUNT) {
+            throw new NotFoundException("no sitemap for this index");
+        }
         StreamingResponseBody body = out -> {
             Iterator<LocationSitemapVO> iterator = locationRepository.scrollAllForSitemap(1000);
             Sitemaps.generateSitemap(
-                "/sites/sitemap.txt",
+                "/sites/sitemap-" + index + ".txt",
                 out,
                 iterator,
-                vo -> true,
+                vo -> Math.floorMod(vo.getLocationDbId().hashCode(), Sitemaps.BUCKET_COUNT) == index,
                 vo -> "/sites/" + vo.getLocationDbId()
             );
         };
diff --git a/backend/src/main/java/fr/inra/urgi/faidare/web/sitemap/SitemapIndexController.java b/backend/src/main/java/fr/inra/urgi/faidare/web/sitemap/SitemapIndexController.java
index 1dd480dfbd465d243ae3b32b535c32b81c6b355a..f80d9e364075a59323f97273847fcd89e5b9df29 100644
--- a/backend/src/main/java/fr/inra/urgi/faidare/web/sitemap/SitemapIndexController.java
+++ b/backend/src/main/java/fr/inra/urgi/faidare/web/sitemap/SitemapIndexController.java
@@ -33,7 +33,9 @@ public class SitemapIndexController {
             .append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
             .append("<sitemapindex xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">\n");
 
-        appendSiteMap(builder, "/sites/sitemap.txt");
+        for (int i = 0; i < Sitemaps.BUCKET_COUNT; i++) {
+            appendSiteMap(builder, "/sites/sitemap-" + i + ".txt");
+        }
         for (int i = 0; i < Sitemaps.BUCKET_COUNT; i++) {
             appendSiteMap(builder, "/germplasms/sitemap-" + i + ".txt");
         }
diff --git a/backend/src/test/java/fr/inra/urgi/faidare/web/site/SiteControllerTest.java b/backend/src/test/java/fr/inra/urgi/faidare/web/site/SiteControllerTest.java
index 4874b602dd899ee384526ab45cb28c4593076756..98237eb1ea3d436242e9eb098216a1b3a10de4c8 100644
--- a/backend/src/test/java/fr/inra/urgi/faidare/web/site/SiteControllerTest.java
+++ b/backend/src/test/java/fr/inra/urgi/faidare/web/site/SiteControllerTest.java
@@ -14,12 +14,14 @@ import java.util.List;
 import fr.inra.urgi.faidare.config.FaidareProperties;
 import fr.inra.urgi.faidare.domain.data.LocationSitemapVO;
 import fr.inra.urgi.faidare.domain.data.LocationVO;
+import fr.inra.urgi.faidare.domain.data.study.StudySitemapVO;
 import fr.inra.urgi.faidare.domain.datadiscovery.data.DataSource;
 import fr.inra.urgi.faidare.domain.response.PaginatedList;
 import fr.inra.urgi.faidare.domain.xref.XRefDocumentSearchCriteria;
 import fr.inra.urgi.faidare.domain.xref.XRefDocumentVO;
 import fr.inra.urgi.faidare.repository.es.LocationRepository;
 import fr.inra.urgi.faidare.repository.es.XRefDocumentRepository;
+import fr.inra.urgi.faidare.utils.Sitemaps;
 import fr.inra.urgi.faidare.web.Fixtures;
 import fr.inra.urgi.faidare.web.thymeleaf.CoordinatesDialect;
 import fr.inra.urgi.faidare.web.thymeleaf.FaidareDialect;
@@ -85,10 +87,28 @@ public class SiteControllerTest {
     void shouldGenerateSitemap() throws Exception {
         List<LocationSitemapVO> sites = Arrays.asList(
             new LocationSitemapVO("site1"),
-            new LocationSitemapVO("site2")
+            new LocationSitemapVO("site4"),
+            new LocationSitemapVO("site53"),
+            new LocationSitemapVO("site68")
         );
-        when(mockLocationRepository.scrollAllForSitemap(anyInt())).thenReturn(sites.iterator());
-        MvcResult mvcResult = mockMvc.perform(get("/faidare/sites/sitemap.txt")
+
+        // the hashCode algorithm is specified in the javadoc, so it's guaranteed to be
+        // the same everywhere
+        // uncomment the following line to see which sitemap index each study has
+        // sites.forEach(site -> System.out.println(site.getLocationDbId() + " = " + Math.floorMod(site.getLocationDbId().hashCode(), Sitemaps.BUCKET_COUNT)));
+
+        when(mockLocationRepository.scrollAllForSitemap(anyInt())).thenAnswer(invocation -> sites.iterator());
+        testSitemap(2, "http://localhost/faidare/sites/site1\nhttp://localhost/faidare/sites/site53\n");
+        testSitemap(5, "http://localhost/faidare/sites/site4\nhttp://localhost/faidare/sites/site68\n");
+        testSitemap(7, "");
+
+        mockMvc.perform(get("/faidare/sites/sitemap-17.txt")
+                            .contextPath("/faidare"))
+               .andExpect(status().isNotFound());
+    }
+
+    private void testSitemap(int index, String expectedContent) throws Exception {
+        MvcResult mvcResult = mockMvc.perform(get("/faidare/sites/sitemap-" + index + ".txt")
                                                   .contextPath("/faidare"))
                                      .andExpect(request().asyncStarted())
                                      .andReturn();
@@ -96,6 +116,7 @@ public class SiteControllerTest {
         this.mockMvc.perform(asyncDispatch(mvcResult))
                     .andExpect(status().isOk())
                     .andExpect(content().contentType(MediaType.TEXT_PLAIN))
-                    .andExpect(content().string("http://localhost/faidare/sites/site1\nhttp://localhost/faidare/sites/site2\n"));
+                    .andExpect(content().string(expectedContent));
+
     }
 }
diff --git a/backend/src/test/java/fr/inra/urgi/faidare/web/sitemap/SitemapIndexControllerTest.java b/backend/src/test/java/fr/inra/urgi/faidare/web/sitemap/SitemapIndexControllerTest.java
index ea03832f41a262ea210eb6f093ef68fe5b583aab..f482c052de0e6e9d832a98adc02978cd1e5cfd80 100644
--- a/backend/src/test/java/fr/inra/urgi/faidare/web/sitemap/SitemapIndexControllerTest.java
+++ b/backend/src/test/java/fr/inra/urgi/faidare/web/sitemap/SitemapIndexControllerTest.java
@@ -25,10 +25,11 @@ class SitemapIndexControllerTest {
         mockMvc.perform(get("/faidare/sitemap.xml").contextPath("/faidare"))
             .andExpect(status().isOk())
             .andExpect(content().contentType(MediaType.TEXT_XML))
-            .andExpect(xpath("/sitemapindex/sitemap[1]/loc").string("http://localhost/faidare/sites/sitemap.txt"))
-            .andExpect(xpath("/sitemapindex/sitemap[2]/loc").string("http://localhost/faidare/germplasms/sitemap-0.txt"))
-            .andExpect(xpath("/sitemapindex/sitemap[3]/loc").string("http://localhost/faidare/germplasms/sitemap-1.txt"))
-            .andExpect(xpath("/sitemapindex/sitemap[" + (Sitemaps.BUCKET_COUNT + 2) + "]/loc").string("http://localhost/faidare/studies/sitemap-0.txt"))
-            .andExpect(xpath("/sitemapindex/sitemap[" + (Sitemaps.BUCKET_COUNT + 3) + "]/loc").string("http://localhost/faidare/studies/sitemap-1.txt"));
+            .andExpect(xpath("/sitemapindex/sitemap[1]/loc").string("http://localhost/faidare/sites/sitemap-0.txt"))
+            .andExpect(xpath("/sitemapindex/sitemap[2]/loc").string("http://localhost/faidare/sites/sitemap-1.txt"))
+            .andExpect(xpath("/sitemapindex/sitemap[" + (Sitemaps.BUCKET_COUNT + 1) + "]/loc").string("http://localhost/faidare/germplasms/sitemap-0.txt"))
+            .andExpect(xpath("/sitemapindex/sitemap[" + (Sitemaps.BUCKET_COUNT + 2) + "]/loc").string("http://localhost/faidare/germplasms/sitemap-1.txt"))
+            .andExpect(xpath("/sitemapindex/sitemap[" + (Sitemaps.BUCKET_COUNT * 2 + 1) + "]/loc").string("http://localhost/faidare/studies/sitemap-0.txt"))
+            .andExpect(xpath("/sitemapindex/sitemap[" + (Sitemaps.BUCKET_COUNT * 2 + 2) + "]/loc").string("http://localhost/faidare/studies/sitemap-1.txt"));
     }
 }