diff --git a/config/vufind/searches.ini b/config/vufind/searches.ini
index 274c11cda28e5c3a2a0e2d0804e6127614705bab..edd90ee5f4c6b1d2fda821f11764014db146f8d5 100644
--- a/config/vufind/searches.ini
+++ b/config/vufind/searches.ini
@@ -26,6 +26,13 @@ default_view         = list
 default_limit        = 20
 ;limit_options        = 10,20,40,60,80,100
 
+; This setting allows to limit pagination of a search result as deep pagination
+; costs a lot of performance and most users are not very likely to navigate
+; further down than 20 pages of a search result.
+; This is especially useful to prevent webcrawlers from descending too deep and
+; eating up search backend performance. Default is set to unlimited.
+;result_limit = 400
+
 ; If this setting is true, boolean operators in searches (AND/OR/NOT) will only
 ; be recognized if they are ALL UPPERCASE.  If set to false, they will be
 ; recognized regardless of case.  If set to a comma-separated list of operators
diff --git a/module/VuFind/src/VuFind/Search/Base/Options.php b/module/VuFind/src/VuFind/Search/Base/Options.php
index 102d11380db23f0483a51996a995faee4a77d7ab..baf551397d1a495b057647b864a2ce80732bab49 100644
--- a/module/VuFind/src/VuFind/Search/Base/Options.php
+++ b/module/VuFind/src/VuFind/Search/Base/Options.php
@@ -212,6 +212,13 @@ abstract class Options implements TranslatorAwareInterface
      */
     protected $configLoader;
 
