diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml
index 7bfbc87109..574837889b 100644
--- a/doc/src/sgml/config.sgml
+++ b/doc/src/sgml/config.sgml
@@ -6989,7 +6989,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv;
        </para>
 
        <para>
-        The value can range from <literal>0</literal> to <literal>100</literal>.
+        The value should be non-negative.
         When <varname>vacuum_cleanup_index_scale_factor</varname> is set to
         <literal>0</literal>, index scans are never skipped during
         <command>VACUUM</command> cleanup. The default value is <literal>0.1</literal>.
diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c
index e0c9c3431c..5671bb6830 100644
--- a/src/backend/access/common/reloptions.c
+++ b/src/backend/access/common/reloptions.c
@@ -416,7 +416,7 @@ static relopt_real realRelOpts[] =
 			RELOPT_KIND_BTREE,
 			ShareUpdateExclusiveLock
 		},
-		-1, 0.0, 100.0
+		-1, 0.0, DBL_MAX
 	},
 	/* list terminator */
 	{{NULL}}
diff --git a/src/backend/access/nbtree/nbtree.c b/src/backend/access/nbtree/nbtree.c
index 27a3032e42..cdd0403e1d 100644
--- a/src/backend/access/nbtree/nbtree.c
+++ b/src/backend/access/nbtree/nbtree.c
@@ -816,6 +816,7 @@ _bt_vacuum_needs_cleanup(IndexVacuumInfo *info)
 	{
 		StdRdOptions *relopts;
 		float8		cleanup_scale_factor;
+		float8		prev_num_heap_tuples;
 
 		/*
 		 * If table receives enough insertions and no cleanup was performed,
@@ -829,11 +830,12 @@ _bt_vacuum_needs_cleanup(IndexVacuumInfo *info)
 								relopts->vacuum_cleanup_index_scale_factor >= 0)
 			? relopts->vacuum_cleanup_index_scale_factor
 			: vacuum_cleanup_index_scale_factor;
+		prev_num_heap_tuples = metad->btm_last_cleanup_num_heap_tuples;
 
 		if (cleanup_scale_factor <= 0 ||
-			metad->btm_last_cleanup_num_heap_tuples < 0 ||
-			info->num_heap_tuples > (1.0 + cleanup_scale_factor) *
-			metad->btm_last_cleanup_num_heap_tuples)
+			prev_num_heap_tuples < 0 ||
+			(info->num_heap_tuples - prev_num_heap_tuples) /
+			prev_num_heap_tuples >= cleanup_scale_factor)
 			result = true;
 	}
 
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index 859ef931e7..daa2894c5a 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -3253,7 +3253,7 @@ static struct config_real ConfigureNamesReal[] =
 			NULL
 		},
 		&vacuum_cleanup_index_scale_factor,
-		0.1, 0.0, 100.0,
+		0.1, 0.0, DBL_MAX,
 		NULL, NULL, NULL
 	},
 
diff --git a/src/test/regress/expected/btree_index.out b/src/test/regress/expected/btree_index.out
index 4778ac14a4..1ad33190a2 100644
--- a/src/test/regress/expected/btree_index.out
+++ b/src/test/regress/expected/btree_index.out
@@ -165,7 +165,7 @@ select reloptions from pg_class WHERE oid = 'btree_idx1'::regclass;
 -- Fail while setting improper values
 create index btree_idx_err on btree_test(a) with (vacuum_cleanup_index_scale_factor = -10.0);
 ERROR:  value -10.0 out of bounds for option "vacuum_cleanup_index_scale_factor"
-DETAIL:  Valid values are between "0.000000" and "100.000000".
+DETAIL:  Valid values are between "0.000000" and "179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368.000000".
 create index btree_idx_err on btree_test(a) with (vacuum_cleanup_index_scale_factor = 100.0);
 create index btree_idx_err on btree_test(a) with (vacuum_cleanup_index_scale_factor = 'string');
 ERROR:  invalid value for floating point option "vacuum_cleanup_index_scale_factor": string
