diff --git a/Gemfile b/Gemfile
index 485324926534970e45eee2eb6a8b882f730babd2..b75090bfef592536dce0caeb69fbea096de3310d 100644
--- a/Gemfile
+++ b/Gemfile
@@ -503,7 +503,7 @@ gem 'ssh_data', '~> 1.3'
 gem 'spamcheck', '~> 1.0.0'
 
 # Gitaly GRPC protocol definitions
-gem 'gitaly', '~> 15.4.0-rc2'
+gem 'gitaly', '~> 15.5.0'
 
 # KAS GRPC protocol definitions
 gem 'kas-grpc', '~> 0.0.2'
diff --git a/Gemfile.checksum b/Gemfile.checksum
index 50463fe271522b26e7f71eb9fceebc48d734d10f..620934a40043aaa874b005e653e6e616008a141b 100644
--- a/Gemfile.checksum
+++ b/Gemfile.checksum
@@ -198,7 +198,7 @@
 {"name":"gettext_i18n_rails","version":"1.8.0","platform":"ruby","checksum":"95e5cf8440b1e08705b27f2bccb56143272c5a7a0dabcf54ea1bd701140a496f"},
 {"name":"gettext_i18n_rails_js","version":"1.3.0","platform":"ruby","checksum":"5d10afe4be3639bff78c50a56768c20f39aecdabc580c08aa45573911c2bd687"},
 {"name":"git","version":"1.11.0","platform":"ruby","checksum":"7e95ba4da8298a0373ef1a6862aa22007d761f3c8274b675aa787966fecea0f1"},
-{"name":"gitaly","version":"15.4.0.pre.rc2","platform":"ruby","checksum":"48764528a730605a46f00cf86c7cfcb92d25f4f3d8cb9e09557baac3e9f3f8e3"},
+{"name":"gitaly","version":"15.5.0","platform":"ruby","checksum":"d85dd4890a1f0fd95f935c848bcedf03f19b78872f20f04b9811e602bea4ef42"},
 {"name":"github-markup","version":"1.7.0","platform":"ruby","checksum":"97eb27c70662d9cc1d5997cd6c99832026fae5d4913b5dce1ce6c9f65078e69d"},
 {"name":"gitlab","version":"4.16.1","platform":"ruby","checksum":"13fd7059cbdad5a1a21b15fa2cf9070b97d92e27f8c688581fe3d84dc038074f"},
 {"name":"gitlab-chronic","version":"0.10.5","platform":"ruby","checksum":"f80f18dc699b708870a80685243331290bc10cfeedb6b99c92219722f729c875"},
diff --git a/Gemfile.lock b/Gemfile.lock
index dc1a39776bc2a2d84452968227a44603c723dc9e..36c5ad429c19c9f26fd9131145e47ddb5341a4e7 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -547,7 +547,7 @@ GEM
       rails (>= 3.2.0)
     git (1.11.0)
       rchardet (~> 1.8)
-    gitaly (15.4.0.pre.rc2)
+    gitaly (15.5.0)
       grpc (~> 1.0)
     github-markup (1.7.0)
     gitlab (4.16.1)
@@ -1624,7 +1624,7 @@ DEPENDENCIES
   gettext (~> 3.3)
   gettext_i18n_rails (~> 1.8.0)
   gettext_i18n_rails_js (~> 1.3)
-  gitaly (~> 15.4.0.pre.rc2)
+  gitaly (~> 15.5.0)
   github-markup (~> 1.7.0)
   gitlab-chronic (~> 0.10.5)
   gitlab-dangerfiles (~> 3.6.1)
diff --git a/app/models/wiki.rb b/app/models/wiki.rb
index b718c3a096fa95bc93b4231c51dd42d755e2c3ad..4fe8170a4ab0398022c748f52bf227fa37ad19eb 100644
--- a/app/models/wiki.rb
+++ b/app/models/wiki.rb
@@ -190,7 +190,7 @@ def has_home_page?
   end
 
   def empty?
-    !repository_exists? || list_page_paths.empty?
+    !repository_exists? || list_page_paths(limit: 1).empty?
   end
 
   def exists?
@@ -207,9 +207,9 @@ def exists?
   #
   # Returns an Array of GitLab WikiPage instances or an
   # empty Array if this Wiki has no pages.
