[ASTERIXDB-3611][RT] Add more stats to query profile

- user model changes: yes
- storage format changes: no
- interface changes: yes

Details:

Add frame counts and average tuples per frame to the
query profile. Also add the raw size of all tuples
forwarded from the operator.

Additionally, improve the calculation of average tuple
size to be a normal average rather than a running average.
This should be fine, because the number of bytes flowing
through and operator should be less than ~8 EB.

Furthermore, pull up all of these stats, along with the
tuple size stats, to the summarized profile in the query
plan. The averages represented in the summarized plan are
a weighted average of each operator's average, proportional
to the cardinality of that instance versus the total across
all partitions.

Ext-ref: MB-66797
Change-Id: I524cbfb1685ad3c7ed269c2db48482e5aba1ce61
Reviewed-on: https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/19809
Integration-Tests: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Tested-by: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Reviewed-by: Ali Alsuliman <ali.al.solaiman@gmail.com>
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/profile/full-scan/full-scan.3.regexjson b/asterixdb/asterix-app/src/test/resources/runtimets/results/profile/full-scan/full-scan.3.regexjson
index 68c1311..106c58a 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results/profile/full-scan/full-scan.3.regexjson
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/profile/full-scan/full-scan.3.regexjson
@@ -40,7 +40,10 @@
                             "cardinality-out": "R{[0-9.]+}",
                             "avg-tuple-size": "R{[0-9.]+}",
                             "min-tuple-size": "R{[0-9.]+}",
-                            "max-tuple-size": "R{[0-9.]+}"
+                            "max-tuple-size": "R{[0-9.]+}",
+                            "tuple-bytes": "R{.+}",
+                            "frames-processed": "R{[0-9.]+}",
+                            "avg-tuples-per-frame": "R{[0-9.]+}"
                         },
                         {
                             "name": "R{.+}",
@@ -51,7 +54,10 @@
                             "cardinality-out": "R{[0-9.]+}",
                             "avg-tuple-size": "R{[0-9.]+}",
                             "min-tuple-size": "R{[0-9.]+}",
-                            "max-tuple-size": "R{[0-9.]+}"
+                            "max-tuple-size": "R{[0-9.]+}",
+                            "tuple-bytes": "R{.+}",
+                            "frames-processed": "R{[0-9.]+}",
+                            "avg-tuples-per-frame": "R{[0-9.]+}"
                         },
                         {
                             "name": "R{.+}",
@@ -60,7 +66,10 @@
                             "cardinality-out": "R{[0-9.]+}",
                             "avg-tuple-size": "R{[0-9.]+}",
                             "min-tuple-size": "R{[0-9.]+}",
-                            "max-tuple-size": "R{[0-9.]+}"
+                            "max-tuple-size": "R{[0-9.]+}",
+                            "tuple-bytes": "R{.+}",
+                            "frames-processed": "R{[0-9.]+}",
+                            "avg-tuples-per-frame": "R{[0-9.]+}"
                         }
                     ]
                 },
@@ -77,7 +86,10 @@
                         "cardinality-out": "R{[0-9.]+}",
                         "avg-tuple-size": "R{[0-9.]+}",
                         "min-tuple-size": "R{[0-9.]+}",
