South Arc Digital
Case Study12 min read

Real-Time Cylinder Rotation Analytics for an Industrial Gas Fleet

We connected TrackAbout and Zoho Books to calculate cylinder rotation analytics for an industrial gas fleet of 3,000+ cylinders in Rajasthan.

Vignesh Ramakrishnan

Guljag Gases and the rotation question

Guljag Gases fills and distributes industrial gas out of Jaipur. Oxygen for hospitals and welding shops, CO2 for restaurants and beverage companies, LPG for kitchens and small factories, plus a mix of specialty gases for industrial buyers across Rajasthan. The fleet sits at roughly 3,000 cylinders at any given moment, valued internally at ₹7,500 per cylinder, which puts about ₹2.25 crore of capital out on the road or sitting in customer yards.

₹2.25 crore

Capital locked across 3,000+ cylinders at any given time

The single most important operational question for a gas distributor is how fast the cylinders come back. A cylinder parked at a customer's site for three weeks is dead capital. A cylinder that goes out, gets emptied, and returns in four days is doing the work that justifies buying it in the first place. Multiplied across the fleet, the gap between good rotation and bad rotation runs into lakhs of rupees of inventory that could either be earning revenue or sitting unused.

Guljag had every data point needed to answer that question. The data lived in two places that had never been connected.

Two systems, no bridge

TrackAbout handled the cylinder side. Every fill at the plant, every delivery to a customer, every return scan at the gate is logged against a specific cylinder ID. Zoho Books handled the commercial side: customer master data, invoices, payment terms, segmentation. Between the two systems sat the entire rotation story. Neither system, on its own, could tell you what the rotation rate was, because rotation requires both halves of the picture.

Cylinder events in TrackAbout, invoices in Zoho Books, rotation rate computed by nobody

A 15-minute sync into MongoDB and a Next.js dashboard with six live views

The rotation formula is not complicated:

Rotation Rate = Total Deliveries ÷ Average Cylinders Held

Over a defined period, usually a calendar month, you take how many filled cylinders went out and divide by how many a customer held on average. A rotation rate of 4x means each cylinder, on average, completed four full out-and-back cycles in that month. Higher is better. The arithmetic is trivial. The work is in getting the inputs lined up against the same customer, the same gas type, and the same time window across two systems that don't share an ID space.

Rotation also varies wildly by gas type, which we knew going in but underestimated until we saw the segmented data. CO2 customers (mostly restaurants, soda fountains, beverage plants) burn through gas slowly because their consumption is metered against drink volume. Oxygen customers (hospitals, welding shops) tear through cylinders. LPG sits in the middle. Comparing a hospital's O2 rotation to a sweet shop's CO2 rotation produces a number that looks like a verdict but is really just a category error. The dashboard segments by gas type for that reason.

The TrackAbout API problem

This is where the project went sideways for a few days.

TrackAbout exposes an API. On paper it does the obvious thing: query cylinder events, get JSON back, paginate through history. In practice the API has authentication and response handling quirks that ordinary HTTP clients don't deal with cleanly. We tried fetch first. Then Axios. Then Got. Each one ran into a different failure: a session token that didn't refresh the way the docs implied, a response shape that varied depending on whether a particular query returned zero results, a Content-Type header that some clients respected and others didn't.

We could make the calls work in Postman. We could not get those same calls to work reliably from the Node.js codebase using any of the standard clients.

After two days of debugging, we stopped fighting it and switched to Newman, the Postman CLI runner. The collection that worked in the Postman GUI got exported. Newman runs that exact collection from Node, programmatically, and writes the responses out as JSON we can pipe into the rest of the pipeline. It is genuinely a hack. It is not how you are supposed to integrate with a third-party API. It works.

If a third-party API works in Postman but breaks in your code, Newman lets you run the Postman collection from Node directly. Not elegant. It ships.

The Zoho Books API, for what it's worth, behaved exactly as documented. The contrast is the whole story of working with vendor APIs in this segment of the market: half are well-built, half are not, and you find out which is which on day one.

The sync runs every 15 minutes. A delta poll pulls new cylinder events from TrackAbout via the Newman collection, fresh invoices and customer updates from Zoho via the official API, merges them on a customer key built from a normalized phone number plus tax ID, and writes the result into MongoDB. The rotation calculations run on the merged collection, not against the source systems directly, because the merged store is where the joins make sense. Fifteen minutes is not real-time. For daily operational decisions on a fleet of 3,000 cylinders, it is close enough.

How customers actually segment

Zoho already had Guljag's customers tagged into broad segments, and those segments mapped reasonably well to how rotation actually behaves.

Hospitals and medical facilities sit at the top of the rotation table. They consume oxygen continuously, run on credit terms, and have a dedicated person whose job is to call for a refill the moment a cylinder hits a defined level. Rotation here regularly clears 4x to 5x in a steady month.

Industrial users (welding shops, small fabricators, factories) sit in the middle. Their consumption is project-dependent. A welding shop with three jobs running through the week burns oxygen fast. The same shop in a slow week sits on the same cylinders for ten days. Rotation here ranges from 2x to 4x depending on the month.

Food and beverage clients rotate slowest. CO2 for a restaurant lasts as long as the restaurant has customers buying soft drinks, which means a single 30 kg cylinder can last weeks at a small outlet and days at a busy one. The fleet average for this segment hovers around 1.5x to 2.5x, with a long tail of customers below 1x in any given month.

Each segment gets its own benchmarks on the dashboard. A 2x rotation in the F&B segment is unremarkable. A 2x rotation for a hospital account would be a signal that something is wrong with the delivery cadence or with the cylinders themselves.

What we put on the screen

6

Live dashboard views, refreshed every 15 minutes