-  def list_pages(limit: 0, direction: DIRECTION_ASC, load_content: false)
+  def list_pages(direction: DIRECTION_ASC, load_content: false, limit: 0, offset: 0)
     create_wiki_repository unless repository_exists?
-    list_pages_with_repository_rpcs(limit: limit, direction: direction, load_content: load_content)
+    list_pages_with_repository_rpcs(direction: direction, load_content: load_content, limit: limit, offset: offset)
   end
 
   def sidebar_entries(limit: Gitlab::WikiPages::MAX_SIDEBAR_PAGES, **options)
@@ -457,7 +457,7 @@ def find_matched_file(title, version)
     escaped_path = RE2::Regexp.escape(sluggified_title(title))
     path_regexp = Gitlab::EncodingHelper.encode_utf8_no_detect("(?i)^#{escaped_path}\\.(#{file_extension_regexp})$")
 
-    matched_files = repository.search_files_by_regexp(path_regexp, version)
+    matched_files = repository.search_files_by_regexp(path_regexp, version, limit: 1)
     return if matched_files.blank?
 
     Gitlab::EncodingHelper.encode_utf8_no_detect(matched_files.first)
@@ -509,15 +509,15 @@ def strip_extension(path)
     path.sub(/\.[^.]+\z/, "")
   end
 
-  def list_page_paths
+  def list_page_paths(limit: 0, offset: 0)
     return [] if repository.empty?
 
     path_regexp = Gitlab::EncodingHelper.encode_utf8_no_detect("(?i)\\.(#{file_extension_regexp})$")
-    repository.search_files_by_regexp(path_regexp, default_branch)
+    repository.search_files_by_regexp(path_regexp, default_branch, limit: limit, offset: offset)
   end
 
-  def list_pages_with_repository_rpcs(limit:, direction:, load_content:)
-    paths = list_page_paths
+  def list_pages_with_repository_rpcs(direction:, load_content:, limit:, offset:)
+    paths = list_page_paths(limit: limit, offset: offset)
     return [] if paths.empty?
 
     pages = paths.map do |path|
diff --git a/lib/gitlab/git/repository.rb b/lib/gitlab/git/repository.rb
index 9bbe17dcad1f46058641077ea66aa0976e758aba..a5eab9aae8cc34229438312214de3e3da10720d1 100644
--- a/lib/gitlab/git/repository.rb
+++ b/lib/gitlab/git/repository.rb
@@ -1054,19 +1054,19 @@ def can_be_merged?(source_sha, target_branch)
         end
       end
 