-                        "max-tuple-size": "R{[0-9.]+}"
+                        "max-tuple-size": "R{[0-9.]+}",
+                        "tuple-bytes": "R{.+}",
+                        "frames-processed": "R{[0-9.]+}",
+                        "avg-tuples-per-frame": "R{[0-9.]+}"
                     },
                     {
                         "name": "R{.+}",
@@ -86,7 +98,10 @@
                         "cardinality-out": "R{[0-9.]+}",
                         "avg-tuple-size": "R{[0-9.]+}",
                         "min-tuple-size": "R{[0-9.]+}",
-                        "max-tuple-size": "R{[0-9.]+}"
+                        "max-tuple-size": "R{[0-9.]+}",
+                        "tuple-bytes": "R{.+}",
+                        "frames-processed": "R{[0-9.]+}",
+                        "avg-tuples-per-frame": "R{[0-9.]+}"
                     },
                     {
                         "name": "R{.+}",
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/profile/non-unary-subplan/non-unary-subplan.3.regexjson b/asterixdb/asterix-app/src/test/resources/runtimets/results/profile/non-unary-subplan/non-unary-subplan.3.regexjson
index 3217ebd..946db29 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results/profile/non-unary-subplan/non-unary-subplan.3.regexjson
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/profile/non-unary-subplan/non-unary-subplan.3.regexjson
@@ -36,7 +36,10 @@
               "cardinality-out": "R{[0-9.]+}",
               "avg-tuple-size": "R{[0-9.]+}",
               "min-tuple-size": "R{[0-9.]+}",
-              "max-tuple-size": "R{[0-9.]+}"
+              "max-tuple-size": "R{[0-9.]+}",
+              "tuple-bytes": "R{[0-9.]+}",
+              "frames-processed": "R{[0-9.]+}",
+              "avg-tuples-per-frame": "R{[0-9.]+}"
             },
             {
               "name": "R{(?s).*}",
@@ -45,7 +48,10 @@
               "cardinality-out": "R{[0-9.]+}",
               "avg-tuple-size": "R{[0-9.]+}",
               "min-tuple-size": "R{[0-9.]+}",
-              "max-tuple-size": "R{[0-9.]+}"
+              "max-tuple-size": "R{[0-9.]+}",
+              "tuple-bytes": "R{[0-9.]+}",
+              "frames-processed": "R{[0-9.]+}",
+              "avg-tuples-per-frame": "R{[0-9.]+}"
             },
             {
               "name": "R{(?s).*}",
@@ -54,7 +60,10 @@
               "cardinality-out": "R{[0-9.]+}",
               "avg-tuple-size": "R{[0-9.]+}",
               "min-tuple-size": "R{[0-9.]+}",
-              "max-tuple-size": "R{[0-9.]+}"
+              "max-tuple-size": "R{[0-9.]+}",
+              "tuple-bytes": "R{[0-9.]+}",
+              "frames-processed": "R{[0-9.]+}",
+              "avg-tuples-per-frame": "R{[0-9.]+}"
             },
             {
               "name": "R{(?s).*}",
@@ -63,7 +72,10 @@
               "cardinality-out": "R{[0-9.]+}",
               "avg-tuple-size": "R{[0-9.]+}",
               "min-tuple-size": "R{[0-9.]+}",
-              "max-tuple-size": "R{[0-9.]+}"
+              "max-tuple-size": "R{[0-9.]+}",
+              "tuple-bytes": "R{[0-9.]+}",
+              "frames-processed": "R{[0-9.]+}",
+              "avg-tuples-per-frame": "R{[0-9.]+}"
             },
             {
               "name": "R{(?s).*}",
@@ -72,7 +84,10 @@
               "cardinality-out": "R{[0-9.]+}",
               "avg-tuple-size": "R{[0-9.]+}",
               "min-tuple-size": "R{[0-9.]+}",
-              "max-tuple-size": "R{[0-9.]+}"
+              "max-tuple-size": "R{[0-9.]+}",
+              "tuple-bytes": "R{[0-9.]+}",
+              "frames-processed": "R{[0-9.]+}",
+              "avg-tuples-per-frame": "R{[0-9.]+}"
             },
             {
               "name": "R{(?s).*}",
@@ -81,7 +96,10 @@
               "cardinality-out": "R{[0-9.]+}",
               "avg-tuple-size": "R{[0-9.]+}",
               "min-tuple-size": "R{[0-9.]+}",
-              "max-tuple-size": "R{[0-9.]+}"
+              "max-tuple-size": "R{[0-9.]+}",
+              "tuple-bytes": "R{[0-9.]+}",
+              "frames-processed": "R{[0-9.]+}",
+              "avg-tuples-per-frame": "R{[0-9.]+}"
             },
             {
               "name": "R{(?s).*}",
@@ -90,7 +108,10 @@
               "cardinality-out": "R{[0-9.]+}",
               "avg-tuple-size": "R{[0-9.]+}",
               "min-tuple-size": "R{[0-9.]+}",
-              "max-tuple-size": "R{[0-9.]+}"
+              "max-tuple-size": "R{[0-9.]+}",
+              "tuple-bytes": "R{[0-9.]+}",
+              "frames-processed": "R{[0-9.]+}",
+              "avg-tuples-per-frame": "R{[0-9.]+}"
             },
             {
               "name": "R{(?s).*}",
@@ -99,7 +120,10 @@
               "cardinality-out": "R{[0-9.]+}",
               "avg-tuple-size": "R{[0-9.]+}",
               "min-tuple-size": "R{[0-9.]+}",
-              "max-tuple-size": "R{[0-9.]+}"
+              "max-tuple-size": "R{[0-9.]+}",
+              "tuple-bytes": "R{[0-9.]+}",
+              "frames-processed": "R{[0-9.]+}",
+              "avg-tuples-per-frame": "R{[0-9.]+}"
             },
             {
               "name": "R{(?s).*}",
@@ -108,7 +132,10 @@
               "cardinality-out": "R{[0-9.]+}",
               "avg-tuple-size": "R{[0-9.]+}",
               "min-tuple-size": "R{[0-9.]+}",
-              "max-tuple-size": "R{[0-9.]+}"
+              "max-tuple-size": "R{[0-9.]+}",
+              "tuple-bytes": "R{[0-9.]+}",
+              "frames-processed": "R{[0-9.]+}",
+              "avg-tuples-per-frame": "R{[0-9.]+}"
             },
             {
               "name": "R{(?s).*}",
@@ -117,7 +144,10 @@
               "cardinality-out": "R{[0-9.]+}",
               "avg-tuple-size": "R{[0-9.]+}",
               "min-tuple-size": "R{[0-9.]+}",
-              "max-tuple-size": "R{[0-9.]+}"
+              "max-tuple-size": "R{[0-9.]+}",
+              "tuple-bytes": "R{[0-9.]+}",
+              "frames-processed": "R{[0-9.]+}",
+              "avg-tuples-per-frame": "R{[0-9.]+}"
             },
             {
               "name": "R{(?s).*}",
@@ -126,7 +156,10 @@
               "cardinality-out": "R{[0-9.]+}",
               "avg-tuple-size": "R{[0-9.]+}",
               "min-tuple-size": "R{[0-9.]+}",
-              "max-tuple-size": "R{[0-9.]+}"
+              "max-tuple-size": "R{[0-9.]+}",
+              "tuple-bytes": "R{[0-9.]+}",
+              "frames-processed": "R{[0-9.]+}",
+              "avg-tuples-per-frame": "R{[0-9.]+}"
             },
             {
               "name": "R{(?s).*}",
@@ -135,7 +168,10 @@
               "cardinality-out": "R{[0-9.]+}",
               "avg-tuple-size": "R{[0-9.]+}",
               "min-tuple-size": "R{[0-9.]+}",
-              "max-tuple-size": "R{[0-9.]+}"
+              "max-tuple-size": "R{[0-9.]+}",
+              "tuple-bytes": "R{[0-9.]+}",
+              "frames-processed": "R{[0-9.]+}",
+              "avg-tuples-per-frame": "R{[0-9.]+}"
             },
             {
               "name": "R{(?s).*}",
@@ -144,7 +180,10 @@
               "cardinality-out": "R{[0-9.]+}",
               "avg-tuple-size": "R{[0-9.]+}",
               "min-tuple-size": "R{[0-9.]+}",
-              "max-tuple-size": "R{[0-9.]+}"
+              "max-tuple-size": "R{[0-9.]+}",
+              "tuple-bytes": "R{[0-9.]+}",
+              "frames-processed": "R{[0-9.]+}",
+              "avg-tuples-per-frame": "R{[0-9.]+}"
             },
             {
               "name": "R{(?s).*}",
@@ -183,7 +222,10 @@
               "cardinality-out": "R{[0-9.]+}",
               "avg-tuple-size": "R{[0-9.]+}",
               "min-tuple-size": "R{[0-9.]+}",
-              "max-tuple-size": "R{[0-9.]+}"
+              "max-tuple-size": "R{[0-9.]+}",
+              "tuple-bytes": "R{[0-9.]+}",
+              "frames-processed": "R{[0-9.]+}",
+              "avg-tuples-per-frame": "R{[0-9.]+}"
             },
             {
               "name": "R{(?s).*}",
@@ -192,7 +234,10 @@
               "cardinality-out": "R{[0-9.]+}",
               "avg-tuple-size": "R{[0-9.]+}",
               "min-tuple-size": "R{[0-9.]+}",
-              "max-tuple-size": "R{[0-9.]+}"
+              "max-tuple-size": "R{[0-9.]+}",
+              "tuple-bytes": "R{[0-9.]+}",
+              "frames-processed": "R{[0-9.]+}",
+              "avg-tuples-per-frame": "R{[0-9.]+}"
             },
             {
               "name": "R{(?s).*}",
@@ -201,7 +246,10 @@
               "cardinality-out": "R{[0-9.]+}",
               "avg-tuple-size": "R{[0-9.]+}",
               "min-tuple-size": "R{[0-9.]+}",
-              "max-tuple-size": "R{[0-9.]+}"
+              "max-tuple-size": "R{[0-9.]+}",
+              "tuple-bytes": "R{[0-9.]+}",
+              "frames-processed": "R{[0-9.]+}",
+              "avg-tuples-per-frame": "R{[0-9.]+}"
             },
             {
               "name": "R{(?s).*}",
@@ -210,7 +258,10 @@
               "cardinality-out": "R{[0-9.]+}",
               "avg-tuple-size": "R{[0-9.]+}",
               "min-tuple-size": "R{[0-9.]+}",
-              "max-tuple-size": "R{[0-9.]+}"
+              "max-tuple-size": "R{[0-9.]+}",
+              "tuple-bytes": "R{[0-9.]+}",
+              "frames-processed": "R{[0-9.]+}",
+              "avg-tuples-per-frame": "R{[0-9.]+}"
             }
           ]
         }
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/profile/plansleep/sleep.3.regexjson b/asterixdb/asterix-app/src/test/resources/runtimets/results/profile/plansleep/sleep.3.regexjson
index 75e1874..a9a4b4d 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results/profile/plansleep/sleep.3.regexjson
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/profile/plansleep/sleep.3.regexjson
@@ -40,6 +40,12 @@
             "min-cardinality": 3,
             "max-cardinality": 3,
             "total-cardinality": 3,
