diff --git a/src/backend/commands/explain.c b/src/backend/commands/explain.c
index 1831ea81cf..6a64282027 100644
--- a/src/backend/commands/explain.c
+++ b/src/backend/commands/explain.c
@@ -24,6 +24,7 @@
 #include "nodes/extensible.h"
 #include "nodes/makefuncs.h"
 #include "nodes/nodeFuncs.h"
+#include "optimizer/cost.h"
 #include "parser/parsetree.h"
 #include "rewrite/rewriteHandler.h"
 #include "storage/bufmgr.h"
@@ -1441,7 +1442,8 @@ ExplainNode(PlanState *planstate, List *ancestors,
 		{
 			if (es->timing)
 				appendStringInfo(es->str,
-								 " (actual time=%.3f..%.3f rows=%.0f loops=%.0f)",
+								 " (actual cost=%.2f..%.2f time=%.3f..%.3f rows=%.0f loops=%.0f)",
+								 plan->cost_info->startup_cost, actual_total_cost(plan, rows),
 								 startup_ms, total_ms, rows, nloops);
 			else
 				appendStringInfo(es->str,
diff --git a/src/backend/optimizer/path/costsize.c b/src/backend/optimizer/path/costsize.c
index 4b9be13f08..16c2c904bb 100644
--- a/src/backend/optimizer/path/costsize.c
+++ b/src/backend/optimizer/path/costsize.c
@@ -201,32 +201,23 @@ clamp_row_est(double nrows)
 
 
 /*
- * cost_seqscan
- *	  Determines and returns the cost of scanning a relation sequentially.
- *
- * 'baserel' is the relation to be scanned
- * 'param_info' is the ParamPathInfo if this is a parameterized path, else NULL
+ * Fill the cost info structure. Later we use this structure to compute the
+ * cost estimation.
  */
-void
-cost_seqscan(Path *path, PlannerInfo *root,
+CostInfo *
+cost_info_seqscan(Path *path, PlannerInfo *root,
 			 RelOptInfo *baserel, ParamPathInfo *param_info)
 {
-	Cost		startup_cost = 0;
-	Cost		cpu_run_cost;
-	Cost		disk_run_cost;
-	double		spc_seq_page_cost;
+	Cost		per_page_cost;
+	Cost		per_row_cost;
+	Cost		per_tuple_cost;
+	Cost		startup_cost = 0.0;
+	double		npages;
+	double		ntuples;
+	double		parallel_divisor;
 	QualCost	qpqual_cost;
-	Cost		cpu_per_tuple;
+	CostInfo	*cost_info;
 
-	/* Should only be applied to base relations */
-	Assert(baserel->relid > 0);
-	Assert(baserel->rtekind == RTE_RELATION);
-
-	/* Mark the path with the correct row estimate */
-	if (param_info)
-		path->rows = param_info->ppi_rows;
-	else
-		path->rows = baserel->rows;
 
 	if (!enable_seqscan)
 		startup_cost += disable_cost;
@@ -234,31 +225,93 @@ cost_seqscan(Path *path, PlannerInfo *root,
 	/* fetch estimated page cost for tablespace containing table */
 	get_tablespace_page_costs(baserel->reltablespace,
 							  NULL,
-							  &spc_seq_page_cost);
+							  &per_page_cost);
 
-	/*
-	 * disk costs
-	 */
-	disk_run_cost = spc_seq_page_cost * baserel->pages;
+	npages = baserel->pages;
 
 	/* CPU costs */
 	get_restriction_qual_cost(root, baserel, param_info, &qpqual_cost);
 
-	startup_cost += qpqual_cost.startup;
-	cpu_per_tuple = cpu_tuple_cost + qpqual_cost.per_tuple;
-	cpu_run_cost = cpu_per_tuple * baserel->tuples;
+	startup_cost = qpqual_cost.startup;
+	per_tuple_cost = cpu_tuple_cost + qpqual_cost.per_tuple;
+	ntuples = baserel->tuples;
 	/* tlist eval costs are paid per output row, not per tuple scanned */
 	startup_cost += path->pathtarget->cost.startup;
-	cpu_run_cost += path->pathtarget->cost.per_tuple * path->rows;
+	per_row_cost = path->pathtarget->cost.per_tuple;
+	parallel_divisor = 1.0;
 
 	/* Adjust costing for parallelism, if used. */
 	if (path->parallel_workers > 0)
 	{
-		double		parallel_divisor = get_parallel_divisor(path);
+		parallel_divisor = get_parallel_divisor(path);
+	}
 
-		/* The CPU cost is divided among all the workers. */
-		cpu_run_cost /= parallel_divisor;
+	cost_info = palloc(sizeof(CostInfo));
+	cost_info->per_page_cost = per_page_cost;
+	cost_info->per_row_cost = per_row_cost;
+	cost_info->per_tuple_cost = per_tuple_cost;
+	cost_info->startup_cost = startup_cost;
+	cost_info->npages = npages;
+	cost_info->ntuples = ntuples;
+	cost_info->parallel_divisor= parallel_divisor;
+
+	return cost_info;
+}
+
+
+/*
+ * Calculate the total cost of a SeqScan
+ */
+double
+total_cost_seqscan(CostInfo *cost_info, double nrows)
+{
+	Cost disk_run_cost;
+	Cost cpu_run_cost;
+
+	/*
+	 * disk costs
+	 */
+	disk_run_cost = cost_info->per_page_cost * cost_info->npages;
 
+	cpu_run_cost = cost_info->per_tuple_cost * cost_info->ntuples + \
+					cost_info->per_row_cost * nrows;
+
+	/* The CPU cost is divided among all the workers. */
+	cpu_run_cost /= cost_info->parallel_divisor;
+
+	return cost_info->startup_cost + cpu_run_cost + disk_run_cost;
+}
+
+
+/*
+ * cost_seqscan
+ *	  Determines and returns the cost of scanning a relation sequentially.
+ *
+ * 'baserel' is the relation to be scanned
+ * 'param_info' is the ParamPathInfo if this is a parameterized path, else NULL
+ */
+void
+cost_seqscan(Path *path, PlannerInfo *root,
+			 RelOptInfo *baserel, ParamPathInfo *param_info)
+{
+	double		nrows;
+	CostInfo	*cost_info;
+
+	/* Should only be applied to base relations */
+	Assert(baserel->relid > 0);
+	Assert(baserel->rtekind == RTE_RELATION);
+
+	/* Mark the path with the correct row estimate */
+	if (param_info)
+		nrows = param_info->ppi_rows;
+	else
+		nrows = baserel->rows;
+
+	cost_info = cost_info_seqscan(path, root, baserel, param_info);
+
+	/* Adjust costing for parallelism, if used. */
+	if (path->parallel_workers > 0)
+	{
 		/*
 		 * It may be possible to amortize some of the I/O cost, but probably
 		 * not very much, because most operating systems already do aggressive
@@ -270,11 +323,13 @@ cost_seqscan(Path *path, PlannerInfo *root,
 		 * In the case of a parallel plan, the row count needs to represent
 		 * the number of tuples processed per worker.
 		 */
-		path->rows = clamp_row_est(path->rows / parallel_divisor);
+		path->rows = clamp_row_est(path->rows / cost_info->parallel_divisor);
 	}
 
-	path->startup_cost = startup_cost;
-	path->total_cost = startup_cost + cpu_run_cost + disk_run_cost;
+	path->startup_cost = cost_info->startup_cost;
+	path->total_cost = total_cost_seqscan(cost_info, nrows);
+
+	pfree(cost_info);
 }
 
 /*
@@ -5551,3 +5606,19 @@ compute_bitmap_pages(PlannerInfo *root, RelOptInfo *baserel, Path *bitmapqual,
 
 	return pages_fetched;
 }
+
+/*
+ * Get the actual total cost by using the actual number of rows
+ */
+double
+actual_total_cost(Plan *plan, double nrows)
+{
+	switch (nodeTag(plan))
+	{
+		case T_SeqScan:
+			return total_cost_seqscan(plan->cost_info, nrows);
+		default:
+			break;
+	}
+	return -1.0;
+}
diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c
index 236f506cfb..3133eb79c0 100644
--- a/src/backend/optimizer/plan/createplan.c
+++ b/src/backend/optimizer/plan/createplan.c
@@ -349,6 +349,8 @@ create_plan(PlannerInfo *root, Path *best_path)
 	 * re-used later
 	 */
 	root->plan_params = NIL;
+	plan->cost_info = cost_info_seqscan(best_path, root,
+						best_path->parent, best_path->param_info);
 
 	return plan;
 }
diff --git a/src/include/nodes/plannodes.h b/src/include/nodes/plannodes.h
index 6d087c268f..36534c619f 100644
--- a/src/include/nodes/plannodes.h
+++ b/src/include/nodes/plannodes.h
@@ -127,6 +127,8 @@ typedef struct Plan
 	double		plan_rows;		/* number of rows plan is expected to emit */
 	int			plan_width;		/* average row width in bytes */
 
+	struct CostInfo *cost_info;
+
 	/*
 	 * information needed for parallel query
 	 */
diff --git a/src/include/optimizer/cost.h b/src/include/optimizer/cost.h
index ac6de0f6be..4576d3747d 100644
--- a/src/include/optimizer/cost.h
+++ b/src/include/optimizer/cost.h
@@ -38,6 +38,17 @@ typedef enum
 	CONSTRAINT_EXCLUSION_PARTITION	/* apply c_e to otherrels only */
 }			ConstraintExclusionType;
 
+typedef struct CostInfo
+{
+	Cost		per_page_cost;
+	Cost		per_row_cost;
+	Cost		per_tuple_cost;
+	Cost		startup_cost;
+	double		npages;
+	double		ntuples;
+	double		parallel_divisor;
+} CostInfo;
+
 
 /*
  * prototypes for costsize.c
@@ -199,4 +210,14 @@ extern PathTarget *set_pathtarget_cost_width(PlannerInfo *root, PathTarget *targ
 extern double compute_bitmap_pages(PlannerInfo *root, RelOptInfo *baserel,
 					 Path *bitmapqual, int loop_count, Cost *cost, double *tuple);
 
+
+extern CostInfo *cost_info_seqscan(Path *path, PlannerInfo *root,
+			 RelOptInfo *baserel, ParamPathInfo *param_info);
+
+extern double total_cost_seqscan(CostInfo *cost_info, double nrows);
+
+/* The actual total cost calculated based on the instument.
+ * Currently, only the number of rows is used to show a proof of concept.
+ */
+extern double actual_total_cost(Plan *plan, double nrows);
 #endif							/* COST_H */
