Published on 06/11/2026•Updated on 06/11/2026•6 min read•Ritik Mohapatra

The Road to v1.2: Lessons from Beta to Launch

ArchitectureProduct Launch
The Road to v1.2: Lessons from Beta to Launch

From serverless connection bottlenecks and offline relational sync to mobile race conditions and cryptographic DNS security, the real engineering complexity behind building and shipping XpenseMate v1.2.

Building a personal finance app in public is a humbling experience.

When you build a static website or a content blog, an edge case bug causes a minor visual glitch. But when you build an offline first multiple bank finance tracker, architectural decisions carry immense weight. If an expense entry disappears into a void, if moving money between accounts skews your tax ledger, or if an interface locks up on mobile, user trust evaporates immediately.

Before releasing XpenseMate v1.2, we spent three months running a closed private beta behind invite tokens and capacity caps.

Here is an honest breakdown of the architectural bottlenecks, state synchronization puzzles, and hard earned engineering lessons that transformed an experimental PWA into a dependable daily driver.


1. Orchestrating Concurrent UI State and Mobile Interrupts

One of our first private beta test reports was as baffling as it was embarrassing:

"I signed up on my phone, and the screen turned dark gray and froze. I could not click anywhere."

When we inspected client state, three independent background listeners had fired simultaneously upon first login:

  1. The Bank Setup Modal: Prompting the user to set up their primary bank account.
  2. The Onboarding Walkthrough: Highlighting navigation drawers and spending analytics.
  3. The Release Notification Banner: Announcing newly shipped improvements.

Each modal rendered its own fixed backdrop with different stacking order layers. The backdrop of one covered the interactive buttons of the other, locking mobile screens in an inescapable backdrop war.

The Fix

We eliminated competing root level listeners and built a sequential state coordinator:

  • New users complete bank onboarding first.
  • The onboarding walkthrough only engages once an active account is committed to local state.
  • System announcement popups wait until after onboarding completes or is dismissed.

On mobile screens, never let multiple independent components decide when to interrupt a user.


2. Offline Sync Needs Relational Temporary ID Rewriting

Building an offline capable PWA is straightforward if records are completely isolated. But financial records are inherently relational:

  • An expense belongs to an account.
  • An account belongs to a user and maintains a real time running balance.
  • A transfer binds a source account to a destination account.
  • A loan repayment attaches to a specific loan record.

If a user goes offline in an underground parking garage and creates a new savings account, then logs two metro ticket expenses under it, those expenses must point to an account ID that does not exist on the server database yet.

The Solution

We built an IndexedDB queue engine that assigns client side temporary cryptographic UUIDs:

  • Optimistic Local Graph: The interface renders immediately against local IndexedDB state using temporary IDs, updating balances with zero latency.
  • Dependency Ordered Sync: When connectivity returns, the background sync worker creates the parent account first on the server, receives the permanent record identifier, and rewrites foreign key references across all pending child transactions in the local queue before firing their API requests.
  • Atomic Balance Reconciliation: Transactions are replayed sequentially as atomic increments at the database layer, ensuring offline logs do not overwrite balance updates made concurrently on other devices.

3. The Reality of Cash

When XpenseMate was originally conceived, we focused heavily on modern digital payment rails like UPI apps and multiple bank ledgers.

Within the first two weeks of private testing, testers pointed out the exact same blind spot:

"I withdrew ₹5,000 from the ATM, bought groceries at the local market, and paid a cab in cash. How am I supposed to log this?"

Even with UPI everywhere, physical cash remains an everyday reality. Treating cash as an afterthought led to messy accounting:

  • If withdrawing money from an ATM was logged as an expense, spending metrics were counted twice, first at the ATM and again when spending the physical currency.
  • If cash was not tracked at all, wallet balances constantly drifted out of sync.

The Solution

We added Physical Cash as a first class account type. Withdrawing money from an ATM is now recorded as an Internal Transfer

  • Checking account balance decreases by ₹5,000.
  • Cash wallet balance increases by ₹5,000.
  • Net worth change is ₹0, preventing artificial inflation in monthly expense analytics.

When cash is subsequently spent on street food or groceries, it logs directly from the Cash account with proper category attribution.


4. Scaling Serverless Databases with Connection Pooling and Atomic Writes

In serverless environments, every incoming API route can spin up an ephemeral execution container. If dozens of users access the application simultaneously, the platform spins up concurrent containers. If each container opened its own fresh database connection, connection pool limits would exhaust rapidly, causing dropped requests and timeouts.

Architectural Safeguards We Implemented

  • Global Connection Singleton: We engineered a persistent connection caching singleton that reuses warm connections across function invocations, avoiding repetitive TLS handshakes on every request.
  • Lean Serialization for High Throughput Reads: By bypassing heavy document hydration on read only queries, we stripped away unnecessary object wrappers and reduced serverless function memory footprints by nearly 60%.
  • Atomic Balance Operations: We never read a balance into memory, compute the difference in application code, and write it back. That invites race conditions when multiple requests fire concurrently. Instead, all ledger mutations execute strictly as atomic arithmetic operations directly inside the database engine.

5. Two Tier Caching with Service Workers and Distributed Edge Shields

Caching personal financial data requires extreme care. Caching too aggressively shows outdated balances, while caching too little causes sluggish page loads and spikes infrastructure bills.

