An online platform that tracks gold and silver prices in real time with interactive charts, threshold alerts, and historical analytics.
Visit OroTracker ↗By the CapregSoft Engineering Team ·
price-to-screen latency target
price updates ingestible at peak
uptime target under peak load
Figures shown are engineering targets and typical outcomes for work of this type, not audited per-client results. We'll share verified numbers for your specific context on a discovery call.
How CapregSoft approached OroTracker — the short version.
Pricing data arrived faster than the existing setup could process and display it. Users saw stale numbers and missed time-sensitive moves, the one thing a price tracker can't afford.
Alerts fired late or not at all, and dashboards visibly lagged whenever traffic spiked. For a product whose entire value is timeliness, that eroded trust on every session.
Replaced slow polling with a streaming ETL ingestion path so price updates flow in continuously, are normalized on arrival, and reach the browser the moment they land.
Used NSQ and NATS as the messaging backbone so ingestion, storage, alerting, and live delivery are decoupled and scale independently under bursty market activity.
Stored every tick in a time-series database so historical queries and chart zooms return instantly instead of scanning a general-purpose table.
Built a dedicated alerting pipeline that evaluates user thresholds on the live stream and delivers notifications within seconds of a crossing.
Pushed live updates to clients over WebSockets so the dashboard reflects the market without a refresh.
The original system asked the upstream price feed for new data on a fixed interval. That model has a hard ceiling: you're always at least one interval behind the market, and shortening the interval just multiplies load without removing the lag. For a commodity tracker, being a few seconds stale is the difference between a useful alert and a missed trade.
We moved to a streaming model. Instead of repeatedly asking 'is there anything new?', the backend keeps an open connection to the source and processes each update as it arrives. Go's goroutines made this natural, thousands of lightweight concurrent workers handling the fan-out from ingestion to storage to connected clients, without the thread overhead a traditional runtime would impose.
A price feed is bursty, quiet one second, a flood the next when the market moves. If ingestion, storage, alerting, and live delivery are wired together directly, the slowest one becomes everyone's bottleneck. We put a message bus between them so each stage runs at its own pace.
We used NATS for low-latency real-time fan-out, getting fresh prices to the dashboard and the alert evaluator with minimal delay, and NSQ for durable queues where work must not be dropped, like persisting every tick and dispatching notifications. This is the same 'fast signaling vs. guaranteed work' split that keeps the system both instant and reliable when volume spikes.
Raw price feeds arrive in vendor-specific shapes. Our ingestion is a streaming ETL stage: extract from the source, transform each update into a consistent internal schema and unit, and load it onto the bus for storage and live delivery. Because normalization happens at the edge, every downstream consumer (charts, alerts, analytics) works against clean, uniform data.
Price history is append-heavy and almost always queried by time range, exactly the access pattern relational tables handle poorly at scale. We used a time-series store so that 'show me the last 24 hours' or 'zoom to this week' returns in milliseconds rather than scanning millions of rows.
Redis sits in front as a hot cache for the latest price and the most-requested chart windows, so the most common reads never touch disk at all.
Alerting is where most price trackers quietly fail: they batch-check thresholds on a timer, so a price can spike and recover between checks and the user never hears about it. We evaluate thresholds against the live stream as prices move, so a crossing triggers a notification within seconds, the moment that actually matters.
This was a Real-Time Data Processing engagement.
Go's goroutine model lets a single service handle tens of thousands of concurrent connections and stream updates with very low memory overhead. For a system whose core job is fanning live data out to many clients at once, that concurrency model keeps latency low and infrastructure cost down compared to runtimes that lean on heavier threads or event loops under the same load.
By replacing interval polling with a persistent streaming connection to the price source, processing each tick as it arrives, caching the latest values in Redis, and pushing updates to the browser over WebSockets. Each hop is designed to add milliseconds, not seconds.
Yes. A NATS/NSQ message bus decouples the ingestion, processing, and delivery tiers so each scales independently, and the hot path is served from a Redis cache. Spikes in viewers don't slow ingestion, and spikes in market activity don't slow the dashboard.
They solve different problems. NATS gives low-latency real-time fan-out for getting fresh prices to the dashboard and alert evaluator instantly. NSQ provides durable, at-least-once queues for work that must never be lost, like persisting every price tick and dispatching alerts. Using each where it's strongest keeps the system both fast and reliable.