diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 111597ee361294cdc2cff5b3f3492f8a84f1f012..b2ad84ad0429a1da20316f05da61e2a9d3b506cb 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -6,13 +6,15 @@ stages:
   - build
   - deploy
 
+# get a cache before each stage
 cache:
-  untracked: true
   # In key name, include Docker image to explicit Python version. Ref slug for branch or tag name.
   key: cache-${CI_JOB_IMAGE}-${CI_COMMIT_REF_SLUG}
   paths:
     - .venv/
     - ./dist
+  # add the untracked files to the cache.zip
+  untracked: true
 
 
 before_script:
@@ -23,6 +25,9 @@ dependencies:
   # Prevent call of before_script because it will fail
   before_script:
     - ''
+  tags:
+    # run only on runners automatically sharing cache (with 'leximpact-shared-cache' tag)
+    - leximpact-shared-cache
   script:
     - python -m venv .venv
     - source .venv/bin/activate
@@ -31,12 +36,16 @@ dependencies:
 check-style:
   stage: test
   needs: ["dependencies"]
+  tags:
+    - leximpact-shared-cache
   script:
     - make check-style
 
 test:
   stage: test
   needs: ["dependencies"]
+  tags:
+    - leximpact-shared-cache
   script:
     - make test-ci
 
@@ -57,6 +66,7 @@ validate_yaml:
 
 check_version:
   stage: test
+  # TODO check if this job really needs "dependencies" and explicit why
   needs: ["dependencies"]
   script:
     # Check for functional changes and version number
@@ -66,6 +76,8 @@ check_version:
 
 build:
   stage: build
+  tags:
+    - leximpact-shared-cache
   script:
     - make build
 
@@ -73,6 +85,8 @@ build:
 # release needed to bypass 'git tag' access rights configuration limited by annual token
 release-and-tag:
   stage: deploy
+  tags:
+    - leximpact-shared-cache
   needs: ["build"]
   # use release-cli to get release name from variable
   image: registry.gitlab.com/gitlab-org/release-cli:latest
@@ -93,6 +107,8 @@ release-and-tag:
 deploy-wheel:
   stage: deploy
   needs: ["build"]
+  tags:
+    - leximpact-shared-cache
   script:
     - if ! .gitlab/ci/has-functional-changes.sh ; then exit 0 ; fi
     # publish the wheel knowing that artifacts from all previous stages are passed by default
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6ba1470b07effb5e6a16448e5f794ce54358261b..b95cdc1e2f365086c8197b0e2442adeaeb0ece4a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,16 @@
 # Changelog
 
+## 4.2.0 [!39](https://git.leximpact.dev/leximpact/simulateur-dotations-communes/openfisca-france-dotations-locales/-/merge_requests/39)
+
+* Évolution du système socio-fiscal.
+* Périodes concernées : 01/01/2017
+* Zones impactées :
+  - `parameters/population/groupes_demographiques.yaml`
+  - `variables/population.py`
+* Détails :
+  - Extrait de `strate_demographique` les seuils de strates en un paramètre `population.groupes_demographiques`
+  - Définit en CI que les runners GitLab doivent avoir pour tag `leximpact-shared-cache`
+
 ### 4.1.1 [!38](https://git.leximpact.dev/leximpact/simulateur-dotations-communes/openfisca-france-dotations-locales/-/merge_requests/38)
 
 * Évolution du système socio-fiscal.
