diff --git a/src/backend/executor/execParallel.c b/src/backend/executor/execParallel.c
index 52f1a96db5f..e3790e5eb7b 100644
--- a/src/backend/executor/execParallel.c
+++ b/src/backend/executor/execParallel.c
@@ -1281,9 +1281,6 @@ ParallelQueryMain(dsm_segment *seg, shm_toc *toc)
 	/* Report workers' query for monitoring purposes */
 	pgstat_report_activity(STATE_RUNNING, debug_query_string);
 
-	/* Prepare to track buffer usage during query execution. */
-	InstrStartParallelQuery();
-
 	/* Attach to the dynamic shared memory area. */
 	area_space = shm_toc_lookup(toc, PARALLEL_KEY_DSA, false);
 	area = dsa_attach_in_place(area_space, seg);
@@ -1309,6 +1306,9 @@ ParallelQueryMain(dsm_segment *seg, shm_toc *toc)
 	/* Pass down any tuple bound */
 	ExecSetTupleBound(fpes->tuples_needed, queryDesc->planstate);
 
+	/* Prepare to track buffer usage during query execution. */
+	InstrStartParallelQuery();
+
 	/*
 	 * Run the plan.  If we specified a tuple bound, be careful not to demand
 	 * more tuples than that.
diff --git a/src/backend/executor/execProcnode.c b/src/backend/executor/execProcnode.c
index 8b3663b3c9d..fb020c9fb83 100644
--- a/src/backend/executor/execProcnode.c
+++ b/src/backend/executor/execProcnode.c
@@ -752,6 +752,13 @@ ExecShutdownNode(PlanState *node)
 
 	planstate_tree_walker(node, ExecShutdownNode, NULL);
 
+	/*
+	 * Allow instrumentation to count stats collected during shutdown for
+	 * nodes that are executed atleast once.
+	 */
+	if (node->instrument && node->instrument->running)
+		InstrStartNode(node->instrument);
+
 	switch (nodeTag(node))
 	{
 		case T_GatherState:
@@ -776,6 +783,13 @@ ExecShutdownNode(PlanState *node)
 			break;
 	}
 
+	/*
+	 * Allow instrumentation to count stats collected during shutdown for
+	 * nodes that are executed atleast once.
+	 */
+	if (node->instrument && node->instrument->running)
+		InstrStopNode(node->instrument, 0);
+
 	return false;
 }
 
diff --git a/src/backend/executor/nodeGather.c b/src/backend/executor/nodeGather.c
index cdc9c51bd15..4a700b7b30e 100644
--- a/src/backend/executor/nodeGather.c
+++ b/src/backend/executor/nodeGather.c
@@ -324,7 +324,10 @@ gather_readnext(GatherState *gatherstate)
 			Assert(!tup);
 			--gatherstate->nreaders;
 			if (gatherstate->nreaders == 0)
+			{
+				ExecShutdownGatherWorkers(gatherstate);
 				return NULL;
+			}
 			memmove(&gatherstate->reader[gatherstate->nextreader],
 					&gatherstate->reader[gatherstate->nextreader + 1],
 					sizeof(TupleQueueReader *)
diff --git a/src/backend/executor/nodeLimit.c b/src/backend/executor/nodeLimit.c
index 56d98b4490b..66ea6aa3c35 100644
--- a/src/backend/executor/nodeLimit.c
+++ b/src/backend/executor/nodeLimit.c
@@ -134,6 +134,8 @@ ExecLimit(PlanState *pstate)
 					node->position - node->offset >= node->count)
 				{
 					node->lstate = LIMIT_WINDOWEND;
+					/* Allow nodes to release or shut down resources. */
+					(void) ExecShutdownNode(outerPlan);
 					return NULL;
 				}
 
