Cq documentation
diff --git a/doc/core/grpc-cq.md b/doc/core/grpc-cq.md
new file mode 100644
index 0000000..b485c35
--- /dev/null
+++ b/doc/core/grpc-cq.md
@@ -0,0 +1,64 @@
+# gRPC Completion Queue
+
+_Author: Sree Kuchibhotla (@sreecha) - Sep 2018_
+
+Code: [completion_queue.cc](https://github.com/grpc/grpc/blob/v1.15.1/src/core/lib/surface/completion_queue.cc)
+
+This document gives an overview of completion queue architecture and focuses mainly on the interaction between completion queue and the Polling engine layer.
+
+## Completion queue attributes
+Completion queue has two attributes
+
+  - Completion_type:
+    - GRPC_CQ_NEXT: grpc_completion_queue_next() can be called (but not grpc_completion_queue_pluck())
+    - GRPC_CQ_PLUCK: grpc_completion_queue_pluck() can be called (but not grpc_completion_queue_next())
+    - GRPC_CQ_CALLBACK: The tags in the queue are function pointers to callbacks. Also, neither next() nor pluck() can be called on this
+
+  - Polling_type:
+    - GRPC_CQ_NON_POLLING: Threads calling completion_queue_next/pluck do not do any polling
+    - GRPC_CQ_DEFAULT_POLLING: Threads calling completion_queue_next/pluck do polling
+    - GRPC_CQ_NON_LISTENING:  Functionally similar to default polling except for a boolean attribute that states that the cq is non-listening. This is used by the grpc-server code to not associate any listening sockets with this completion-queue’s pollset
+
+
+## Details
+
+![image](../images/grpc-cq.png)
+
+
+### **grpc\_completion\_queue\_next()** & **grpc_completion_queue_pluck()** APIS
+
+
+``` C++
+grpc_completion_queue_next(cq, deadline)/pluck(cq, deadline, tag) {
+  while(true) {
+    \\ 1. If an event is queued in the completion queue, dequeue and return
+    \\    (in case of pluck() dequeue only if the tag is the one we are interested in)
+
+    \\ 2. If completion queue shutdown return
+
+    \\ 3. In case of pluck, add (tag, worker) pair to the tag<->worker map on the cq
+
+    \\ 4.  Call grpc_pollset_work(cq’s-pollset, deadline) to do polling
+    \\     Note that if this function found some fds to be readable/writable/error,
+    \\     it would have scheduled those closures (which may queue completion events
+    \\    on SOME completion queue - not necessarily this one)
+  }
+}
+```
+
+### Queuing a completion event (i.e., "tag")
+
+``` C++
+grpc_cq_end_op(cq, tag) {
+  \\ 1. Queue the tag in the event queue
+
+  \\ 2. Find the pollset corresponding to the completion queue
+  \\     (i)  If the cq is of type GRPC_CQ_NEXT, then KICK ANY worker
+  \\          i.e., call grpc_pollset_kick(pollset, nullptr)
+  \\     (ii) If the cq is of type GRPC_CQ_PLUCK, then search the tag<->worker
+  \\          map on the completion queue to find the worker. Then specifically
+  \\          kick that worker i.e  call grpc_pollset_kick(pollset, worker)
+}
+
+```
+ 
diff --git a/doc/images/grpc-cq.png b/doc/images/grpc-cq.png
new file mode 100644
index 0000000..2d9e095
--- /dev/null
+++ b/doc/images/grpc-cq.png
Binary files differ