Rajnish.
Let's talk ↗
← All Work
migrationpythonfintechbackendsystems-design

Upgrading a Live Fintech Engine

Taxspanner (via Prismberry) · 2022–2023

Upgrading a live tax filing platform from end-of-life Python 2.7 to modern Python without dropping user filings.

Context

Taxspanner handles online income tax filings for hundreds of thousands of Indian taxpayers. The core backend was still running on Python 2.7 and Django 1.6, both long unsupported. The company needed to modernize to stay secure and ship new capabilities, but could not risk filing errors during tax season.


The Problem

Running on unsupported dependencies meant unpatched security risks, zero compatibility with modern cloud tooling, and high friction whenever developers tried to build new features. Because tax calculations are strictly regulated, any calculation discrepancy would cause severe real-world consequences.

Constraints
  • The service had to remain active for taxpayers throughout the year.
  • Test coverage was sparse on several legacy calculation paths.
  • Government tax department APIs and banking gateway integrations could not break.
  • Product teams needed to keep shipping quarterly updates during the migration.

My Role

I planned the migration roadmap, built compatibility bridges, wrote the core modernization code, and coordinated testing to ensure zero calculation regressions.

The Thinking

A complete rewrite from scratch was far too risky with live financial calculations. We used the strangler fig approach: keep the legacy system running, build new services alongside it, and shift traffic gradually after verifying calculation parity.

The Decision

We began with self-contained utility modules to establish our deployment pipeline. For new capabilities, we introduced FastAPI services to gain async performance and automatic typing. Core tax filing calculations were migrated last, running old and new engines in parallel until outputs matched 100%.


Implementation
  • 01Built a compatibility bridge supporting both Python 2 and Python 3 syntax to migrate modules step by step.
  • 02Wrote thorough test suites for critical tax calculation paths before altering the underlying code.
  • 03Used FastAPI for new backend services to get clean async request handling and OpenAPI documentation.
  • 04Ran shadow traffic on production data, comparing the new service outputs against the legacy engine to catch edge cases.
  • 05Maintained a shared migration dashboard so everyone on product and engineering could see real progress.
Trade-offs
  • Running legacy and new services side-by-side temporarily increased hosting costs during the transition period.
  • Maintaining both Django and FastAPI meant developers had to navigate two code styles for several months.
  • We deliberately left stable, low-touch legacy helper scripts untouched to avoid introducing unnecessary risk.

Outcome

Successfully moved the platform to Python 3.10 and Django 4 without user disruption. The modernized stack supported new features that contributed to a 40% increase in user acquisition.

What I Learned

Large migrations succeed because of discipline and communication. Building thorough automated test suites before changing production code was the single best decision we made, catching multiple subtle edge cases before they reached users.

← Previous

From 3.5s to 500ms API Latency

Next →

Optimizing High-Volume E-Commerce APIs