+            "min-tuple-size": 39,
+            "max-tuple-size": 44,
+            "avg-tuple-size": 41.666666666666664,
+            "frame-count": 1,
+            "avg-tuples-per-frame": 3.0,
+            "tuple-bytes": "125 bytes",
             "physical-operator": "STREAM_PROJECT",
             "execution-mode": "PARTITIONED",
             "optimizer-estimates": {
@@ -89,7 +95,13 @@
                         "max-time": "R{[0-9.]+}",
                         "min-cardinality": 3,
                         "max-cardinality": 3,
-                        "total-cardinality": 3
+                        "total-cardinality": 3,
+                        "min-tuple-size": 53,
+                        "max-tuple-size": 63,
+                        "avg-tuple-size": 58.333333333333336,
+                        "frame-count": 1,
+                        "avg-tuples-per-frame": 3.0,
+                        "tuple-bytes": "175 bytes"
                       }
                     ],
                     "physical-operator": "STABLE_SORT [$$49(ASC)]",
@@ -131,6 +143,12 @@
                             "min-cardinality": 3,
                             "max-cardinality": 3,
                             "total-cardinality": 3,
+                            "min-tuple-size": 53,
+                            "max-tuple-size": 63,
+                            "avg-tuple-size": 58.333333333333336,
+                            "frame-count": 1,
+                            "avg-tuples-per-frame": 3.0,
+                            "tuple-bytes": "175 bytes",
                             "physical-operator": "ASSIGN",
                             "execution-mode": "PARTITIONED",
                             "optimizer-estimates": {
@@ -158,6 +176,12 @@
                                 "min-cardinality": 3,
                                 "max-cardinality": 3,
                                 "total-cardinality": 3,
+                                "min-tuple-size": 53,
+                                "max-tuple-size": 63,
+                                "avg-tuple-size": 58.333333333333336,
+                                "frame-count": 1,
+                                "avg-tuples-per-frame": 3.0,
+                                "tuple-bytes": "175 bytes",
                                 "physical-operator": "ASSIGN",
                                 "execution-mode": "PARTITIONED",
                                 "optimizer-estimates": {
@@ -224,7 +248,13 @@
                                             "max-time": "R{[0-9.]+}",
                                             "min-cardinality": 3,
                                             "max-cardinality": 3,
-                                            "total-cardinality": 3
+                                            "total-cardinality": 3,
+                                            "min-tuple-size": 27,
+                                            "max-tuple-size": 32,
+                                            "avg-tuple-size": 29.666666666666668,
+                                            "frame-count": 1,
+                                            "avg-tuples-per-frame": 3.0,
+                                            "tuple-bytes": "89 bytes"
                                           }
                                         ],
                                         "physical-operator": "SORT_GROUP_BY[$$56]",
@@ -298,7 +328,13 @@
                                                     "max-time": "R{[0-9.]+}",
                                                     "min-cardinality": 3,
                                                     "max-cardinality": 3,
-                                                    "total-cardinality": 3
+                                                    "total-cardinality": 3,
+                                                    "min-tuple-size": 27,
+                                                    "max-tuple-size": 32,
+                                                    "avg-tuple-size": 29.666666666666668,
+                                                    "frame-count": 1,
+                                                    "avg-tuples-per-frame": 3.0,
+                                                    "tuple-bytes": "89 bytes"
                                                   }
                                                 ],
                                                 "physical-operator": "SORT_GROUP_BY[$$50]",
@@ -339,6 +375,12 @@
                                                         "min-cardinality": "R{[0-9.]+}",
                                                         "max-cardinality": "R{[0-9.]+}",
                                                         "total-cardinality": "R{[0-9.]+}",
