Case study 04 · Marketplace and revenue
Moving a US marketplace from PHP to Node with no downtime
We took over a marketplace that kept crashing on shared hosting and rebuilt it on AWS in four phases over four years, with me as Technical Lead.
zero downtime
Four phases in four years, zero downtime: no outage was recorded in the logs or reported
60 → 90+
Lighthouse performance 60 → 90+ and SEO 30 → 90+ after the public site moved to Next.js
90% faster
Twenty slowest queries
The story in 5 steps
Stack
- Node.js
- React
- Next.js
- Expo
- MySQL
- OpenSearch
- InfluxDB
- Redis
- AWS
01 · Context
The product is a US marketplace that connects truck drivers and fleets with repair, towing and tire services.
The product is a US marketplace that connects truck drivers and fleets with repair, towing and tire services. When we took it over, it ran on PHP on shared hosting that did not scale, it went down regularly, and SQL injection was reaching production.
The work ran in four phases: two months of stabilization, two years of rebuilding, a shared design system, and then AI built into how the team works. The product never went down in any of them.
The part of this work I am proudest of is the analytics, even more than the migration. The platform took over two million writes a day, advertisers read them live in their dashboard, and annual reports came back in under a second even for the largest accounts.
02 · Could not change
The marketplace was live and was the client's only source of revenue.
The marketplace was live and was the client's only source of revenue. Advertisers pay to be visible, so they pay for every hour of downtime and get nothing for it. We could not take anything offline, and we could not rewrite the system in place.
The mobile apps shaped the whole rebuild, because we controlled the web but not the phones. A web user gets the new version on their next page load. A mobile user updates whenever they feel like it, and shutting down the old backend breaks an app that is already installed on someone's phone.
03 · What we did
Phase 1: stabilize (2 months). We moved the existing PHP application onto AWS without rewriting it.
Phase 1: stabilize (2 months). We moved the existing PHP application onto AWS without rewriting it. We added a firewall, closed the inherited security holes, moved images to object storage and mail into a queue, and indexed the twenty slowest queries, which made them 90% faster.
Rewriting straight away was tempting, but we stabilized what was earning money first and spent the next two years on the rewrite.
Phase 2: rebuild (2 years). The backend moved from PHP to Node and later to a typed framework, the dashboards to React, the public site to Next.js, the mobile apps to Expo, and the hosting to containers with autoscaling. We deliberately kept MySQL as the one fixed point, the only thing that was not allowed to move. When language, framework, hosting and mobile stack all change at once, you need one thing that stays the same to prove the new version behaves like the old one.
Data moved through a script that remapped the schema, and triggers kept the old and new databases synchronized in both directions for over a year. An ad created in the new system appeared in the old one, and the other way round. We shut the old system down only when analytics showed that its last user had left. Rollback was a change of origin at the CDN: seconds, no deploy.
After the public site moved to Next.js, Lighthouse performance went from 60 to over 90, and SEO from 30 to over 90. The platform lives on organic search, so those scores feed straight into revenue. Amazon measured in 2006 that every 100 ms of added load time cost it 1% of sales, and Walmart found that every second of improvement raised conversion by 2%.
Phase 3: design system. We built over 200 components in a monorepo, shared between the dashboards and the mobile app. Only side effects differ per platform, so web and mobile cannot drift apart.
Phase 4: AI in the process (2026). We wrote the engineering standards as executable rules, checked before every commit and again in CI. Each codebase got its own rule set, because a single set for a backend and a component library would be too loose for one or too strict for the other. Claude Code was in daily use for components, tests and integrations, and design was connected to Figma.
Analytics, across all four phases. This part of the system had to absorb over two million writes a day, keep each advertiser's dashboard live and produce a full year's report in under a second, even for accounts with more than 900 listings. One database rarely manages all three, because a database built for fast writes tends to be slow at complex queries, and a year of raw data at this volume runs to hundreds of millions of rows.
We split the work between two databases. Writes went into a time-series database whose index we kept small on purpose. Once a day, each listing's events were summarized into a row in MySQL, and the dashboard and the invoices read those rows. Raw events stayed for seven days before going to the archive. The annual report never read them at all: it added up 365 daily rows per listing.
04 · Result
Four phases in four years, zero downtime: no outage was recorded in the logs or reported
- Four phases in four years, zero downtime: no outage was recorded in the logs or reported
- Lighthouse performance 60 → 90+ and SEO 30 → 90+ after the public site moved to Next.js
- Twenty slowest queries 90% faster
- Analytics at 2M+ writes/day with live reads, and an annual report under one second at 900+ listings
- Team throughput up roughly 50% after AI was built into the process, estimated from ticket cycle
- 19 repositories, 506 API routes, 100 data models and 194 migrations, five user types on a single codebase, and four databases, each chosen for its purpose
05 · Differently
We let the system spread across nineteen repositories with no shared package.
We let the system spread across nineteen repositories with no shared package. The same queue helper ended up copied into seven of them, so changing a message format means changing it in seven places. A shared internal package should have come before the fifth service rather than after the fifteenth.
Related services
The services that draw on this work.
- Web developmentFull-stack web developmentA live marketplace moved from PHP to Node.js with no outage. Lighthouse rose from 60 to above 90 once its public site moved to Next.js.
- How we can workA developer in your teamFour years on one client’s US marketplace, through four phases of work, none of which caused an outage.
- AIApp audit and rescueA US marketplace that went down regularly, running PHP on hosting that couldn’t scale, with SQL injection in production. In the two months we spent stabilizing it, before any code was rewritten, we made its twenty slowest queries 90% faster and closed the security holes. The rebuild took the two years after that.
- How we can workApp takeover and launchWe inherited a live US marketplace that kept crashing on its hosting. Two months went into stabilizing it, and in four years it never had an outage.
- Cloud and DevOpsZero-downtime migrationA US marketplace moved from PHP to Node.js with zero outages. Its two databases were synced in both directions for more than a year, and going back was a change of origin at the CDN that took seconds.
- Web developmentMarketplace and logistics platformsThrough four years and four phases of work, the same marketplace never went offline.
- Web developmentSEO and programmatic pagesA US marketplace that depends on organic search moved its public site to Next.js with no downtime, and its SEO score rose from 30 to above 90.
- Web developmentWeb performanceA US marketplace on shared hosting that could not scale. In the first two months, without rewriting its PHP, we made its twenty slowest queries 90% faster. Lighthouse performance went from 60 to above 90, and SEO from 30 to above 90, after its public site moved to Next.js.
- MobileWeb to mobile portOn a US marketplace, the dashboards and the mobile app draw on more than 200 shared components in one monorepo. Only side effects differ between the platforms.
- Backend, data and integrationsAPI and backend developmentA backend with 100 data models and 194 migrations, moved from PHP to Node.js and later to a typed framework while the product stayed live, with zero outages.
- Backend, data and integrationsSQL and data warehouse optimizationWhen we took over a marketplace whose hosting couldn’t keep up, we indexed its twenty slowest queries in the first two months and made them 90% faster.
- Backend, data and integrationsEmail infrastructureWe moved a live marketplace’s mail onto a queue in the first two months of stabilizing it, before any code was rewritten.
- Regulated and sensitive systemsSecurity reviewA marketplace that had SQL injection reaching production when we took it over. In the first two months, before anything was rewritten, we added a firewall and closed the inherited security holes.
- Cloud and DevOpsAWS architectureA US marketplace moved from shared hosting onto AWS in two months, and later onto containers with autoscaling, without a single outage.
- Cloud and DevOpsDocker, self-hosting and backupsA US marketplace began on shared hosting and ended up on containers with autoscaling, and the product stayed up throughout.
- Design systemsDesign system and component libraryMore than 200 components in a monorepo for a US truck-services marketplace, built while the product stayed live and used by both its dashboards and its mobile app.
- How we can workTechnical leadershipTechnical Lead on a US marketplace for four years, leading a team of twelve and owning the architecture, roadmap, hiring and client relationship. Four phases, zero outages.
Related writing
Posts that came out of this project.
Case study 04
Working on a similar problem? We reply within one business day.
The first call takes 30 minutes, and you’re under no obligation.