diff --git a/Gemfile b/Gemfile
index 46a4a94d26514f890f25bb87d27b9956c8a14638..e5876af4d20c34bb33673297b78fc149142296ad 100644
--- a/Gemfile
+++ b/Gemfile
@@ -63,6 +63,7 @@ gem "puma"
 gem "rails", "~> 7.1.0"
 gem "rails-autocomplete", "~> 2"
 gem "rails-i18n"
+gem "redis", "~> 5.1"
 gem "roo", "~> 2"
 gem "sanitize"
 gem "sassc-rails"
diff --git a/Gemfile.lock b/Gemfile.lock
index 6296e8bf17a73d5de9c376574eea833ac43ca205..3e46a3e06ace1b91cc394ee00e0fc43577076304 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -495,6 +495,10 @@ GEM
       ffi (~> 1.0)
     rdoc (6.6.3.1)
       psych (>= 4.0.0)
+    redis (5.1.0)
+      redis-client (>= 0.17.0)
+    redis-client (0.20.0)
+      connection_pool
     regexp_parser (2.9.0)
     reline (0.5.0)
       io-console (~> 0.5)
@@ -697,6 +701,7 @@ DEPENDENCIES
   rails (~> 7.1.0)
   rails-autocomplete (~> 2)
   rails-i18n
+  redis (~> 5.1)
   roo (~> 2)
   sanitize
   sassc-rails
diff --git a/app/views/admin/active_storage/blobs/static.html.erb b/app/views/admin/active_storage/blobs/static.html.erb
index 39aa7d32d21f423540c3260e1ac7d3b3a8320c10..1c061a9e98493a17d7f1c922095bbce4d6fcd36b 100644
--- a/app/views/admin/active_storage/blobs/static.html.erb
+++ b/app/views/admin/active_storage/blobs/static.html.erb
@@ -1,3 +1,7 @@
+<%-
+university = University.find_by(id: @about.university_id)
+cache [@about, university] do
+-%>
 <%
 width, height = @about.metadata.values_at('width', 'height')
 ratio = width.present? && height.present? ? (width.to_f / height.to_f) : nil
@@ -6,7 +10,6 @@ if ratio.present?
   format = 'landscape' if ratio > 1
   format = 'portrait' if ratio < 1
 end
-university = University.find_by(id: @about.university_id)
 base_url = university&.url || ""
 media_endpoint_path = medium_path(signed_id: @about.signed_id, filename_with_transformations: @about.filename)
 %>
@@ -21,3 +24,4 @@ media_endpoint_path = medium_path(signed_id: @about.signed_id, filename_with_tra
   "url" => "#{base_url}#{media_endpoint_path}",
   "direct_url" => @about.url
 }.compact.to_yaml) %>
+<%- end -%>
\ No newline at end of file
diff --git a/app/views/admin/administration/locations/static.html.erb b/app/views/admin/administration/locations/static.html.erb
index 0e9acdb0aa54c4c185d1e52681eb70762282b08c..ac114fbdd1c2154eba3804a764127fbc663db1c2 100644
--- a/app/views/admin/administration/locations/static.html.erb
+++ b/app/views/admin/administration/locations/static.html.erb
@@ -27,8 +27,8 @@ diplomas:
       <%= diploma.to_s %>
     path: <%= diploma.slug %>
     programs: <% @programs = @about.education_programs.where(diploma: diploma).root.ordered %>
-<%= render 'admin/education/programs/static_list', 
-            diploma: diploma, 
+<%= render 'admin/education/programs/static_list',
+            diploma: diploma,
             programs: @programs,
             all_programs: @about.programs,
             depth: 4 %>
diff --git a/app/views/admin/communication/websites/menus/static.html.erb b/app/views/admin/communication/websites/menus/static.html.erb
index e8ce01e9054a239d70aaab91e73c636557bb1da8..dfe7f86982ac1bcf91b8e22243152f0a7b4f439e 100644
--- a/app/views/admin/communication/websites/menus/static.html.erb
+++ b/app/views/admin/communication/websites/menus/static.html.erb
@@ -5,7 +5,7 @@ items = @about.items
               .ordered
               .map(&:to_static_hash)
               .compact
