diff --git a/lib/gitlab/database/migration_helpers.rb b/lib/gitlab/database/migration_helpers.rb
index 4800a509b377878c8c2b22d0874b412cc20c62d8..fc445ab94831264f67f40ac2e8554d8adb47b672 100644
--- a/lib/gitlab/database/migration_helpers.rb
+++ b/lib/gitlab/database/migration_helpers.rb
@@ -54,7 +54,7 @@ module Gitlab
 
         disable_statement_timeout
 
-        key_name = "fk_#{source}_#{target}_#{column}"
+        key_name = concurrent_foreign_key_name(source, column)
 
         # Using NOT VALID allows us to create a key without immediately
         # validating it. This means we keep the ALTER TABLE lock only for a
@@ -74,6 +74,15 @@ module Gitlab
         execute("ALTER TABLE #{source} VALIDATE CONSTRAINT #{key_name};")
       end
 
+      # Returns the name for a concurrent foreign key.
+      #
+      # PostgreSQL constraint names have a limit of 63 bytes. The logic used
+      # here is based on Rails' foreign_key_name() method, which unfortunately
+      # is private so we can't rely on it directly.
+      def concurrent_foreign_key_name(table, column)
+        "fk_#{Digest::SHA256.hexdigest("#{table}_#{column}_fk").first(10)}"
+      end
+
       # Long-running migrations may take more than the timeout allowed by
       # the database. Disable the session's statement timeout to ensure
       # migrations don't get killed prematurely. (PostgreSQL only)
diff --git a/spec/lib/gitlab/database/migration_helpers_spec.rb b/spec/lib/gitlab/database/migration_helpers_spec.rb
index e94ca4fcfd2620b8c54fe7752141eaa3d95ce184..e007044868c1a173df2e5f1d32ca15cdd3221435 100644
--- a/spec/lib/gitlab/database/migration_helpers_spec.rb
+++ b/spec/lib/gitlab/database/migration_helpers_spec.rb
@@ -101,6 +101,16 @@ describe Gitlab::Database::MigrationHelpers, lib: true do
     end
   end
 
+  describe '#concurrent_foreign_key_name' do
+    it 'returns the name for a foreign key' do
+      name = model.concurrent_foreign_key_name(:this_is_a_very_long_table_name,
+                                               :with_a_very_long_column_name)
+
+      expect(name).to be_an_instance_of(String)
+      expect(name.length).to eq(13)
+    end
+  end
+
   describe '#disable_statement_timeout' do
     context 'using PostgreSQL' do
       it 'disables statement timeouts' do