diff --git a/openfisca_france_dotations_locales/parameters/population/groupes_demographiques.yaml b/openfisca_france_dotations_locales/parameters/population/groupes_demographiques.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..87794399da3aabe1d69c508de87f43d1644c54e6
--- /dev/null
+++ b/openfisca_france_dotations_locales/parameters/population/groupes_demographiques.yaml
@@ -0,0 +1,97 @@
+description: Groupes démographiques des communes déterminés en fonction de l'importance de leur population \
+  (autrement désignés par strates démographiques)
+metadata:
+  type: single_amount
+  reference: https://www.legifrance.gouv.fr/codes/article_lc/LEGIARTI000033878299
+  # la référence définit les seuils mais pas de numéro de groupe (strate) qu'on déduit ici
+brackets:
+- amount:
+    2017-01-01:
+      value: 1
+  threshold:
+    2017-01-01:
+      value: 0
+- amount:
+    2017-01-01:
+      value: 2
+  threshold:
+    2017-01-01:
+      value: 500
+- amount:
+    2017-01-01:
+      value: 3
+  threshold:
+    2017-01-01:
+      value: 1_000
+- amount:
+    2017-01-01:
+      value: 4
+  threshold:
+    2017-01-01:
+      value: 2_000
+- amount:
+    2017-01-01:
+      value: 5
+  threshold:
+    2017-01-01:
+      value: 3_500
+- amount:
+    2017-01-01:
+      value: 6
+  threshold:
+    2017-01-01:
+      value: 5_000
+- amount:
+    2017-01-01:
+      value: 7
+  threshold:
+    2017-01-01:
+      value: 7_500
+- amount:
+    2017-01-01:
+      value: 8
+  threshold:
+    2017-01-01:
+      value: 10_000
+- amount:
+    2017-01-01:
+      value: 9
+  threshold:
+    2017-01-01:
+      value: 15_000
+- amount:
+    2017-01-01:
+      value: 10
+  threshold:
+    2017-01-01:
+      value: 20_000
+- amount:
+    2017-01-01:
+      value: 11
+  threshold:
+    2017-01-01:
+      value: 35_000
+- amount:
+    2017-01-01:
+      value: 12
+  threshold:
+    2017-01-01:
+      value: 50_000
+- amount:
+    2017-01-01:
+      value: 13
+  threshold:
+    2017-01-01:
+      value: 75_000
+- amount:
+    2017-01-01:
+      value: 14
+  threshold:
+    2017-01-01:
+      value: 100_000
+- amount:
+    2017-01-01:
+      value: 15
+  threshold:
+    2017-01-01:
+      value: 200_000
diff --git a/openfisca_france_dotations_locales/variables/population.py b/openfisca_france_dotations_locales/variables/population.py
index b6f6635f3d184eb869b62cbbca5862f7dae6747a..62e9c9961ffacabf6e72798f809e1d99bfc96209 100644
--- a/openfisca_france_dotations_locales/variables/population.py
+++ b/openfisca_france_dotations_locales/variables/population.py
@@ -16,24 +16,8 @@ class strate_demographique(Variable):
 
     def formula(commune, period, parameters):
         pop = commune('population_dgf', period)
-
-        return (
-            + 1 * (pop <= 499)
-            + 2 * (499 < pop) * (pop <= 999)
-            + 3 * (999 < pop) * (pop <= 1999)
-            + 4 * (1999 < pop) * (pop <= 3499)
-            + 5 * (3499 < pop) * (pop <= 4999)
-            + 6 * (4999 < pop) * (pop <= 7499)
-            + 7 * (7499 < pop) * (pop <= 9999)
-            + 8 * (9999 < pop) * (pop <= 14999)
-            + 9 * (14999 < pop) * (pop <= 19999)
-            + 10 * (19999 < pop) * (pop <= 34999)
-            + 11 * (34999 < pop) * (pop <= 49999)
-            + 12 * (49999 < pop) * (pop <= 74999)
-            + 13 * (74999 < pop) * (pop <= 99999)
-            + 14 * (99999 < pop) * (pop <= 199999)
-            + 15 * (199999 < pop)
-            )
+        bareme_strates_demographiques = parameters(period).population.groupes_demographiques
+        return bareme_strates_demographiques.calc(pop)
 
 
 class population_insee(Variable):
diff --git a/setup.py b/setup.py
index 48df14bb348186f1b0ed9eab5e3d8de09f1c5c16..b8f4e78dda34bdd77b4f7647a1492d39a3dea68f 100644
--- a/setup.py
+++ b/setup.py
@@ -4,7 +4,7 @@ from setuptools import setup, find_packages
 
 setup(
     name = "OpenFisca-France-Dotations-Locales",
-    version = "4.1.1",
+    version = "4.2.0",
     author = "LexImpact Team",
     author_email = "leximpact@an.fr",
     classifiers=[