-hash = { 
+hash = {
   'title' => title,
   'items' => items
 }
diff --git a/app/views/admin/education/programs/static.html.erb b/app/views/admin/education/programs/static.html.erb
index 6733ff2a34066406308b36a2418796cc20facc27..5a95d31aa230c5cd86c7a32f82a80f82fe119038 100644
--- a/app/views/admin/education/programs/static.html.erb
+++ b/app/views/admin/education/programs/static.html.erb
@@ -80,7 +80,7 @@ capacity: <%= @about.capacity %>
 continuing: <%= @about.continuing %>
 initial: <%= @about.initial %>
 certifications:
-  qualiopi: 
+  qualiopi:
     certified: <%= @about.qualiopi_certified %>
     text: >-
       <%= prepare_html_for_static @about.qualiopi_text %>
diff --git a/app/views/admin/research/publications/static.html.erb b/app/views/admin/research/publications/static.html.erb
index 6319e133b918886d2a31500b2edb65f4dd0edbfc..b52bd95770610fef0a2cff8093bc2363206b5fed 100644
--- a/app/views/admin/research/publications/static.html.erb
+++ b/app/views/admin/research/publications/static.html.erb
@@ -29,10 +29,10 @@ researchers:
   - <%= researcher.slug %>
 <% end %>
 citations:
-<% 
-Citations::FORMATS.each do |format| 
+<%
+Citations::FORMATS.each do |format|
   citation = @about.public_send("citation_#{format}")
-  next if (@website.default_language.iso_code == "fr" && format == 'iso690') 
+  next if (@website.default_language.iso_code == "fr" && format == 'iso690')
 %>
   - label: "<%= t("research.citations.#{format}.label") %>"
     format: "<%= format %>"
diff --git a/app/views/admin/university/organizations/static.html.erb b/app/views/admin/university/organizations/static.html.erb
index b69a31b3803f2034a4f168eb38136a9b8b0330bd..babe66fa34ffffb27ad97da4b0f0605405406630 100644
--- a/app/views/admin/university/organizations/static.html.erb
+++ b/app/views/admin/university/organizations/static.html.erb
@@ -55,7 +55,7 @@ logo_on_dark_background: "<%= @about.logo_on_dark_background.blob.id %>"
 <%= render 'admin/application/summary/static' %>
 <%= render 'admin/application/connections/backlinks' %>
 <% if @about.categories.any? %>
-organizations_categories: 
+organizations_categories:
 <% @about.categories.each do |category| %>
   - slug: "<%= category.slug %>"
     path: "<%= category.current_permalink_in_website(@website)&.path %>"
diff --git a/app/views/admin/university/people/static.html.erb b/app/views/admin/university/people/static.html.erb
index 8267e16fba5474c3162050e20dd59e4849ae6d9e..aab9e373045df5f8dae9d53a7e9aabc08dbcfe7e 100644
--- a/app/views/admin/university/people/static.html.erb
+++ b/app/views/admin/university/people/static.html.erb
@@ -36,7 +36,7 @@ contact_details:
 <%= render 'admin/application/static/contact_detail', variable: :phone_personal, data: @about.phone_personal, kind: ContactDetails::Phone %>
 <%= render 'admin/application/static/contact_detail', variable: :email, data: @about.email, kind: ContactDetails::Email %>
 <% if @about.best_picture.attached? %>
-image: 
+image:
   id: "<%= @about.best_picture.blob.id %>"
   alt: ""
   credit: >-
@@ -84,7 +84,7 @@ administrative_missions:
 <% end %>
 <%= render 'admin/application/connections/backlinks' %>
 <% if @about.categories.any? %>
-persons_categories: 
+persons_categories:
 <% @about.categories.each do |category| %>
   - slug: "<%= category.slug %>"
     path: "<%= category.current_permalink_in_website(@website)&.path %>"
diff --git a/config/environments/production.rb b/config/environments/production.rb
index ec867fd5c480372a9687ff98796c7b904a259a89..88550be9153a1b09bc82c418434e16b93aada911 100644
--- a/config/environments/production.rb
+++ b/config/environments/production.rb
@@ -60,7 +60,9 @@ Rails.application.configure do
   config.log_level = ENV.fetch("RAILS_LOG_LEVEL", "info")
 
   # Use a different cache store in production.
-  # config.cache_store = :mem_cache_store
+  config.cache_store = :redis_cache_store, {
+    url: "#{ ENV['REDIS_URL'] }/0:#{ ENV['SOURCE_VERSION'] || ENV['CONTAINER_VERSION'] }"
+  }
 
   # Use a real queuing backend for Active Job (and separate queues per environment).
   # config.active_job.queue_adapter     = :resque