Skip to main content
Issue 04
/
Backend Architecture8 min read

Migrating a Fintech Backend: From PHP Symfony to Node.js

How we planned and executed a zero-downtime backend migration for a fintech platform, moving from a legacy Symfony monolith to a modular Node.js service layer.

Abdelghani Salama

Backend Architecture

Tookeez is a fintech product where reliability is not optional. When the existing PHP Symfony backend started showing cracks — slow cold starts, monolithic coupling that made hotfixes dangerous, and a deployment pipeline averaging 40 minutes — the decision was made to migrate to Node.js. We had to do it without downtime and without a single transaction loss.

The biggest risk in a migration is not the code — it is the invisible assumptions baked into the data model that nobody documented.

Abdelghani SalamaBackend Architecture

The strategy was strangler fig: run both systems in parallel, route traffic by feature, and gradually strangle the legacy system. We introduced an NGINX layer to split traffic: new transaction endpoints went to Node.js (Express), legacy reporting stayed on Symfony. Both systems wrote to the same PostgreSQL instance via a shared data contract.

The most dangerous part was the authentication layer. The legacy system used Symfony's security bundle with custom JWT claims that had evolved over three years. We built an adapter in the Node.js gateway that validated both token formats, issued a normalized internal token, and logged any format mismatches for analysis. This ran for six weeks before we killed Symfony's auth entirely.

Database migration happened in four phases: read-only queries first (safe, reversible), then write operations with dual-write confirmation, then atomic transactions using PostgreSQL advisory locks to prevent race conditions during the cutover window, and finally read traffic moved fully to Node.js. We never took the database offline.

The post-migration numbers: deployment time dropped from 40 minutes to 6 minutes with GitHub Actions and Docker. Memory footprint per instance fell by 55%. P99 API latency improved from 340ms to 80ms under load. Most importantly, zero transactions were lost and no user-facing incidents occurred during the entire eight-week migration window.

Filed underNode.jsBackendArchitectureMigrationFintech