The Next.js dashboard exposes six views to Guljag's operations team. We wrote them in the order the operations head asked for them, which turned out to be a useful prioritization exercise.

  1. Fleet Overview. Total cylinders by gas type, current distribution split into in-plant, in-transit, and at-customer. The locked-capital number sits at the top. It is the number the owner looks at first.
  2. Rotation by Gas Type. The headline metric, segmented across O2, CO2, LPG, and the long tail of specialty gases. This is the view that gets screenshotted into WhatsApp groups.
  3. Customer Rotation Rankings. A leaderboard, descending by rotation rate, filterable by segment and gas type. The bottom of this list is where the deposit conversation starts.
  4. Delivery Trends. Volume patterns over time, with overlays for the same period in the previous year. Seasonal shifts in CO2 (festival season) and O2 (winter respiratory cases) are very visible here.
  5. Capital Analysis. Locked capital by customer segment, by gas type, by individual customer. Calculated at ₹7,500 per cylinder, the internal book value Guljag uses for its own accounting.
  6. Outlier Alerts. Customers significantly below the rolling average rotation rate for their segment and gas type. The alert threshold is set at the 25th percentile within a segment, recalculated weekly.

The Outlier Alerts view is the one that drives action. Everything else describes the world. Outlier Alerts tells the sales team which accounts to call this week.

When you can show that one segment is sitting on 200 cylinders at a 1.5x rotation rate, that's ₹15 lakh of capital earning a fraction of what it should. The conversation about deposit increases gets very concrete very fast.

The benchmark customer

The top performer in the dataset, across the months we have data for, is a sweet shop in central Jaipur called Jantaa Sweet Home. Their CO2 rotation rate hit 6.55x in the best month we measured. That works out to a full delivery-and-return cycle every five to six days. The fleet-wide CO2 average sits around 2.5x to 3x.

Jantaa became the internal benchmark almost by accident. Once the dashboard surfaced their number, the question in operational reviews stopped being "what is good rotation for CO2" and became "why can't all our CO2 customers rotate like Jantaa." Some of the answer is that Jantaa orders consistently and pays on time, which makes them a customer the delivery team prioritizes. Some of it is that they run a high-throughput business that genuinely consumes CO2 fast. Some of it is that they own their own logistics for cylinder pickup, so the return leg doesn't depend on a Guljag truck being in their area.

The exercise of figuring out which of those three factors is replicable across other accounts is the real product of the dashboard. The number is just the prompt.

What the system runs on

The full stack is small. Next.js for the frontend and the API routes that serve the dashboard. MongoDB Atlas for the merged analytics store. Newman for the TrackAbout integration, run as a child process from the Node.js sync worker. The Zoho Books REST API for invoicing and customer data, called directly. A 15-minute cron, deployed on Railway, that orchestrates the sync and writes the recomputed rotation tables.

Total infrastructure cost is in the low thousands of rupees per month. The data volumes are small enough that everything sits comfortably inside starter tiers, and the 15-minute polling cadence keeps API call counts well under the rate limits of both upstream systems.

The MongoDB schema deliberately keeps the merged store denormalized. Each document holds a customer, a gas type, a month, and the precomputed rotation metrics for that combination, plus arrays of the underlying delivery events and invoice references. Querying is fast because the joins are already done. Recomputation is cheap because each 15-minute cycle only touches the documents whose underlying events changed.

What we'd do differently

The Newman dependency is the soft spot. It works, but it is a dependency on a CLI tool that wraps a JSON file that approximates an HTTP client. If TrackAbout updates their API, the Postman collection needs manual updating, and the failure mode is silent (the collection runs, returns nothing, and the sync looks fine until somebody notices the rotation numbers stopped moving). A proper SDK wrapper would be more maintainable. We have not built it because the time investment doesn't justify the marginal reliability gain at current scale.

Newman as an HTTP client is brittle. If the upstream API changes, the Postman collection has to be re-exported by hand, and failures are silent. Wrap it with a heartbeat check that alerts when no new events arrive within a defined window.

The customer-key normalization is the other piece we would redo. We built it as a deterministic hash of normalized phone plus tax ID, which works for the 95% of customers who have both fields populated cleanly. The remaining 5% require manual reconciliation, and that reconciliation lives in a Google Sheet that the operations team maintains. A proper master data layer with a UI would be a real engineering project. The Google Sheet works for now.

What it changed about the business

The rotation dashboard did not invent a new business model for Guljag. It made an existing question answerable. Before the dashboard, the operations head had a feel for which customers were slow and which were fast. After the dashboard, that feel is a number, segmented by gas type, refreshed every 15 minutes, and visible to everybody who needs to see it.

The most concrete result is the deposit conversation. When a CO2 customer is sitting at 1.2x rotation in a segment where the median is 2.5x, the dashboard surfaces it, the sales team calls, and the conversation is no longer "we think you might be holding too many cylinders" but "you have 18 of our cylinders, your average rotation is 1.2x, our median CO2 rotation is 2.5x, we need to either raise your deposit or pull cylinders back." The data does not win the argument by itself. It changes which arguments are possible to have.

The second result, less measurable, is that operational reviews have a shared artifact. Six dashboard views, refreshed every 15 minutes, available on a phone, drive the agenda. The previous version of those reviews was a stack of TrackAbout exports and a Zoho invoice list and somebody trying to reconcile them in Excel during the meeting. That reconciliation is now done by a 15-minute cron, written to MongoDB, and rendered by Next.js. The meetings got shorter. The decisions got faster. The capital sitting in customer yards started to come back.

Built on Next.js, MongoDB Atlas, the Zoho Books API, and a Newman-wrapped Postman collection in place of a TrackAbout SDK. Deployed on Railway. Live at Guljag Gases, Jaipur.


Want to build something like this?

We design and ship AI products, automation systems, and custom software.

Get in touch

Related