diff --git a/src/proto/grpc/testing/control.proto b/src/proto/grpc/testing/control.proto
index a55483e3e0e349efe6ed7e515946a2f564f2a9dd..aa6a23abe5a3c9b12907088386a3fb4539afbbea 100644
--- a/src/proto/grpc/testing/control.proto
+++ b/src/proto/grpc/testing/control.proto
@@ -243,6 +243,7 @@ message ScenarioResultSummary
   double failed_requests_per_second = 14;
 
   double client_polls_per_request = 15;
+  double server_polls_per_request = 16;
 }
 
 // Results of a single benchmark scenario.
diff --git a/src/proto/grpc/testing/stats.proto b/src/proto/grpc/testing/stats.proto
index 8818f70cc5f5d8c26cfa69f459530945d81296e6..78df5333421d03d15d74e315c9fc795b104c1283 100644
--- a/src/proto/grpc/testing/stats.proto
+++ b/src/proto/grpc/testing/stats.proto
@@ -47,6 +47,8 @@ message ServerStats {
 
   // change in idle time of the server (data from proc/stat)
   uint64 idle_cpu_time = 5;
+
+  uint64 cq_poll_count = 6;
 }
 
 // Histogram params based on grpc/support/histogram.c
diff --git a/test/cpp/qps/driver.cc b/test/cpp/qps/driver.cc
index c4cae286fde76c6649488b146e7e5ba3411f012d..24e9f730af1edbc1dbf05fd82b4ce2ca577a0464 100644
--- a/test/cpp/qps/driver.cc
+++ b/test/cpp/qps/driver.cc
@@ -112,7 +112,8 @@ static deque<string> get_workers(const string& env_name) {
 static double WallTime(ClientStats s) { return s.time_elapsed(); }
 static double SystemTime(ClientStats s) { return s.time_system(); }
 static double UserTime(ClientStats s) { return s.time_user(); }
-static double PollCount(ClientStats s) { return s.cq_poll_count(); }
+static double CliPollCount(ClientStats s) { return s.cq_poll_count(); }
+static double SvrPollCount(ServerStats s) { return s.cq_poll_count(); }
 static double ServerWallTime(ServerStats s) { return s.time_elapsed(); }
 static double ServerSystemTime(ServerStats s) { return s.time_system(); }
 static double ServerUserTime(ServerStats s) { return s.time_user(); }
@@ -181,8 +182,10 @@ static void postprocess_scenario_result(ScenarioResult* result) {
     result->mutable_summary()->set_failed_requests_per_second(failures /
                                                               time_estimate);
   }
-  gpr_log(GPR_INFO, "poll count : %f", sum(result->client_stats(), PollCount));
-  result->mutable_summary()->set_client_polls_per_request(sum(result->client_stats(), PollCount)/histogram.Count());
+  gpr_log(GPR_INFO, "client poll count : %f", sum(result->client_stats(), CliPollCount));
+  result->mutable_summary()->set_client_polls_per_request(sum(result->client_stats(), CliPollCount)/histogram.Count());
+  gpr_log(GPR_INFO, "server poll count : %f", sum(result->server_stats(), SvrPollCount));
+  result->mutable_summary()->set_server_polls_per_request(sum(result->server_stats(), SvrPollCount)/histogram.Count());
 }
 
 std::unique_ptr<ScenarioResult> RunScenario(
diff --git a/test/cpp/qps/report.cc b/test/cpp/qps/report.cc
index ae56b0e857498c09b77dbfb9eb5f2f2e0a361c06..8bb4c9a3a50a63c86e591eb6fa743f334c5d42d0 100644
--- a/test/cpp/qps/report.cc
+++ b/test/cpp/qps/report.cc
@@ -128,8 +128,10 @@ void GprLogReporter::ReportCpuUsage(const ScenarioResult& result) {
 }
 
 void GprLogReporter::ReportPollCount(const ScenarioResult& result) {
-  gpr_log(GPR_INFO, "Client Polls per Request: %.2f%%",
+  gpr_log(GPR_INFO, "Client Polls per Request: %.2f",
           result.summary().client_polls_per_request());
+  gpr_log(GPR_INFO, "Server Polls per Request: %.2f",
+          result.summary().server_polls_per_request());
 }
 
 void JsonReporter::ReportQPS(const ScenarioResult& result) {
diff --git a/test/cpp/qps/server.h b/test/cpp/qps/server.h
index 8fbf37a0957869868fec4b68c75c0823f21e1b39..5d5d5ffe096d61ffc1fe2b5ba8458590dc51c0e2 100644
--- a/test/cpp/qps/server.h
+++ b/test/cpp/qps/server.h
@@ -49,7 +49,7 @@ namespace testing {
 
 class Server {
  public:
-  explicit Server(const ServerConfig& config) : timer_(new UsageTimer) {
+  explicit Server(const ServerConfig& config) : timer_(new UsageTimer), last_reset_poll_count_(0) {
     cores_ = gpr_cpu_num_cores();
     if (config.port()) {
       port_ = config.port();
@@ -62,10 +62,12 @@ class Server {
 
   ServerStats Mark(bool reset) {
     UsageTimer::Result timer_result;
+    int last_reset_poll_count_to_use = last_reset_poll_count_;
     if (reset) {
       std::unique_ptr<UsageTimer> timer(new UsageTimer);
       timer.swap(timer_);
       timer_result = timer->Mark();
+      last_reset_poll_count_ = GetPollCount();
     } else {
       timer_result = timer_->Mark();
     }
@@ -76,6 +78,7 @@ class Server {
     stats.set_time_user(timer_result.user);
     stats.set_total_cpu_time(timer_result.total_cpu_time);
     stats.set_idle_cpu_time(timer_result.idle_cpu_time);
+    stats.set_cq_poll_count(GetPollCount() - last_reset_poll_count_to_use);
     return stats;
   }
 
@@ -106,10 +109,16 @@ class Server {
     }
   }
 
+  virtual int GetPollCount() {
+    // For sync server.
+    return 0;
+  }
+
  private:
   int port_;
   int cores_;
   std::unique_ptr<UsageTimer> timer_;
+  int last_reset_poll_count_;
 };
 
 std::unique_ptr<Server> CreateSynchronousServer(const ServerConfig& config);
diff --git a/test/cpp/qps/server_async.cc b/test/cpp/qps/server_async.cc
index b499b82091e55d48d618a61677fbb7bd4ab5eb04..e503e6220474d5b2561c3f85f52a0af0eb4915f3 100644
--- a/test/cpp/qps/server_async.cc
+++ b/test/cpp/qps/server_async.cc
@@ -53,6 +53,10 @@
 #include "test/core/util/test_config.h"
 #include "test/cpp/qps/server.h"
 
+extern "C" {
+#include "src/core/lib/surface/completion_queue.h"
+}
+
 namespace grpc {
 namespace testing {
 
@@ -154,6 +158,16 @@ class AsyncQpsServerTest final : public grpc::testing::Server {
     shutdown_thread.join();
   }
 
+  int GetPollCount() {
+    int count = 0;
+    int i = 0;
+    for (auto cq = srv_cqs_.begin(); cq != srv_cqs_.end(); cq++) {
+      int k = (int)grpc_get_cq_poll_num((*cq)->cq());
+      gpr_log(GPR_INFO, "%d: per cq poll:%d", i++, k);
+      count += k;
+    }
+    return count;
+  }
  private:
   void ShutdownThreadFunc() {
     // TODO (vpai): Remove this deadline and allow Shutdown to finish properly