+                                                        "min-tuple-size": "R{[0-9.]+}",
+                                                        "max-tuple-size": "R{[0-9.]+}",
+                                                        "avg-tuple-size": "R{[0-9.]+}",
+                                                        "frame-count": "R{[0-9.]+}",
+                                                        "avg-tuples-per-frame": "R{[0-9.]+}",
+                                                        "tuple-bytes": "R{.+}",
                                                         "physical-operator": "ASSIGN",
                                                         "execution-mode": "PARTITIONED",
                                                         "optimizer-estimates": {
@@ -357,6 +399,12 @@
                                                             "min-cardinality": 5,
                                                             "max-cardinality": 5,
                                                             "total-cardinality": 5,
+                                                            "min-tuple-size": 142,
+                                                            "max-tuple-size": 151,
+                                                            "avg-tuple-size": 145.6,
+                                                            "frame-count": 1,
+                                                            "avg-tuples-per-frame": 5.0,
+                                                            "tuple-bytes": "728 bytes",
                                                             "physical-operator": "STREAM_SELECT",
                                                             "execution-mode": "PARTITIONED",
                                                             "optimizer-estimates": {
@@ -377,6 +425,12 @@
                                                                 "min-cardinality": 10,
                                                                 "max-cardinality": 10,
                                                                 "total-cardinality": 10,
+                                                                "min-tuple-size": 137,
+                                                                "max-tuple-size": 151,
+                                                                "avg-tuple-size": 143.1,
+                                                                "frame-count": 1,
+                                                                "avg-tuples-per-frame": 10.0,
+                                                                "tuple-bytes": "1 KB",
                                                                 "physical-operator": "STREAM_PROJECT",
                                                                 "execution-mode": "PARTITIONED",
                                                                 "optimizer-estimates": {
@@ -411,6 +465,12 @@
                                                                         "min-cardinality": 10,
                                                                         "max-cardinality": 10,
                                                                         "total-cardinality": 10,
+                                                                        "min-tuple-size": 150,
+                                                                        "max-tuple-size": 164,
+                                                                        "avg-tuple-size": 156.1,
+                                                                        "frame-count": 1,
+                                                                        "avg-tuples-per-frame": 10.0,
+                                                                        "tuple-bytes": "1 KB",
                                                                         "physical-operator": "DATASOURCE_SCAN",
                                                                         "execution-mode": "PARTITIONED",
                                                                         "optimizer-estimates": {
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/profile/sleep/sleep.3.regexjson b/asterixdb/asterix-app/src/test/resources/runtimets/results/profile/sleep/sleep.3.regexjson
index b83927a..d5ceca0 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results/profile/sleep/sleep.3.regexjson
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/profile/sleep/sleep.3.regexjson
@@ -23,7 +23,10 @@
                             "cardinality-out": "R{[0-9.]+}",
                             "avg-tuple-size": "R{[0-9.]+}",
                             "min-tuple-size": "R{[0-9.]+}",
-                            "max-tuple-size": "R{[0-9.]+}"
+                            "max-tuple-size": "R{[0-9.]+}",
+                            "tuple-bytes": "R{.+}",
+                            "frames-processed": "R{[0-9.]+}",
+                            "avg-tuples-per-frame": "R{[0-9.]+}"
                         },
                         {
                             "name": "R{.+}",
@@ -34,16 +37,22 @@
                             "cardinality-out": "R{[0-9.]+}",
                             "avg-tuple-size": "R{[0-9.]+}",
                             "min-tuple-size": "R{[0-9.]+}",
-                            "max-tuple-size": "R{[0-9.]+}"
+                            "max-tuple-size": "R{[0-9.]+}",
+                            "tuple-bytes": "R{.+}",
+                            "frames-processed": "R{[0-9.]+}",
+                            "avg-tuples-per-frame": "R{[0-9.]+}"
                         },
                         {
                             "name": "R{.+}",
                             "run-time": "R{5.+}",
                             "runtime-id": "R{.+}",
                             "cardinality-out": 10,
-                            "avg-tuple-size": 25,
+                            "avg-tuple-size": 25.0,
                             "min-tuple-size": 25,
-                            "max-tuple-size": 25
+                            "max-tuple-size": 25,
+                            "tuple-bytes": 250,
+                            "frames-processed": 1,
+                            "avg-tuples-per-frame": 10.0
                         },
                         {
                             "name": "R{.+}",
@@ -52,7 +61,10 @@
                             "cardinality-out": "R{[0-9.]+}",
                             "avg-tuple-size": "R{[0-9.]+}",
                             "min-tuple-size": "R{[0-9.]+}",
-                            "max-tuple-size": "R{[0-9.]+}"
+                            "max-tuple-size": "R{[0-9.]+}",
+                            "tuple-bytes": "R{.+}",
+                            "frames-processed": "R{[0-9.]+}",
+                            "avg-tuples-per-frame": "R{[0-9.]+}"
                         },
                         {
                             "name": "R{.+}",
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/profile/sleep/sleep.4.regexjson b/asterixdb/asterix-app/src/test/resources/runtimets/results/profile/sleep/sleep.4.regexjson
index 87b6ab1..aafd143 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results/profile/sleep/sleep.4.regexjson
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/profile/sleep/sleep.4.regexjson
@@ -40,7 +40,10 @@
               "cardinality-out": "R{[0-9.]+}",
               "avg-tuple-size": "R{[0-9.]+}",
               "min-tuple-size": "R{[0-9.]+}",
-              "max-tuple-size": "R{[0-9.]+}"
+              "max-tuple-size": "R{[0-9.]+}",
+              "tuple-bytes": "R{.+}",
+              "frames-processed": "R{[0-9.]+}",
+              "avg-tuples-per-frame": "R{[0-9.]+}"
             }
           ]
         },
@@ -70,7 +73,10 @@
               "cardinality-out": "R{[0-9.]+}",
               "avg-tuple-size": "R{[0-9.]+}",
               "min-tuple-size": "R{[0-9.]+}",
-              "max-tuple-size": "R{[0-9.]+}"
+              "max-tuple-size": "R{[0-9.]+}",
+              "tuple-bytes": "R{.+}",
+              "frames-processed": "R{[0-9.]+}",
+              "avg-tuples-per-frame": "R{[0-9.]+}"
             },
             {
               "name": "R{.+}",
@@ -79,7 +85,10 @@
               "cardinality-out": "R{[0-9.]+}",
               "avg-tuple-size": "R{[0-9.]+}",
               "min-tuple-size": "R{[0-9.]+}",
-              "max-tuple-size": "R{[0-9.]+}"
+              "max-tuple-size": "R{[0-9.]+}",
+              "tuple-bytes": "R{.+}",
+              "frames-processed": "R{[0-9.]+}",
+              "avg-tuples-per-frame": "R{[0-9.]+}"
             },
             {
               "name": "R{.+}",
@@ -99,9 +108,12 @@
               "run-time": "R{[0-9.]+}",
               "runtime-id": "R{.+}",
               "cardinality-out": 10,
-              "avg-tuple-size": 140,
+              "avg-tuple-size": 143.1,
               "min-tuple-size": 137,
-              "max-tuple-size": 151
+              "max-tuple-size": 151,
+              "tuple-bytes": 1431,
+              "frames-processed": 1,
+              "avg-tuples-per-frame": 10.0
             },
             {
               "name": "R{.+}",
@@ -112,7 +124,10 @@
               "cardinality-out": "R{[0-9.]+}",
               "avg-tuple-size": "R{[0-9.]+}",
               "min-tuple-size": "R{[0-9.]+}",
-              "max-tuple-size": "R{[0-9.]+}"
+              "max-tuple-size": "R{[0-9.]+}",
+              "tuple-bytes": "R{.+}",
+              "frames-processed": "R{[0-9.]+}",
+              "avg-tuples-per-frame": "R{[0-9.]+}"
             },
             {
               "name": "R{.+}",
@@ -121,7 +136,10 @@
               "cardinality-out": "R{[0-9.]+}",
               "avg-tuple-size": "R{[0-9.]+}",
               "min-tuple-size": "R{[0-9.]+}",
-              "max-tuple-size": "R{[0-9.]+}"
+              "max-tuple-size": "R{[0-9.]+}",
+              "tuple-bytes": "R{.+}",
+              "frames-processed": "R{[0-9.]+}",
+              "avg-tuples-per-frame": "R{[0-9.]+}"
             },
             {
               "name": "R{.+}",
@@ -130,7 +148,10 @@
               "cardinality-out": "R{[0-9.]+}",
               "avg-tuple-size": "R{[0-9.]+}",
               "min-tuple-size": "R{[0-9.]+}",
-              "max-tuple-size": "R{[0-9.]+}"
+              "max-tuple-size": "R{[0-9.]+}",
+              "tuple-bytes": "R{.+}",
+              "frames-processed": "R{[0-9.]+}",
+              "avg-tuples-per-frame": "R{[0-9.]+}"
             },
             {
               "name": "R{.+}",
@@ -139,7 +160,10 @@
               "cardinality-out": "R{[0-9.]+}",
               "avg-tuple-size": "R{[0-9.]+}",
               "min-tuple-size": "R{[0-9.]+}",
-              "max-tuple-size": "R{[0-9.]+}"
+              "max-tuple-size": "R{[0-9.]+}",
+              "tuple-bytes": "R{.+}",
+              "frames-processed": "R{[0-9.]+}",
+              "avg-tuples-per-frame": "R{[0-9.]+}"
             },
             {
               "name": "R{.+}",
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/profile/sleep/sleep.5.regexjson b/asterixdb/asterix-app/src/test/resources/runtimets/results/profile/sleep/sleep.5.regexjson
index 187c3c1..a107d0a 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results/profile/sleep/sleep.5.regexjson
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/profile/sleep/sleep.5.regexjson
@@ -40,7 +40,10 @@
               "cardinality-out": "R{[0-9.]+}",
               "avg-tuple-size": "R{[0-9.]+}",
               "min-tuple-size": "R{[0-9.]+}",
-              "max-tuple-size": "R{[0-9.]+}"
+              "max-tuple-size": "R{[0-9.]+}",
+              "tuple-bytes": "R{.+}",
+              "frames-processed": "R{[0-9.]+}",
+              "avg-tuples-per-frame": "R{[0-9.]+}"
             }
           ]
         },
