diff --git a/.gitlab/ci/rails.gitlab-ci.yml b/.gitlab/ci/rails.gitlab-ci.yml
index f534f3418414b95a63782573d9f8ce7eb0c4e49d..a0366e8bb0b20966d2738ff2adbd96f1ab16e447 100644
--- a/.gitlab/ci/rails.gitlab-ci.yml
+++ b/.gitlab/ci/rails.gitlab-ci.yml
@@ -340,6 +340,7 @@ db:check-schema:
     - .rails:rules:ee-mr-and-default-branch-only
   script:
     - source scripts/schema_changed.sh
+    - scripts/validate_migration_timestamps
 
 db:check-migrations:
   extends:
diff --git a/scripts/validate_migration_timestamps b/scripts/validate_migration_timestamps
new file mode 100755
index 0000000000000000000000000000000000000000..d3722e7a4af7921641e3e2c22b955dbb22b6236c
--- /dev/null
+++ b/scripts/validate_migration_timestamps
@@ -0,0 +1,24 @@
+#!/usr/bin/env ruby
+
+# frozen_string_literal: true
+
+require 'time'
+
+MIGRATION_DIRS = %w[db/migrate db/post_migrate].freeze
+VERSION_DIGITS = 14
+MIGRATION_TIMESTAMP_REGEX = /\A(?<version>\d{#{VERSION_DIGITS}})_/.freeze
+
+maximum_timestamp = Time.now.utc.strftime('%Y%m%d%H%M%S').to_i
+
+MIGRATION_DIRS.each do |migration_dir|
+  Dir[File.join(migration_dir, '*.rb')].each do |filename|
+    file_basename = File.basename(filename)
+    version_match = MIGRATION_TIMESTAMP_REGEX.match(file_basename)
+
+    raise "#{filename} has an invalid migration version" if version_match.nil?
+
+    migration_timestamp = version_match['version'].to_i
+
+    raise "#{filename} has a future timestamp" if migration_timestamp > maximum_timestamp
+  end
+end