We designed a two tier caching and security architecture:

  • Tier 1 (Client Cache via Service Worker and IndexedDB): Precaches application shell assets, static typography, and local UI bundles for instant startup, alongside encrypted local storage for offline transaction queues.
  • Tier 2 (Distributed Edge Security Layer): Sliding window rate limiting on sensitive authentication endpoints throttles brute force attempts in under 10ms before requests ever hit our primary database.

This defense in depth keeps the client experience fluid while protecting primary database clusters from traffic spikes.


6. From Default Subdomain to Custom .in Domain and Cryptographic DNS

During early development, we hosted the application on a platform provided preview subdomain. It worked for internal testing, but for a personal finance application, brand trust is paramount.

Why We Committed to xpensemate.in

We made the deliberate investment to acquire and wire up our custom domain xpensemate.in

The .in domain establishes a verified, permanent home built natively around Indian banking and UPI workflows.

Cryptographic DNS Security

A custom domain is also the cryptographic backbone for all outbound communication:

  • Dedicated Mail Routing: We separated automated transactional notices (noreply@xpensemate.in) from user correspondence (support@xpensemate.in).
  • Cryptographic DNS Verification: Full SPF, DKIM (2048 bit key signing), and DMARC policies guarantee onboarding emails land in primary inboxes rather than spam folders.

7. Replacing Raw SMTP with Fast REST Email Pipelines

One of our biggest backend hurdles was transactional email delivery.

Initially, we hooked up standard SMTP socket connections. On localhost it worked fine, but inside serverless containers in production, SMTP showed severe bottlenecks:

  • Socket Overhead: Opening a fresh TCP and TLS socket connection on every serverless invocation wasted 2 to 3 seconds before transmission began.
  • Delivery Latency: SMTP end to end wait times reached 3 to 5 seconds, causing mobile users to tap "Resend OTP" multiple times.
  • Reliability Bottlenecks: Sockets dropped intermittently during traffic bursts, with zero delivery event webhooks to diagnose delivery failures.

The Shift to a Dedicated REST API

Transitioning email dispatch to a specialized HTTPS REST API dropped OTP dispatch latency by nearly 85% to under 400ms. Reusable HTTPS keep alive connections eliminated TCP negotiation overhead, ensuring verification codes arrive instantly.


8. Earning User Trust with an Interactive Client Side Demo Sandbox

In our earliest beta build, exploring XpenseMate required registering with an email upfront. But personal finance is sensitive. Visitors rightfully hesitated to hand over an email before understanding whether the workflow fit their routine.

To bridge that trust gap, we built Interactive Demo Mode:

  • Clicking "Try Demo" loads an isolated sandbox pre populated with realistic bank accounts, recurring subscriptions, loan ledgers, and spending charts.
  • The entire demo executes in client session memory without touching the production database.
  • Visitors can test logging an expense, simulating an internal transfer, or exporting a PDF report risk free.

Introducing zero signup demo mode noticeably improved onboarding confidence and reduced landing page bounce rates.


9. Mobile PWA Polish Over Web Clutter

Because XpenseMate is a Progressive Web App rather than a native mobile application, delivering a smooth 60fps native feel required obsessive discipline:

  • GPU Layer Management: We rebuilt our icon and drawer motion engine with Framer Motion, animating composite only properties and promoting GPU transform layers only during active transitions.
  • Device Specific Install Flows: Instead of a generic "Install PWA" button that confused users, we added platform specific walkthroughs for iOS Safari Share Sheet and Android Chrome WebAPK prompts.
  • Zero Layout Shifts: Modals, activity drawers, and date pickers were refactored for single screen ergonomics on mobile screens, preventing virtual keyboards from pushing input fields off screen.

10. Separating Peer Loans and Shared Costs from Regular Expenses

During private beta testing, one common user dilemma surfaced almost immediately:

"I paid rent for my flatmates and lent money to a colleague. When they paid me back, my monthly spending metrics were completely distorted."

In traditional expense apps, lending money is recorded as an expense, and receiving repayment is recorded as income. This distorts both sides of your ledger:

  • Monthly spending charts spike artificially during the month you covered a shared expense.
  • Repayments show up as false income, skewing cashflow and tax estimates.

The Solution

We added dedicated Loans and Advances tracking with partial repayment schedules:

  • Lending money creates a receivable asset rather than an expense entry.
  • Repayments decrement outstanding balances without artificially inflating monthly income.
  • When debts are settled, records archive cleanly without skewing annual budget analytics.

What Next for XpenseMate: The Path to Sustainable Growth

Releasing v1.2 and opening public access is only the first milestone.

Running serverless infrastructure, production database clusters, edge security layers, and transactional email pipelines incurs real operational costs. Many personal finance apps monetize by charging expensive monthly subscriptions or selling user transaction logs to credit card affiliates.

We built XpenseMate because we wanted a private, accessible tool without paywalls on basic bookkeeping. Our commitment is simple:

The core personal finance workspace, including tracking multiple accounts, offline logging, cash management, debt tracking, and data exports, will remain 100% free and private.

As our community scales, we will explore unobtrusive, privacy respecting sustainability models, such as clean, non intrusive display sponsorships that never track users or touch financial records.

Until then, our focus is listening closely, squashing bugs, and building the cleanest personal finance experience on the web.


Try the Demo

XpenseMate

Experience XpenseMate with sample data

Explore multiple bank accounts, loan schedules, and analytics with zero setup or signup.

Try Interactive Demo

If you have feedback, architectural thoughts, or feature requests, reach out on X (@XpenseMate), where we ship updates regularly.

Continue Reading