diff --git a/ee/app/models/geo/file_registry.rb b/ee/app/models/geo/file_registry.rb
index 1fef42277917a0cdcf461fcaf0c9e7aaa56a9c13..8c0de66eb4fae4df6ac351bc2f8255fef0e201b9 100644
--- a/ee/app/models/geo/file_registry.rb
+++ b/ee/app/models/geo/file_registry.rb
@@ -5,4 +5,14 @@ class Geo::FileRegistry < Geo::BaseRegistry
 
   scope :lfs_objects, -> { where(file_type: :lfs) }
   scope :attachments, -> { where(file_type: Geo::FileService::DEFAULT_OBJECT_TYPES) }
+
+  self.inheritance_column = 'file_type'
+
+  def self.find_sti_class(file_type)
+    if file_type == 'lfs'
+      Geo::LfsObjectRegistry
+    elsif Geo::FileService::DEFAULT_OBJECT_TYPES.include?(file_type.to_sym)
+      Geo::UploadRegistry
+    end
+  end
 end
diff --git a/ee/app/models/geo/lfs_object_registry.rb b/ee/app/models/geo/lfs_object_registry.rb
new file mode 100644
index 0000000000000000000000000000000000000000..709fbb95c395d34a8266dfe262c8363882f58b6b
--- /dev/null
+++ b/ee/app/models/geo/lfs_object_registry.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+class Geo::LfsObjectRegistry < Geo::FileRegistry
+  belongs_to :lfs_object, foreign_key: :file_id, class_name: 'LfsObject'
+
+  def self.sti_name
+    'lfs'
+  end
+end
diff --git a/ee/app/models/geo/upload_registry.rb b/ee/app/models/geo/upload_registry.rb
new file mode 100644
index 0000000000000000000000000000000000000000..fd0198c7a40ed34f17928fd1c7ac073b8461d57d
--- /dev/null
+++ b/ee/app/models/geo/upload_registry.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+class Geo::UploadRegistry < Geo::FileRegistry
+  belongs_to :upload, foreign_key: :file_id
+
+  if Rails.gem_version >= Gem::Version.new('6.0')
+    raise '.type_condition was changed in Rails 6.0, please adapt this code accordingly'
+    # see https://github.com/rails/rails/commit/6a1a1e66ea7a917942bd8369fa8dbfedce391dab
+  end
+
+  def self.type_condition(table = arel_table)
+    sti_column = arel_attribute(inheritance_column, table)
+    sti_names  = Geo::FileService::DEFAULT_OBJECT_TYPES
+
+    sti_column.in(sti_names)
+  end
+end
diff --git a/ee/changelogs/unreleased/geo-split-file-registry.yml b/ee/changelogs/unreleased/geo-split-file-registry.yml
new file mode 100644
index 0000000000000000000000000000000000000000..feeda2e8a5dd0c8445f84e1e07fbf5c52644e530
--- /dev/null
+++ b/ee/changelogs/unreleased/geo-split-file-registry.yml
@@ -0,0 +1,5 @@
+---
+title: "Geo: Create separate models for different registries"
+merge_request: 9755
+author:
+type: added
diff --git a/ee/spec/models/geo/file_registry_spec.rb b/ee/spec/models/geo/file_registry_spec.rb
index 892aba3c9944a1d12543c65bbe976377520159b8..b533f9544063d5babb7c82c2c4f8deb05953875b 100644
--- a/ee/spec/models/geo/file_registry_spec.rb
+++ b/ee/spec/models/geo/file_registry_spec.rb
@@ -6,13 +6,13 @@ describe Geo::FileRegistry do
 
   describe '.failed' do
     it 'returns registries in the failed state' do
-      expect(described_class.failed).to contain_exactly(failed)
+      expect(described_class.failed).to match_ids(failed)
     end
   end
 
   describe '.synced' do
     it 'returns registries in the synced state' do
-      expect(described_class.synced).to contain_exactly(synced)
+      expect(described_class.synced).to match_ids(synced)
     end
   end
 
@@ -21,7 +21,7 @@ describe Geo::FileRegistry do
     set(:retry_tomorrow) { create(:geo_file_registry, retry_at: Date.tomorrow) }
 
     it 'returns registries in the synced state' do
-      expect(described_class.retry_due).not_to contain_exactly([retry_tomorrow])
+      expect(described_class.retry_due).to match_ids([failed, synced, retry_yesterday])
     end
   end
 end
diff --git a/ee/spec/models/geo/lfs_object_registry_spec.rb b/ee/spec/models/geo/lfs_object_registry_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..7dd54c032f445bac253e6b968441833d31450df0
--- /dev/null
+++ b/ee/spec/models/geo/lfs_object_registry_spec.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Geo::LfsObjectRegistry, :geo do
+  set(:lfs_registry) { create(:geo_file_registry, :lfs, :with_file) }
+  set(:attachment_registry) { create(:geo_file_registry, :attachment) }
+
+  it 'only finds lfs registries' do
+    expect(described_class.all).to match_ids(lfs_registry)
+  end
+
+  it 'finds associated LfsObject record' do
+    expect(described_class.find(lfs_registry.id).lfs_object).to be_an_instance_of(LfsObject)
+  end
+end
diff --git a/ee/spec/models/geo/upload_registry_spec.rb b/ee/spec/models/geo/upload_registry_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..d5064091102360c28e446acc1514ba081977cfa1
--- /dev/null
+++ b/ee/spec/models/geo/upload_registry_spec.rb
@@ -0,0 +1,30 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Geo::UploadRegistry, :geo do
+  set(:lfs_registry) { create(:geo_file_registry, :lfs) }
+  set(:attachment_registry) { create(:geo_file_registry, :attachment, :with_file) }
+  set(:avatar_registry) { create(:geo_file_registry, :avatar) }
+  set(:file_registry) { create(:geo_file_registry, :file) }
+  set(:namespace_file_registry) { create(:geo_file_registry, :namespace_file) }
+  set(:personal_file_registry) { create(:geo_file_registry, :personal_file) }
+  set(:favicon_registry) { create(:geo_file_registry, :favicon) }
+  set(:import_export_registry) { create(:geo_file_registry, :import_export) }
+
+  it 'finds all upload registries' do
+    expected = [attachment_registry,
+                avatar_registry,
+                file_registry,
+                namespace_file_registry,
+                personal_file_registry,
+                favicon_registry,
+                import_export_registry]
+
+    expect(described_class.all).to match_ids(expected)
+  end
+
+  it 'finds associated Upload record' do
+    expect(described_class.find(attachment_registry.id).upload).to be_an_instance_of(Upload)
+  end
+end