Price Feed Queue: Providers, Routing, and Rate Limits

Part of the Sanchayam series. Why a Queue A price fetch is an external API call. It can be slow, it can fail, it needs rate limiting, and it should not block a user request. The right place for it is a background worker draining a persistent queue, not an inline synchronous call. When the frontend requests holdings data and a price is missing or stale, the backend responds immediately with what it has and enqueues the asset for a fetch. The next time the user loads the page, the price is ready. There is no blocking wait. ...

April 26, 2026 · 6 min · 1078 words · Sagar Nayak

FX: USD Pivot, Two-Layer Cache, Stale-While-Revalidate

Part of the Sanchayam series. Why FX Matters Sanchayam tracks assets in their native currency. An Indian equity is priced in INR. A US stock is priced in USD. Crypto may be in USD or USDT. A bank account might be in AED. The portfolio view needs to aggregate everything into one base currency (the user’s choice - INR by default). Every portfolio snapshot, every holdings page, every P&L calculation requires converting across currencies. FX rates are fetched from the same Twelve Data API used for price feeds. A naive approach - one API call per currency per request - would be both slow and expensive. ...

April 20, 2026 · 4 min · 771 words · Sagar Nayak

The Asset Schema: One Table for Every Asset Type

Part of the Sanchayam series. The Problem with Per-Type Tables The obvious design for a multi-asset tracker is a table per asset type: one for stocks, one for mutual funds, one for real estate. That approach breaks down when you need cross-asset aggregation. Computing total portfolio value means querying five different tables and unioning them. Adding a new asset type means new tables, new routes, new UI components. Sanchayam uses a single assets catalog and a single holdings table. Behavior differences between asset types are encoded in schema flags, not in separate tables. ...

April 8, 2026 · 4 min · 841 words · Sagar Nayak

The Two-Layer Cache Architecture

Part of the MediaBridge series. Why Cache S3 at All S3 ListObjectsV2 is not free. Each call costs money, takes time, and returns at most 1,000 objects per page. A bucket with 10,000 files in a single prefix requires 10 paginated S3 calls just to render one folder. Do that on every page load and you burn money, slow the UI, and hit S3 rate limits under concurrent users. Presigned URL generation is also not free. It is CPU work on the server. A folder with 50 files requires 50 presigned PUT or GET URL generations per load if nothing is cached. ...

February 25, 2026 · 6 min · 1065 words · Sagar Nayak

DNS Health Monitoring Without Hammering the API

Part of the PurelyManage series. The Naive Approach Breaks at Scale The first version of the Domains page rechecked every domain on every page load. The logic was simple: call updateDomainSettings with recheckDns: true for each domain, then call listDomains to get the fresh DNS status. That is N+2 API calls per request where N is the number of domains. With the dashboard set to auto-refresh every 60 seconds: 50 domains × 52 API calls × 60 requests/hour = ~3,000 API calls/hour This is both wasteful and fragile. Most domains are healthy most of the time. Rechecking 50 domains every minute to confirm they are still green is unnecessary. And if PurelyMail ever introduces rate limits, this approach is the first to break. ...

January 2, 2026 · 5 min · 950 words · Sagar Nayak