-      def search_files_by_name(query, ref)
+      def search_files_by_name(query, ref, limit: 0, offset: 0)
         safe_query = query.sub(%r{^/*}, "")
         ref ||= root_ref
 
         return [] if empty? || safe_query.blank?
 
-        gitaly_repository_client.search_files_by_name(ref, safe_query).map do |file|
+        gitaly_repository_client.search_files_by_name(ref, safe_query, limit: limit, offset: offset).map do |file|
           Gitlab::EncodingHelper.encode_utf8(file)
         end
       end
 
-      def search_files_by_regexp(filter, ref = 'HEAD')
-        gitaly_repository_client.search_files_by_regexp(ref, filter).map do |file|
+      def search_files_by_regexp(filter, ref = 'HEAD', limit: 0, offset: 0)
+        gitaly_repository_client.search_files_by_regexp(ref, filter, limit: limit, offset: offset).map do |file|
           Gitlab::EncodingHelper.encode_utf8(file)
         end
       end
diff --git a/lib/gitlab/gitaly_client/repository_service.rb b/lib/gitlab/gitaly_client/repository_service.rb
index f11437552e1fd9c7ab4e9c42fa7da1f68b3e784a..8934067551c20aeb2ed7b01ecf52cef6c290d00b 100644
--- a/lib/gitlab/gitaly_client/repository_service.rb
+++ b/lib/gitlab/gitaly_client/repository_service.rb
@@ -303,8 +303,8 @@ def raw_changes_between(from, to)
         GitalyClient.call(@storage, :repository_service, :get_raw_changes, request, timeout: GitalyClient.fast_timeout)
       end
 
-      def search_files_by_name(ref, query)
-        request = Gitaly::SearchFilesByNameRequest.new(repository: @gitaly_repo, ref: ref, query: query)
+      def search_files_by_name(ref, query, limit: 0, offset: 0)
+        request = Gitaly::SearchFilesByNameRequest.new(repository: @gitaly_repo, ref: ref, query: query, limit: limit, offset: offset)
         GitalyClient.call(@storage, :repository_service, :search_files_by_name, request, timeout: GitalyClient.fast_timeout).flat_map(&:files)
       end
 
@@ -314,8 +314,8 @@ def search_files_by_content(ref, query, options = {})
         search_results_from_response(response, options)
       end
 
-      def search_files_by_regexp(ref, filter)
-        request = Gitaly::SearchFilesByNameRequest.new(repository: @gitaly_repo, ref: ref, query: '.', filter: filter)
+      def search_files_by_regexp(ref, filter, limit: 0, offset: 0)
+        request = Gitaly::SearchFilesByNameRequest.new(repository: @gitaly_repo, ref: ref, query: '.', filter: filter, limit: limit, offset: offset)
         GitalyClient.call(@storage, :repository_service, :search_files_by_name, request, timeout: GitalyClient.fast_timeout).flat_map(&:files)
       end
 
diff --git a/spec/support/shared_examples/models/wiki_shared_examples.rb b/spec/support/shared_examples/models/wiki_shared_examples.rb
index b1aa90449e177391b3016e97f2840ec1242e594a..7f0a87be939d8bcde4b572076f7dd8ef43f1e6d3 100644
--- a/spec/support/shared_examples/models/wiki_shared_examples.rb
+++ b/spec/support/shared_examples/models/wiki_shared_examples.rb
@@ -161,9 +161,10 @@
       let(:wiki_pages) { subject.list_pages }
 
       before do
-        subject.create_page('index', 'This is an index')
+        # The order is intentional
         subject.create_page('index2', 'This is an index2')
-        subject.create_page('an index3', 'This is an index3')
+        subject.create_page('index', 'This is an index')
+        subject.create_page('index3', 'This is an index3')
       end
 
       it 'returns an array of WikiPage instances' do
@@ -183,13 +184,47 @@
 
       context 'with limit option' do
         it 'returns limited set of pages' do
-          expect(subject.list_pages(limit: 1).count).to eq(1)
+          expect(
+            subject.list_pages(limit: 1).map(&:title)
+          ).to eql(%w[index])
+        end
+
+        it 'returns all set of pages if limit is more than the total pages' do
+          expect(subject.list_pages(limit: 4).count).to eq(3)
+        end
+
+        it 'returns all set of pages if limit is 0' do
+          expect(subject.list_pages(limit: 0).count).to eq(3)
+        end
+      end
+
+      context 'with offset option' do
+        it 'returns offset-ed set of pages' do
+          expect(
+            subject.list_pages(offset: 1).map(&:title)
+          ).to eq(%w[index2 index3])
+
+          expect(
+            subject.list_pages(offset: 2).map(&:title)
+          ).to eq(["index3"])
+          expect(subject.list_pages(offset: 3).count).to eq(0)
+          expect(subject.list_pages(offset: 4).count).to eq(0)
+        end
+
+        it 'returns all set of pages if offset is 0' do
+          expect(subject.list_pages(offset: 0).count).to eq(3)
+        end
+
+        it 'can combines with limit' do
+          expect(
+            subject.list_pages(offset: 1, limit: 1).map(&:title)
+          ).to eq(["index2"])
         end
       end
 
       context 'with sorting options' do
         it 'returns pages sorted by title by default' do
-          pages = ['an index3', 'index', 'index2']
+          pages = %w[index index2 index3]
 
           expect(subject.list_pages.map(&:title)).to eq(pages)
           expect(subject.list_pages(direction: 'desc').map(&:title)).to eq(pages.reverse)
@@ -200,9 +235,9 @@
         let(:pages) { subject.list_pages(load_content: true) }
 
         it 'loads WikiPage content' do
-          expect(pages.first.content).to eq('This is an index3')
-          expect(pages.second.content).to eq('This is an index')
-          expect(pages.third.content).to eq('This is an index2')
+          expect(pages.first.content).to eq('This is an index')
+          expect(pages.second.content).to eq('This is an index2')
+          expect(pages.third.content).to eq('This is an index3')
         end
       end
     end