diff --git a/src/backend/access/heap/vacuumlazy.c b/src/backend/access/heap/vacuumlazy.c
index cb28830..26115ca 100644
--- a/src/backend/access/heap/vacuumlazy.c
+++ b/src/backend/access/heap/vacuumlazy.c
@@ -429,6 +429,7 @@ heap_vacuum_rel(Relation rel, VacuumParams *params,
 	vacrel->live_tuples = 0;
 	vacrel->recently_dead_tuples = 0;
 	vacrel->missed_dead_tuples = 0;
+	vacrel->cutoffs.OldestXmin = InvalidTransactionId;
 
 	/*
 	 * Get cutoffs that determine which deleted tuples are considered DEAD,
@@ -446,7 +447,22 @@ heap_vacuum_rel(Relation rel, VacuumParams *params,
 	 * want to teach lazy_scan_prune to recompute vistest from time to time,
 	 * to increase the number of dead tuples it can prune away.)
 	 */
-	vacrel->aggressive = vacuum_get_cutoffs(rel, params, &vacrel->cutoffs);
+	/* If this is a TOAST and we have a horizon from the parent, use it */
+	if (params->toast_parent != InvalidOid && params->cached_parent_cutoffs_valid)
+	{
+		vacrel->cutoffs.OldestXmin = params->cached_parent_oldest_xmin;
+		vacrel->aggressive = vacuum_get_cutoffs(rel, params, &vacrel->cutoffs);
+	}
+	else
+	{
+		vacrel->aggressive = vacuum_get_cutoffs(rel, params, &vacrel->cutoffs);
+		if (params->toast_parent == InvalidOid)
+		{
+			params->cached_parent_oldest_xmin = vacrel->cutoffs.OldestXmin;
+			params->cached_parent_cutoffs_valid = true;
+		}
+	}
+
 	vacrel->rel_pages = orig_rel_pages = RelationGetNumberOfBlocks(rel);
 	vacrel->vistest = GlobalVisTestFor(rel);
 	/* Initialize state used to track oldest extant XID/MXID */
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index c42c8a6..0b8442f 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -628,6 +628,7 @@ vacuum(List *relations, VacuumParams *params, BufferAccessStrategy bstrategy,
 				 * to avoid affecting other relations.
 				 */
 				memcpy(&params_copy, params, sizeof(VacuumParams));
+				params_copy.cached_parent_cutoffs_valid = false;
 
 				if (!vacuum_rel(vrel->oid, vrel->relation, &params_copy, bstrategy))
 					continue;
@@ -1117,7 +1118,8 @@ vacuum_get_cutoffs(Relation rel, const VacuumParams *params,
 	 * that only one vacuum process can be working on a particular table at
 	 * any time, and that each vacuum is always an independent transaction.
 	 */
-	cutoffs->OldestXmin = GetOldestNonRemovableTransactionId(rel);
+	if (!TransactionIdIsValid(cutoffs->OldestXmin))
+		cutoffs->OldestXmin = GetOldestNonRemovableTransactionId(rel);
 
 	Assert(TransactionIdIsNormal(cutoffs->OldestXmin));
 
@@ -2297,6 +2299,12 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
 		toast_vacuum_params.options |= VACOPT_PROCESS_MAIN;
 		toast_vacuum_params.toast_parent = relid;
 
+		if (params->cached_parent_cutoffs_valid)
+		{
+			toast_vacuum_params.cached_parent_oldest_xmin = params->cached_parent_oldest_xmin;
+			toast_vacuum_params.cached_parent_cutoffs_valid = true;
+		}
+
 		vacuum_rel(toast_relid, NULL, &toast_vacuum_params, bstrategy);
 	}
 
@@ -2309,7 +2317,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
 	return true;
 }
 
-
 /*
  * Open all the vacuumable indexes of the given relation, obtaining the
  * specified kind of lock on each.  Return an array of Relation pointers for
diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h
index 759f9a8..d5ae2bf 100644
--- a/src/include/commands/vacuum.h
+++ b/src/include/commands/vacuum.h
@@ -237,6 +237,9 @@ typedef struct VacuumParams
 	 * disabled.
 	 */
 	int			nworkers;
+
+	bool		cached_parent_cutoffs_valid; /* Flag for cache cutoffs to TOAST */
+	TransactionId	cached_parent_oldest_xmin;
 } VacuumParams;
 
 /*