@@ -70,7 +73,10 @@
               "cardinality-out": "R{[0-9.]+}",
               "avg-tuple-size": "R{[0-9.]+}",
               "min-tuple-size": "R{[0-9.]+}",
-              "max-tuple-size": "R{[0-9.]+}"
+              "max-tuple-size": "R{[0-9.]+}",
+              "tuple-bytes": "R{.+}",
+              "frames-processed": "R{[0-9.]+}",
+              "avg-tuples-per-frame": "R{[0-9.]+}"
             },
             {
               "name": "R{.+}",
@@ -79,7 +85,10 @@
               "cardinality-out": "R{[0-9.]+}",
               "avg-tuple-size": "R{[0-9.]+}",
               "min-tuple-size": "R{[0-9.]+}",
-              "max-tuple-size": "R{[0-9.]+}"
+              "max-tuple-size": "R{[0-9.]+}",
+              "tuple-bytes": "R{.+}",
+              "frames-processed": "R{[0-9.]+}",
+              "avg-tuples-per-frame": "R{[0-9.]+}"
             },
             {
               "name": "R{.+}",
@@ -88,7 +97,10 @@
               "cardinality-out": "R{[0-9.]+}",
               "avg-tuple-size": "R{[0-9.]+}",
               "min-tuple-size": "R{[0-9.]+}",
-              "max-tuple-size": "R{[0-9.]+}"
+              "max-tuple-size": "R{[0-9.]+}",
+              "tuple-bytes": "R{.+}",
+              "frames-processed": "R{[0-9.]+}",
+              "avg-tuples-per-frame": "R{[0-9.]+}"
             },
             {
               "name": "R{.+}",
@@ -127,7 +139,10 @@
               "cardinality-out": "R{[0-9.]+}",
               "avg-tuple-size": "R{[0-9.]+}",
               "min-tuple-size": "R{[0-9.]+}",
-              "max-tuple-size": "R{[0-9.]+}"
+              "max-tuple-size": "R{[0-9.]+}",
+              "tuple-bytes": "R{.+}",
+              "frames-processed": "R{[0-9.]+}",
+              "avg-tuples-per-frame": "R{[0-9.]+}"
             }
           ]
         },
@@ -144,7 +159,10 @@
               "cardinality-out": "R{[0-9.]+}",
               "avg-tuple-size": "R{[0-9.]+}",
               "min-tuple-size": "R{[0-9.]+}",
-              "max-tuple-size": "R{[0-9.]+}"
+              "max-tuple-size": "R{[0-9.]+}",
+              "tuple-bytes": "R{.+}",
+              "frames-processed": "R{[0-9.]+}",
+              "avg-tuples-per-frame": "R{[0-9.]+}"
             },
             {
               "name": "R{.+}",
@@ -155,7 +173,10 @@
               "cardinality-out": "R{[0-9.]+}",
               "avg-tuple-size": "R{[0-9.]+}",
               "min-tuple-size": "R{[0-9.]+}",
-              "max-tuple-size": "R{[0-9.]+}"
+              "max-tuple-size": "R{[0-9.]+}",
+              "tuple-bytes": "R{.+}",
+              "frames-processed": "R{[0-9.]+}",
+              "avg-tuples-per-frame": "R{[0-9.]+}"
             },
             {
               "name": "R{.+}",
@@ -164,7 +185,10 @@
               "cardinality-out": "R{[0-9.]+}",
               "avg-tuple-size": "R{[0-9.]+}",
               "min-tuple-size": "R{[0-9.]+}",
-              "max-tuple-size": "R{[0-9.]+}"
+              "max-tuple-size": "R{[0-9.]+}",
+              "tuple-bytes": "R{.+}",
+              "frames-processed": "R{[0-9.]+}",
+              "avg-tuples-per-frame": "R{[0-9.]+}"
             },
             {
               "name": "R{.+}",
@@ -173,7 +197,10 @@
               "cardinality-out": "R{[0-9.]+}",
               "avg-tuple-size": "R{[0-9.]+}",
               "min-tuple-size": "R{[0-9.]+}",
-              "max-tuple-size": "R{[0-9.]+}"
+              "max-tuple-size": "R{[0-9.]+}",
+              "tuple-bytes": "R{.+}",
+              "frames-processed": "R{[0-9.]+}",
+              "avg-tuples-per-frame": "R{[0-9.]+}"
             },
             {
               "name": "R{.+}",
@@ -182,7 +209,10 @@
               "cardinality-out": "R{[0-9.]+}",
               "avg-tuple-size": "R{[0-9.]+}",
               "min-tuple-size": "R{[0-9.]+}",
-              "max-tuple-size": "R{[0-9.]+}"
+              "max-tuple-size": "R{[0-9.]+}",
+              "tuple-bytes": "R{.+}",
+              "frames-processed": "R{[0-9.]+}",
+              "avg-tuples-per-frame": "R{[0-9.]+}"
             },
             {
               "name": "R{.+}",
@@ -204,7 +234,10 @@
               "cardinality-out": "R{[0-9.]+}",
               "avg-tuple-size": "R{[0-9.]+}",
               "min-tuple-size": "R{[0-9.]+}",
-              "max-tuple-size": "R{[0-9.]+}"
+              "max-tuple-size": "R{[0-9.]+}",
+              "tuple-bytes": "R{.+}",
+              "frames-processed": "R{[0-9.]+}",
+              "avg-tuples-per-frame": "R{[0-9.]+}"
             },
             {
               "name": "R{.+}",
diff --git a/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/prettyprint/LogicalOperatorPrettyPrintVisitorJson.java b/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/prettyprint/LogicalOperatorPrettyPrintVisitorJson.java
index 7185c24..3ca1277 100644
--- a/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/prettyprint/LogicalOperatorPrettyPrintVisitorJson.java
+++ b/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/prettyprint/LogicalOperatorPrettyPrintVisitorJson.java
@@ -28,6 +28,7 @@
 import java.util.Objects;
 import java.util.Optional;
 
+import org.apache.commons.io.FileUtils;
 import org.apache.commons.lang3.mutable.Mutable;
 import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
 import org.apache.hyracks.algebricks.common.exceptions.NotImplementedException;
@@ -116,6 +117,18 @@
     private static final String MAX_CARDINALITY = "max-cardinality";
 
     private static final String TOTAL_CARDINALITY = "total-cardinality";
+
+    private static final String MIN_TUPLE_SIZE = "min-tuple-size";
+
+    private static final String MAX_TUPLE_SIZE = "max-tuple-size";
+
+    private static final String AVG_TUPLE_SIZE = "avg-tuple-size";
+
+    private static final String FRAME_COUNT = "frame-count";
+
+    private static final String TUPLE_BYTES = "tuple-bytes";
+
+    private static final String AVG_TUPLES_PER_FRAME = "avg-tuples-per-frame";
     private static final String NAME = "name";
     private static final String ID = "id";
     private static final String RUNTIME_ID = "runtime-id";
@@ -266,18 +279,53 @@
 
     }
 