+    /**
+     * Maximum number of results (no limit by default)
+     *
+     * @var int
+     */
+    protected $resultLimit = -1;
+
     /**
      * Constructor
      *
@@ -724,8 +731,7 @@ abstract class Options implements TranslatorAwareInterface
      */
     public function getVisibleSearchResultLimit()
     {
-        // No limit by default:
-        return -1;
+        return intval($this->resultLimit);
     }
 
     /**
diff --git a/module/VuFind/src/VuFind/Search/Base/Results.php b/module/VuFind/src/VuFind/Search/Base/Results.php
index 80bed2d0ea6cfd4a7da09eb535255a6945a132dd..7ada0ce8b4c575bf2f16dc33d35d9fdb312b9a1f 100644
--- a/module/VuFind/src/VuFind/Search/Base/Results.php
+++ b/module/VuFind/src/VuFind/Search/Base/Results.php
@@ -304,11 +304,17 @@ abstract class Results implements ServiceLocatorAwareInterface
      */
     public function getStartRecord()
     {
-        if (!is_null($this->startRecordOverride)) {
+        if (null !== $this->startRecordOverride) {
             return $this->startRecordOverride;
         }
         $params = $this->getParams();
-        return (($params->getPage() - 1) * $params->getLimit()) + 1;
+        $page = $params->getPage();
+        $pageLimit = $params->getLimit();
+        $resultLimit = $this->getOptions()->getVisibleSearchResultLimit();
+        if ($resultLimit > -1 && $resultLimit < $page * $pageLimit) {
+            $page = ceil($resultLimit / $pageLimit);
+        }
+        return (($page - 1) * $pageLimit) + 1;
     }
 
     /**
@@ -319,16 +325,19 @@ abstract class Results implements ServiceLocatorAwareInterface
     public function getEndRecord()
     {
         $total = $this->getResultTotal();
-        $limit = $this->getParams()->getLimit();
-        $page = $this->getParams()->getPage();
-        if ($page * $limit > $total) {
-            // The end of the current page runs past the last record, use total
-            // results
-            return $total;
+        $params = $this->getParams();
+        $page = $params->getPage();
+        $pageLimit = $params->getLimit();
+        $resultLimit = $this->getOptions()->getVisibleSearchResultLimit();
+
+        if ($resultLimit > -1 && $resultLimit < ($page * $pageLimit)) {
+            $record = $resultLimit;
         } else {
-            // Otherwise use the last record on this page
-            return $page * $limit;
+            $record = $page * $pageLimit;
         }
+        // If the end of the current page runs past the last record, use total
+        // results; otherwise use the last record on this page:
+        return ($record > $total) ? $total : $record;
     }
 
     /**
diff --git a/module/VuFind/src/VuFind/Search/EDS/Options.php b/module/VuFind/src/VuFind/Search/EDS/Options.php
index d3cd5e05a0fb7a557faa9fba3636d78252963b09..41327ea4fdc4eb328a223032a24600d0139dad5a 100644
--- a/module/VuFind/src/VuFind/Search/EDS/Options.php
+++ b/module/VuFind/src/VuFind/Search/EDS/Options.php
@@ -38,13 +38,6 @@ namespace VuFind\Search\EDS;
  */
 class Options extends \VuFind\Search\Base\Options
 {
-    /**
-     * Maximum number of results
-     *
-     * @var int
-     */
-    protected $resultLimit = 100;
-
     /**
      * Available search mode options
      *
@@ -127,6 +120,7 @@ class Options extends \VuFind\Search\Base\Options
         $this->searchIni = $this->facetsIni = 'EDS';
         $searchSettings = $configLoader->get($this->searchIni);
         parent::__construct($configLoader);
+        $this->resultLimit = 100;
         $this->viewOptions = [
             'list|title' => 'Title View', 'list|brief' => 'Brief View',
             'list|detailed' => 'Detailed View'
@@ -237,18 +231,6 @@ class Options extends \VuFind\Search\Base\Options
         return 'eds-advanced';
     }
 
-    /**
-     * If there is a limit to how many search results a user can access, this
-     * method will return that limit.  If there is no limit, this will return
-     * -1.
-     *
-     * @return int
-     */
-    public function getVisibleSearchResultLimit()
-    {
-        return $this->resultLimit;
-    }
-
     /**
      * Set the search options from the Eds API Info methods results
      *
diff --git a/module/VuFind/src/VuFind/Search/Primo/Options.php b/module/VuFind/src/VuFind/Search/Primo/Options.php
index af7f763f49dc2e86133fd1626f36f5e0f311d54e..7236deb59cb0ee6eb5ec3f0a02ef4b99b0f25d31 100644
--- a/module/VuFind/src/VuFind/Search/Primo/Options.php
+++ b/module/VuFind/src/VuFind/Search/Primo/Options.php
@@ -38,13 +38,6 @@ namespace VuFind\Search\Primo;
  */
 class Options extends \VuFind\Search\Base\Options
 {
-    /**
-     * Maximum number of results
-     *
-     * @var int
-     */
-    protected $resultLimit = 3980;
-
     /**
      * Advanced search operators
      *
@@ -101,6 +94,8 @@ class Options extends \VuFind\Search\Base\Options
         // Result limit:
         if (isset($searchSettings->General->result_limit)) {
             $this->resultLimit = $searchSettings->General->result_limit;
+        } else {
+            $this->resultLimit = 3980;  // default
         }
 
         // Search handler setup:
@@ -140,18 +135,6 @@ class Options extends \VuFind\Search\Base\Options
         }
     }
 
-    /**
-     * If there is a limit to how many search results a user can access, this
-     * method will return that limit.  If there is no limit, this will return
-     * -1.
-     *
-     * @return int
-     */
-    public function getVisibleSearchResultLimit()
-    {
-        return intval($this->resultLimit);
-    }
-
     /**
      * Return the route name for the search results action.
      *
diff --git a/module/VuFind/src/VuFind/Search/Solr/Options.php b/module/VuFind/src/VuFind/Search/Solr/Options.php
index efb5cbc75f62e6f234118a3350bc54e9745281ca..fde902c08f43ae092544e19320a5116253ce4be7 100644
--- a/module/VuFind/src/VuFind/Search/Solr/Options.php
+++ b/module/VuFind/src/VuFind/Search/Solr/Options.php
@@ -113,6 +113,10 @@ class Options extends \VuFind\Search\Base\Options
             $this->defaultFilters = $searchSettings->General->default_filters
                 ->toArray();
         }
+        // Result limit:
+        if (isset($searchSettings->General->result_limit)) {
+            $this->resultLimit = $searchSettings->General->result_limit;
+        }
         if (isset($searchSettings->Basic_Searches)) {
             foreach ($searchSettings->Basic_Searches as $key => $value) {
                 $this->basicHandlers[$key] = $value;
diff --git a/module/VuFind/src/VuFind/Search/Summon/Options.php b/module/VuFind/src/VuFind/Search/Summon/Options.php
index 2d567d96b09e089e250eae440729bbbd5b76ea67..ee938d1227c4639a373e171de5971da61839b49b 100644
--- a/module/VuFind/src/VuFind/Search/Summon/Options.php
+++ b/module/VuFind/src/VuFind/Search/Summon/Options.php
@@ -38,13 +38,6 @@ namespace VuFind\Search\Summon;
  */
 class Options extends \VuFind\Search\Base\Options
 {
-    /**
-     * Maximum number of results
-     *
-     * @var int
-     */
-    protected $resultLimit = 400;
-
     /**
      * Maximum number of topic recommendations to show (false for none)
      *
@@ -119,6 +112,8 @@ class Options extends \VuFind\Search\Base\Options
         }
         if (isset($searchSettings->General->result_limit)) {
             $this->resultLimit = $searchSettings->General->result_limit;
+        } else {
+            $this->resultLimit = 400;   // default
         }
 
         // Search handler setup:
@@ -197,18 +192,6 @@ class Options extends \VuFind\Search\Base\Options
         return $this->emptySearchRelevanceOverride;
     }
 
-    /**
-     * If there is a limit to how many search results a user can access, this
-     * method will return that limit.  If there is no limit, this will return
-     * -1.
-     *
-     * @return int
-     */
-    public function getVisibleSearchResultLimit()
-    {
-        return intval($this->resultLimit);
-    }
-
     /**
      * Get the maximum number of topic recommendations (false for none)
      *