diff --git a/CHANGELOG.md b/CHANGELOG.md
index cb40253a33a94db1ddab0fe7010c4ac7b47e7438..91adae9bc5d0759a94be371816b38ca79ee8219c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,6 +6,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
 
 ## [Unreleased]
 
+### Fixed
+- CachedMeshLoader checks file last modification time.
+
 ## [2.4.0] - 2023-11-27
 
 ### Added
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 9a1c88c0e5332f4e4056e18a0e13e7873d3db20f..157689289055caf000dcf40757ee979e9b3ceb94 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -114,9 +114,9 @@ endif()
 SET_BOOST_DEFAULT_OPTIONS()
 EXPORT_BOOST_DEFAULT_OPTIONS()
 IF(WIN32)
-  ADD_PROJECT_DEPENDENCY(Boost REQUIRED COMPONENTS chrono thread date_time serialization)
+  ADD_PROJECT_DEPENDENCY(Boost REQUIRED COMPONENTS chrono thread date_time serialization filesystem)
 ELSE(WIN32)
-  ADD_PROJECT_DEPENDENCY(Boost REQUIRED chrono serialization)
+  ADD_PROJECT_DEPENDENCY(Boost REQUIRED chrono serialization filesystem)
 ENDIF(WIN32)
 if(BUILD_PYTHON_INTERFACE)
   find_package(Boost REQUIRED COMPONENTS system)
diff --git a/include/hpp/fcl/mesh_loader/loader.h b/include/hpp/fcl/mesh_loader/loader.h
index d2443cc21f785d0600f7824194a9ff9c28375db4..2c3f36249727693ace8fd042e0d10581ca0486a2 100644
--- a/include/hpp/fcl/mesh_loader/loader.h
+++ b/include/hpp/fcl/mesh_loader/loader.h
@@ -44,6 +44,7 @@
 #include <hpp/fcl/collision_object.h>
 
 #include <map>
+#include <ctime>
 
 namespace hpp {
 namespace fcl {
@@ -86,7 +87,11 @@ class HPP_FCL_DLLAPI CachedMeshLoader : public MeshLoader {
 
     bool operator<(const CachedMeshLoader::Key& b) const;
   };
-  typedef std::map<Key, BVHModelPtr_t> Cache_t;
+  struct HPP_FCL_DLLAPI Value {
+    BVHModelPtr_t model;
+    std::time_t mtime;
+  };
+  typedef std::map<Key, Value> Cache_t;
 
   const Cache_t& cache() const { return cache_; }
 
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index e1fe526732fa92b6a4bfafba42eb046fd2716ea3..474e4a3310915be2f0b22760611e089d177f1758 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -191,6 +191,7 @@ TARGET_LINK_LIBRARIES(${LIBRARY_NAME}
   PUBLIC
   Boost::serialization
   Boost::chrono
+  Boost::filesystem
 )
 
 IF(WIN32)
diff --git a/src/mesh_loader/loader.cpp b/src/mesh_loader/loader.cpp
index b874c54eca7d8d256e190eca0c1e592b01a2f418..3153f1a8d2e1446dcf4f1053fd51c1faca768324 100644
--- a/src/mesh_loader/loader.cpp
+++ b/src/mesh_loader/loader.cpp
@@ -37,6 +37,8 @@
 #include <hpp/fcl/mesh_loader/loader.h>
 #include <hpp/fcl/mesh_loader/assimp.h>
 
+#include <boost/filesystem.hpp>
+
 #ifdef HPP_FCL_HAS_OCTOMAP
 #include <hpp/fcl/octree.h>
 #endif
@@ -100,14 +102,26 @@ CollisionGeometryPtr_t MeshLoader::loadOctree(const std::string& filename) {
 BVHModelPtr_t CachedMeshLoader::load(const std::string& filename,
                                      const Vec3f& scale) {
   Key key(filename, scale);
-  Cache_t::const_iterator _cached = cache_.find(key);
-  if (_cached == cache_.end()) {
-    BVHModelPtr_t geom = MeshLoader::load(filename, scale);
-    cache_.insert(std::make_pair(key, geom));
-    return geom;
-  } else {
-    return _cached->second;
+
+  std::time_t mtime = 0;
+  try {
+    mtime = boost::filesystem::last_write_time(filename);
+
+    Cache_t::const_iterator _cached = cache_.find(key);
+    if (_cached != cache_.end() && _cached->second.mtime == mtime)
+      // File found in cache and mtime is the same
+      return _cached->second.model;
+  } catch (boost::filesystem::filesystem_error&) {
+    // Could not stat. Make sure we will try to load the file so that
+    // there will be a file not found error.
   }
+
+  BVHModelPtr_t geom = MeshLoader::load(filename, scale);
+  Value val;
+  val.model = geom;
+  val.mtime = mtime;
+  cache_[key] = val;
+  return geom;
 }
 }  // namespace fcl