+    private static class WeightedAvg {
+        private long totalCard = 0;
+        private double weightedSum = 0.0;
+        private double avg = 0.0;
+
+        public void update(double val, long card) {
+            weightedSum += val * card;
+            totalCard += card;
+            avg = totalCard > 0 ? weightedSum / totalCard : 0.0;
+        }
+
+    }
+
     private class OperatorProfile {
 
         Map<String, String> activityNames;
         Map<String, MinMax<Double>> activityTimes;
         Map<String, MinMax<Long>> activityCards;
         Map<String, Long> activityCardTotal;
+        Map<String, MinMax<Long>> activityTupleSizes;
+        Map<String, WeightedAvg> activityAvgTupleSizes;
+        Map<String, Long> activityFrameCountTotal;
+        Map<String, WeightedAvg> activityAvgTuplesPerFrame;
+        Map<String, Long> activityTupleBytes;
 
         OperatorProfile() {
             activityNames = new HashMap<>();
             activityTimes = new HashMap<>();
             activityCards = new HashMap<>();
             activityCardTotal = new HashMap<>();
+            activityTupleSizes = new HashMap<>();
+            activityAvgTupleSizes = new HashMap<>();
+            activityFrameCountTotal = new HashMap<>();
+            activityAvgTuplesPerFrame = new HashMap<>();
+            activityTupleBytes = new HashMap<>();
+        }
+
+        void updateOperator(String extendedOpId, String name, double time, long cardinality, long minSize, long maxSize,
+                double avgSize, long frameCount, double avgTuples, long tupleBytes) {
+            updateOperator(extendedOpId, name, time, cardinality);
+            updateMinMax(minSize, extendedOpId, activityTupleSizes);
+            updateMinMax(maxSize, extendedOpId, activityTupleSizes);
+            updateAverage(avgSize, cardinality, extendedOpId, activityAvgTupleSizes);
+            activityFrameCountTotal.compute(extendedOpId,
+                    (id, calls) -> calls == null ? frameCount : calls + frameCount);
+            updateAverage(avgTuples, cardinality, extendedOpId, activityAvgTuplesPerFrame);
+            activityTupleBytes.compute(extendedOpId, (id, bytes) -> bytes == null ? tupleBytes : bytes + tupleBytes);
         }
 
         void updateOperator(String extendedOpId, String name, double time, long cardinality) {
@@ -295,6 +343,11 @@
             MinMax<T> stat = opMap.computeIfAbsent(id, i -> new MinMax<>(comp));
             stat.update(comp);
         }
+
+        private void updateAverage(double avg, long card, String id, Map<String, WeightedAvg> opMap) {
+            WeightedAvg stat = opMap.computeIfAbsent(id, i -> new WeightedAvg());
+            stat.update(avg, card);
+        }
     }
 
     private Pair<ExtendedActivityId, String> splitAcId(String name) {
@@ -314,9 +367,18 @@
                             profiledOps.computeIfAbsent(counters.get(RUNTIME_ID).asText(), i -> new OperatorProfile());
                     Pair<ExtendedActivityId, String> identities = splitAcId(counters.get(NAME).asText());
                     JsonNode card = counters.get("cardinality-out");
-                    if (card != null) {
+                    JsonNode minTupleSz = counters.get("min-tuple-size");
+                    JsonNode maxTupleSz = counters.get("max-tuple-size");
+                    JsonNode avgTupleSz = counters.get("avg-tuple-size");
+                    JsonNode tupleBytes = counters.get("tuple-bytes");
+                    JsonNode framesProcessedNode = counters.get("frames-processed");
+                    JsonNode avgTuplesPerFrameNode = counters.get("avg-tuples-per-frame");
+                    if (card != null && minTupleSz != null && maxTupleSz != null && avgTupleSz != null
+                            && framesProcessedNode != null && avgTuplesPerFrameNode != null && tupleBytes != null) {
                         info.updateOperator(identities.first.getActivityAndLocalId(), identities.second,
-                                counters.get("run-time").asDouble(), card.asLong(0));
+                                counters.get("run-time").asDouble(), card.asLong(), minTupleSz.asLong(),
+                                maxTupleSz.asLong(), avgTupleSz.asDouble(), framesProcessedNode.asLong(),
+                                avgTuplesPerFrameNode.asDouble(), tupleBytes.asLong());
                     } else {
                         info.updateOperator(identities.first.getActivityAndLocalId(), identities.second,
                                 counters.get("run-time").asDouble());
@@ -394,7 +456,9 @@
     }
 
     private void printActivityStats(Optional<MinMax<Double>> time, Optional<MinMax<Long>> card,
-            Optional<Long> totalCard) throws IOException {
+            Optional<Long> totalCard, Optional<MinMax<Long>> tupleSize, Optional<WeightedAvg> avgTupleSize,
+            Optional<Long> frameCount, Optional<WeightedAvg> avgTuplesPerFrame, Optional<Long> tupleBytes)
+            throws IOException {
         if (time.isPresent()) {
             jsonGenerator.writeNumberField(MIN_TIME, time.get().min);
             jsonGenerator.writeNumberField(MAX_TIME, time.get().max);
@@ -406,6 +470,22 @@
         if (totalCard.isPresent()) {
             jsonGenerator.writeNumberField(TOTAL_CARDINALITY, totalCard.get());
         }
+        if (tupleSize.isPresent()) {
+            jsonGenerator.writeNumberField(MIN_TUPLE_SIZE, tupleSize.get().min);
+            jsonGenerator.writeNumberField(MAX_TUPLE_SIZE, tupleSize.get().max);
+        }
+        if (avgTupleSize.isPresent()) {
+            jsonGenerator.writeNumberField(AVG_TUPLE_SIZE, avgTupleSize.get().avg);
+        }
+        if (frameCount.isPresent()) {
+            jsonGenerator.writeNumberField(FRAME_COUNT, frameCount.get());
+        }
+        if (avgTuplesPerFrame.isPresent()) {
+            jsonGenerator.writeNumberField(AVG_TUPLES_PER_FRAME, avgTuplesPerFrame.get().avg);
+        }
+        if (tupleBytes.isPresent()) {
+            jsonGenerator.writeStringField(TUPLE_BYTES, FileUtils.byteCountToDisplaySize(tupleBytes.get()));
+        }
     }
 
     private void printOperatorStats(OperatorProfile info) throws IOException {
@@ -413,7 +493,13 @@
             Optional<MinMax<Double>> times = info.activityTimes.values().stream().findFirst();
             Optional<MinMax<Long>> cards = info.activityCards.values().stream().findFirst();
             Optional<Long> total = info.activityCardTotal.values().stream().findFirst();
-            printActivityStats(times, cards, total);
+            Optional<MinMax<Long>> tupleSizes = info.activityTupleSizes.values().stream().findFirst();
+            Optional<WeightedAvg> avgTupleSize = info.activityAvgTupleSizes.values().stream().findFirst();
+            Optional<Long> frameCount = info.activityFrameCountTotal.values().stream().findFirst();
+            Optional<WeightedAvg> avgTuplesPerFrame = info.activityAvgTuplesPerFrame.values().stream().findFirst();
+            Optional<Long> tupleBytes = info.activityTupleBytes.values().stream().findFirst();
+            printActivityStats(times, cards, total, tupleSizes, avgTupleSize, frameCount, avgTuplesPerFrame,
+                    tupleBytes);
         } else if (info.activityTimes.size() > 1) {
             jsonGenerator.writeArrayFieldStart("activity-stats");
             for (String acId : info.activityTimes.keySet()) {
@@ -425,7 +511,12 @@
                 jsonGenerator.writeStringField("id", acId);
                 printActivityStats(Optional.ofNullable(info.activityTimes.get(acId)),
                         Optional.ofNullable(info.activityCards.get(acId)),
-                        Optional.ofNullable(info.activityCardTotal.get(acId)));
+                        Optional.ofNullable(info.activityCardTotal.get(acId)),
+                        Optional.ofNullable(info.activityTupleSizes.get(acId)),
+                        Optional.ofNullable(info.activityAvgTupleSizes.get(acId)),
+                        Optional.ofNullable(info.activityFrameCountTotal.get(acId)),
+                        Optional.ofNullable(info.activityAvgTuplesPerFrame.get(acId)),
+                        Optional.ofNullable(info.activityTupleBytes.get(acId)));
                 jsonGenerator.writeEndObject();
             }
             jsonGenerator.writeEndArray();
diff --git a/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/dataflow/ProfiledFrameWriter.java b/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/dataflow/ProfiledFrameWriter.java
index fb4ed3c..53de340 100644
--- a/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/dataflow/ProfiledFrameWriter.java
+++ b/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/dataflow/ProfiledFrameWriter.java
@@ -44,7 +44,6 @@
     protected IOperatorStats inputStats = NoOpOperatorStats.INSTANCE;
     private int minSz = Integer.MAX_VALUE;
     private int maxSz = -1;
-    private long avgSz;
 
     private final ICounter totalTime;
 
@@ -87,23 +86,22 @@
         int tupleCountOffset = FrameHelper.getTupleCountOffset(buffer.limit());
         int tupleCount = IntSerDeUtils.getInt(buffer.array(), tupleCountOffset);
         ICounter tupleCounter = inputStats.getTupleCounter();
-        long prevCount = tupleCounter.get();
+        long tupleSizes = 0;
         for (int i = 0; i < tupleCount; i++) {
             int tupleLen = getTupleLength(i, tupleCountOffset, buffer);
+            tupleSizes += tupleLen;
             if (maxSz < tupleLen) {
                 maxSz = tupleLen;
             }
             if (minSz > tupleLen) {
                 minSz = tupleLen;
             }
-            long prev = avgSz * prevCount;
-            avgSz = (prev + tupleLen) / (prevCount + 1);
-            prevCount++;
         }
         inputStats.getMaxTupleSz().set(maxSz);
         inputStats.getMinTupleSz().set(minSz);
-        inputStats.getAverageTupleSz().set(avgSz);
+        inputStats.getTupleBytes().update(tupleSizes);
         tupleCounter.update(tupleCount);
+        inputStats.getTotalFrameCount().update(1);
     }
 
     @Override
diff --git a/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/job/profiling/IOperatorStats.java b/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/job/profiling/IOperatorStats.java
index 2dd7b41..6b6f64a 100644
--- a/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/job/profiling/IOperatorStats.java
+++ b/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/job/profiling/IOperatorStats.java
@@ -72,10 +72,10 @@
     ICounter cloudPersistPageCounter();
 
     /**
-     * @return A counter used to set the average tuple size outputted by an operator
+     * @return A counter used to set the total number of tuple bytes outputted by an operator
      */
 
-    ICounter getAverageTupleSz();
+    ICounter getTupleBytes();
 
     /**
      * @return A counter used to set the max tuple size outputted by an operator
@@ -94,6 +94,8 @@
      *         like index searches or other scan types
      */
 
+    ICounter getTotalFrameCount();
+
     ICounter getInputTupleCounter();
 
     ICounter getLevel();
diff --git a/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/job/profiling/NoOpOperatorStats.java b/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/job/profiling/NoOpOperatorStats.java
index 8219d2f..57dd546 100644
--- a/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/job/profiling/NoOpOperatorStats.java
+++ b/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/job/profiling/NoOpOperatorStats.java
@@ -110,7 +110,7 @@
     }
 
     @Override
