# ZohoPOS sync platform

The server side that keeps offline point-of-sale registers consistent with a finance platform, which I worked on for four years.

> Canonical URL: https://sudohulk.com/projects/zohopos-sync-platform
> Status: done
> Tags: java, kafka, redis, mysql, websocket
> Author: Vignesh Kumar A <vignesh@sudohulk.com>
> Licence: CC BY 4.0. Quote freely, cite the canonical URL.

---

## What it was

The server side of a point-of-sale product: sales processing, and the sync layer that pushes items, prices, stock and settings out to Android, iOS and Windows registers that spend part of their day with no network.

## What I worked on

Described at the level I can talk about publicly. Every number here is on my [resume](/resume).

- Replaced per-device polling and M×N direct API calls with one event per change over Kafka, cutting upstream API load by 99% and isolating the platform from outages in the finance system it syncs with. New sync consumers are declared in YAML and onboard in minutes rather than weeks; several teams picked the framework up.
- A transactional outbox: the outgoing event is written inside the same MySQL transaction as the sale, with a background retry behind it, so a crash between "sale committed" and "event published" cannot happen. 99.9% consistency at more than a thousand transactions a minute.
- Split a single-segment JVM and Redis cache into three isolated segments with version-based invalidation: hit rate from 84.3% to 98.1%, about 131 million fewer database queries a week.
- A three-level circuit breaker (global, per-organisation, per-register) with Redis-backed state and a sliding window tuned from p97 latency. It opens within fifteen seconds and queues rather than failing, so downstream slowness degrades gracefully for customers running 200 or more registers.
- Real-time push to over a thousand concurrent WebSocket endpoints over Kafka and Redis, so price and inventory changes reach a register without anyone pressing refresh. Data conflicts fell by 98%.
- Correlation-ID tracing across asynchronous NIO callback threads, which turned three-day root-cause hunts into minutes for organisations processing 80 or more invoices a minute.
- A config-driven access-control framework with bitwise permission storage, adopted across the product's APIs.

## What I learned

That almost every bug I could not explain turned out to be a question about durability, isolation or ordering, and that the answers were a layer below the code I was writing. That is what sent me into database internals. Several of these stories will become posts in the series *Things a POS platform taught me*.
