Home » Blogs » Engineering » How Prodio leveraged NodeJs async/await to modify Zerodha APIs - Part 1

How Prodio leveraged NodeJs async/await to modify Zerodha APIs - Part 1

Pawan Wagh

Home » Blogs » Engineering » How Prodio leveraged NodeJs async/await to modify Zerodha APIs - Part 1

How Prodio leveraged NodeJs async/await to modify Zerodha APIs — Part 1

We are building something that helps to manage risk, buckets your capital into meaningful allocations, automates your trade, and monitors your trading actions & decisions for retrospection and future trading decisions.

One of our core and challenging requirement is to process tick data which we receive from Zerodha which publishes tick data on websockets. Zerodha has provided a nice NodeJs SDK to save our coding efforts and simplified the whole process.

Our problem that Zerodha SDK doesn’t solve

Zerodha SDK provides an event “ticks”, which can trigger a callback function passed to it on every received tick. By definition, we can receive multiple of ticks in a single second. But Zerodha SDK calls that callback function in a synchronous way which could block further execution of thread if we’ve to execute algorithms inside that callback function. This leads to missing ticks, if the post tick arrival processing — whether running some formulae or tracking for strategy — runs longer as number of instruments and number of formulae rise , the next tick will be missed.

e.g. One feature which required immediate solution was threshold tracking. In this feature, whenever price of an instrument crosses certain threshold of profit defined by subscriber in a limited time period (eg. if price of an instrument increases by 5% in 10 days), a notification should be sent to the subscriber.

So — we needed to convert zerodha node sdk into async mode, so we could set our processes running after the tick is received, while our main thread continues to listen for next tick. That allows us almost any amount of time for processing compared to earlier 500 ms that’s generally there between Zerodha ticks.

//Sample code for logging frequency of tick data from zerodha using zerodha SDK
const KiteTicker = require("kiteconnect").KiteTicker;
const ticker = new KiteTicker({
api_key: "api_key",
access_token: "access_token"
ticker.on("ticks", onTicks);
ticker.on("connect", subscribe);
var start = process.hrtime();
function onTicks(tick) {
elapsedTime("TICK RECEIVED IN:"); // first log may give incorrect result
console.log("TICK DATA RECEIVED FOR INSTRUMENTS: ", tick.length);
function subscribe() {
const items = [738561, ........];
ticker.setMode(ticker.modeFull, items);
function elapsedTime(note){
const precision = 3;
const elapsed = process.hrtime(start)[1] / 1000000;
console.log(note + elapsed.toFixed(precision) + " ms");
start = process.hrtime(); // reset the timer
//Tick data logs
TICK RECEIVED IN: 545.586 ms
TICK RECEIVED IN: 600.785 ms
TICK RECEIVED IN: 614.124 ms
TICK RECEIVED IN: 712.715 ms
TICK RECEIVED IN: 510.640 ms
TICK RECEIVED IN: 582.587 ms
TICK RECEIVED IN: 552.164 ms

What were our options:
1. Multithreaded programming language like golang, python.
2. Some way to make NodeJs more performant

1. Adding one more programming language in tech stack was not a viable option for us. Also, these programming languages had their own learning language which means developers had to spent more time in learning new language rather than solving important problems, implementing crucial features and contributing to the product.
So, we rejected this option.

2. We’d to figure some way to execute all algorithms parallely without blocking NodeJs event loop. So, we decided to solve this problem leveraging NodeJs’s async await feature. We wrapped the onTicks function with async op, this async keyword tells NodeJs to execute this operation or algorithm asynchronously without waiting or blocking next operation.

ticker.on("connect", subscribe);
async (tick) => ( await onTicks(tick))
async function onTicks(tick) {
// logic

In this onTicks function, we could split multiple operations like persisting ticks in db, executing algorithms, etc.

ticker.on("connect", subscribe);
async (tick) => ( await onTicks(tick))
async function onTicks(ticks) {
const ps = [saveTick(ticks), splitAndProcess(ticks)];
await Promise.all(ps);
return 'success';
async function saveTick(tick) {
//send to sqs or REST API call
async function thresholdTrackingAlgo(tick) {
// algo logic
async function splitAndProcess(ticks) {
const executions = ticks.map(
tick => thresholdTrackingAlgo(tick)

const results = await Promise.all(executions);
return results;

Problem 2: Latency in network requests. We didn’t want to waste our precious time in network requests (for fetching tracked instruments current price, last traded price in previous tick, traded volume, volume traded in last 5 mins, etc.)

1. Blazing fast cache service like redis
2. In-memory caching

1. Redis comes with it’s own learning curve, which being a new technology for us could’ve taken more time for implementing the essential feature. New technology ( or service, tool, etc.) means more infrastructure burden, configuration, and management. Also, syncing tracking list & data between db and Redis.
Communicating with redis via network request would’ve introduced more delay, even though in multiple of milliseconds was a waste of available execution time.
So, we rejected this option for our use case.

2. Major advantage of in-memory caching was it brought down delay in the range of nanoseconds. It boosted I/O operations tremendously. There are already in-memory caching solution available on npm. We choose “node-cache” for it’s simple API’s.

Check this out : https://gist.github.com/jboner/2841832


We decided to use NodeJs async/await feature along with in-memory caching which executes multiple and parallel processes like persisting ticks, executing strategy on ticks, stop loss monitoring, etc.

On the next article i.e Part 2, I will be adding a bit more to this by providing some results and analytics to show the execution time we saved before next tick arrives and some logging results.This part will also include more advanced use of async/await and running NodeJs in cluster mode across multiple CPU cores.
Note: If you need any clarification catch me as @pawan on prodio slack channel.


  1. https://medium.com/@tkssharma/writing-neat-asynchronous-node-js-code-with-promises-async-await-fa8d8b0bcd7c
  2. https://blog.risingstack.com/mastering-async-await-in-nodejs/
  3. https://nodejs.org/en/docs/guides/blocking-vs-non-blocking/
  4. https://medium.freecodecamp.org/what-exactly-is-node-js-ae36e97449f5
  5. https://www.andlil.com/en/tick-sizes-in-financial-markets-and-their-effect-on-trading/
  6. https://medium.com/@globalprimeforex/why-is-tick-volume-important-to-monitor-56a936eea70d

How Prodio leveraged NodeJs async/await to modify Zerodha APIs — Part 1 was originally published in Prodio DesignWorks on Medium, where people are continuing the conversation by highlighting and responding to this story.

Story published on September 17, 2020

more in Engineering

Zoom Meeting Integration in web application — Part 1

Zoom Meeting Integration in web application — Part 1Case study how we integrated Zoom Meetings via REST APIs for one our client’s products.A Little BackgroundThis product

Pawan Wagh

Embedding OpenSource Product into Our React HRM Product

We have an HR Management Product NeoHRM and wanted to build an interesting feature that captures the culture of the firm and helps build a community around knowledge management

Vatsal Shah

JavaScript SEO strategy for client-side rendered web apps — Part I

Case study how we strategized & implemented Javascript SEO strategy for a react/redux content heavy website to implement new biz

Pawan Wagh