-    public ICounter getAverageTupleSz() {
+    public ICounter getTupleBytes() {
         return NOOP_COUNTER;
     }
 
@@ -125,6 +125,11 @@
     }
 
     @Override
+    public ICounter getTotalFrameCount() {
+        return NOOP_COUNTER;
+    }
+
+    @Override
     public ICounter getInputTupleCounter() {
         return NOOP_COUNTER;
     }
diff --git a/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/job/profiling/OperatorStats.java b/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/job/profiling/OperatorStats.java
index 9dbac3d..93ee0cd 100644
--- a/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/job/profiling/OperatorStats.java
+++ b/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/job/profiling/OperatorStats.java
@@ -28,7 +28,7 @@
 import org.apache.hyracks.api.job.profiling.counters.ICounter;
 
 public class OperatorStats implements IOperatorStats {
-    private static final long serialVersionUID = 6401830963361567126L;
+    private static final long serialVersionUID = 6401830963361567128L;
     public final String operatorName;
 
     public final String operatorId;
@@ -39,10 +39,11 @@
     public final ICounter cloudReadRequestCounter;
     public final ICounter cloudReadPageCounter;
     public final ICounter cloudPersistPageCounter;
-    public final ICounter avgTupleSz;
+    public final ICounter tupleBytes;
     public final ICounter minTupleSz;
     public final ICounter maxTupleSz;
     public final ICounter inputTupleCounter;
+    public final ICounter frameCounter;
     public final ICounter level;
     public final ICounter bytesRead;
     public final ICounter bytesWritten;
@@ -63,10 +64,11 @@
         cloudReadRequestCounter = new Counter("cloudReadRequestCounter");
         cloudReadPageCounter = new Counter("cloudReadPageCounter");
         cloudPersistPageCounter = new Counter("cloudPersistPageCounter");
-        avgTupleSz = new Counter("avgTupleSz");
+        tupleBytes = new Counter("tupleBytes");
         minTupleSz = new Counter("minTupleSz");
         maxTupleSz = new Counter("maxTupleSz");
         inputTupleCounter = new Counter("inputTupleCounter");
+        frameCounter = new Counter("frameCounter");
         level = new Counter("level");
         bytesRead = new Counter("bytesRead");
         bytesWritten = new Counter("bytesWritten");
@@ -115,11 +117,6 @@
     }
 
     @Override
-    public ICounter getAverageTupleSz() {
-        return avgTupleSz;
-    }
-
-    @Override
     public ICounter getMaxTupleSz() {
         return maxTupleSz;
     }
@@ -130,6 +127,11 @@
     }
 
     @Override
+    public ICounter getTupleBytes() {
+        return tupleBytes;
+    }
+
+    @Override
     public ICounter getInputTupleCounter() {
         return inputTupleCounter;
     }
@@ -150,6 +152,11 @@
     }
 
     @Override
+    public ICounter getTotalFrameCount() {
+        return frameCounter;
+    }
+
+    @Override
     public String getOperatorId() {
         return operatorId;
     }
@@ -195,10 +202,11 @@
         output.writeLong(cloudReadRequestCounter.get());
         output.writeLong(cloudReadPageCounter.get());
         output.writeLong(cloudPersistPageCounter.get());
-        output.writeLong(avgTupleSz.get());
+        output.writeLong(tupleBytes.get());
         output.writeLong(minTupleSz.get());
         output.writeLong(maxTupleSz.get());
         output.writeLong(inputTupleCounter.get());
+        output.writeLong(frameCounter.get());
         output.writeLong(level.get());
         output.writeLong(bytesRead.get());
         output.writeLong(bytesWritten.get());
@@ -214,10 +222,11 @@
         cloudReadRequestCounter.set(input.readLong());
         cloudReadPageCounter.set(input.readLong());
         cloudPersistPageCounter.set(input.readLong());
-        avgTupleSz.set(input.readLong());
+        tupleBytes.set(input.readLong());
         minTupleSz.set(input.readLong());
         maxTupleSz.set(input.readLong());
         inputTupleCounter.set(input.readLong());
+        frameCounter.set(input.readLong());
         level.set(input.readLong());
         bytesRead.set(input.readLong());
         bytesWritten.set(input.readLong());
@@ -249,10 +258,11 @@
                 + cloudReadRequestCounter.getName() + "\": " + cloudReadRequestCounter.get() + ", \""
                 + cloudReadPageCounter.getName() + "\": " + cloudReadPageCounter.get() + ", \""
                 + cloudPersistPageCounter.getName() + "\": " + cloudPersistPageCounter.get() + ", \""
-                + avgTupleSz.getName() + "\": " + avgTupleSz.get() + ", \"" + minTupleSz.getName() + "\": "
-                + minTupleSz.get() + ", \"" + minTupleSz.getName() + "\": " + timeCounter.get() + ", \""
-                + inputTupleCounter.getName() + "\": " + bytesRead.get() + ", \"" + bytesRead.getName() + "\": "
-                + bytesWritten.get() + ", \"" + bytesWritten.getName() + "\": " + inputTupleCounter.get() + ", \""
-                + level.getName() + "\": " + level.get() + ", \"indexStats\": \"" + indexesStats + "\" }";
+                + tupleBytes.getName() + "\": " + tupleBytes.get() + ", \"" + minTupleSz.getName() + "\": "
+                + minTupleSz.get() + ", \"" + maxTupleSz.getName() + "\": " + maxTupleSz.get() + ", \""
+                + inputTupleCounter.getName() + "\": " + inputTupleCounter.get() + ", \"" + frameCounter.getName()
+                + "\": " + frameCounter.get() + ", \"" + bytesRead.getName() + "\": " + bytesRead.get() + ", \""
+                + bytesWritten.getName() + "\": " + bytesWritten.get() + ", \"" + level.getName() + "\": " + level.get()
+                + ", \"indexStats\": \"" + indexesStats + "\" }";
     }
 }
diff --git a/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-common/src/main/java/org/apache/hyracks/control/common/job/profiling/om/TaskProfile.java b/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-common/src/main/java/org/apache/hyracks/control/common/job/profiling/om/TaskProfile.java
index b66be1e..e361e42 100644
--- a/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-common/src/main/java/org/apache/hyracks/control/common/job/profiling/om/TaskProfile.java
+++ b/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-common/src/main/java/org/apache/hyracks/control/common/job/profiling/om/TaskProfile.java
@@ -142,9 +142,13 @@
             }
             if (value.getTupleCounter().get() > 0) {
                 jpe.put("cardinality-out", value.getTupleCounter().get());
-                jpe.put("avg-tuple-size", value.getAverageTupleSz().get());
+                jpe.put("avg-tuple-size", (double) value.getTupleBytes().get() / value.getTupleCounter().get());
                 jpe.put("min-tuple-size", value.getMinTupleSz().get());
                 jpe.put("max-tuple-size", value.getMaxTupleSz().get());
+                jpe.put("tuple-bytes", value.getTupleBytes().get());
+                jpe.put("frames-processed", value.getTotalFrameCount().get());
+                jpe.put("avg-tuples-per-frame",
+                        (double) value.getTupleCounter().get() / value.getTotalFrameCount().get());
             }
             if (value.getLevel().get() > -1) {
                 jpe.put("level", value.getLevel().get());