· 7 min read
TopGear India: moving a publishing CMS from CodeIgniter to Laravel while the newsroom kept publishing
The decisions behind one CMS migration: a full rewrite, the content model and URLs kept, the speed found in SQL, caching and images, and an editor-first CMS.
The TopGear India CMS migration moved a busy motoring magazine's website and newsroom tools from CodeIgniter on shared hosting to Laravel on Google Cloud, with Redis caching and an edge CDN in front, while the editors kept publishing every day. Page load time on the home and category pages, before and after: 1–3 min → 3 s. Bounce rate, before and after: 70% → 30%.
I was the lead engineer on it in 2024, as the senior engineer behind the products of the media group that publishes the magazine. My staged migration playbook is the general method for moving a live PHP application; this is the record of one project. I keep it to what I can stand behind: the decisions and results in the case study and the two measured numbers in my claims ledger, both read from the site's Google Analytics. Where I explain why a technique works in general, I say so, and I don't reconstruct details of the project I can't show you.
What was the site, and what was wrong with it?
TopGear India publishes daily stories, galleries and reviews. Its traffic is spiky in a predictable way: every time a car launches, readers arrive at once. And its editors cannot stop publishing for a migration, because a motoring magazine that goes quiet on launch day loses the day.
The legacy system was a CodeIgniter application on shared hosting, and it was slowest exactly when it mattered, during those spikes. Shared hosting also meant infrastructure that could be neither scaled nor properly monitored. The brief came down to three constraints: make it fast under load, keep everything editors and search engines already depended on, and never stop the newsroom.
Why a full rewrite instead of patches?
Patching the old stack had stopped paying off. Each fix bought a little time and left the platform no better placed for the next spike, so we rewrote the application in Laravel. That is more work up front, and it is the first trade-off listed in the case study.
A rewrite is not the same thing as a big-bang launch. Martin Fowler's Strangler Fig Application describes replacing a system gradually so that investment and returns arrive "gradually and visibly"; my playbook covers how to stage a cut-over like that. On TopGear the decision about the code was "rewrite", and the constraint on going live was "publishing never stops". Those are separate questions, and teams that merge them tend either to patch forever or to switch over in one risky night.
What stayed the same?
Two things were deliberately kept: the content model and the URLs.
Keeping the content model meant the new Laravel application stored stories in MySQL in the shape the newsroom already knew. Editors didn't have to relearn what a story, a gallery or a review was, and the content didn't have to be reshaped during the move.
Keeping the URLs protected years of search traffic. Google's site move guidance says 301 and other permanent redirects don't cause a loss in PageRank, and its redirects documentation lists 301 and 308 as the permanent server-side options. A URL that never changes needs no redirect at all, though, and can't be missed from a redirect map. The cost, which the case study records, is that stable URLs limited some structural changes we might otherwise have made. For a publication whose archive is a large part of its value, that was the right side of the trade.
Where did the speed come from?
Not from clever code. The big gains came from architecture and from fixing the slow parts at their source.
| Change | The problem it addressed | Why it works (general practice) |
|---|---|---|
| Queries rewritten, tables indexed | The slow pages came from slow SQL | An index built for how the site actually reads data turns a scan into a lookup; Laravel's eager loading is the standard fix for the "N + 1" pattern of one query per row |
| Redis caching and an edge CDN | Every page view reached the application and the database | Most views are served from the CDN or the cache, so they never touch the database |
| Images sized for the page | Full-size originals were served | An image delivered at the size it is shown is a fraction of the bytes; web.dev's responsive images guide explains srcset and sizes |
| Google Cloud instead of shared hosting | Capacity couldn't be added or watched | Infrastructure that can be scaled and monitored turns "the site is slow" into a graph and a fix |
The measured result on the home and category pages is the one in the opening paragraph: 1–3 min → 3 s. The ledger defines that number as the load time of those pages before and after the rebuild, and attributes it to the whole set of changes above, not to any one of them. I can't give you a breakdown by change, so I won't.
How do you cache a newsroom without serving stale stories?
The second trade-off in the case study is the one every publisher meets: caching aggressively means planning invalidation carefully, so that a published change appears promptly without purging everything.
The general technique I use is to invalidate by what changed, not by time. When an editor publishes or corrects a story, the system knows which pages show it: the story itself, its section, the home page, perhaps a tag page. Those, and only those, are refreshed. Laravel supports this pattern with cache tags, which let you flush every cached item tagged, say, with a section's name; the same documentation notes that tags aren't supported on the file, DynamoDB, database or storage drivers, which is one reason Redis is the usual choice. At the CDN, the equivalent is purging specific paths rather than the whole site. A short time-to-live behind both is a safety net, not the mechanism.
What changed for the editors?
The CMS was rebuilt editor-first, around the newsroom's real publishing workflow, built with Laravel and Vue.js. The result for the editorial team: publishing moved from hours to minutes.
That is also the lesson I'd put first. Editors are users too, and a CMS migration only counts as a success once publishing is easier as well as faster. A fast public site with a slower back office would have been a failed project, whatever the load time said.
What were the results?
All four are in the case study:
- Page load time on the home and category pages: 1–3 min → 3 s.
- Bounce rate: 70% → 30%, and traffic grew.
- Publishing moved from hours to minutes for the editorial team.
- The site now runs on cloud infrastructure that can be scaled and monitored.
What would I tell a team in the same position?
- Decide rewrite or patch on evidence. If each patch leaves you no better placed for the next spike, the platform is the problem, and a clean migration is cheaper than endless fixes.
- Find the slow SQL before buying servers. Hosting matters, but slow queries follow you to any host.
- Keep the URLs and the content model unless you have a reason not to. Both are assets you have already paid for.
- Design invalidation on day one. A cache you are afraid to invalidate is worse than no cache.
- Treat editors as the second user group. Watch them publish, and build for that.
- Stay current after you land. Laravel's support policy gives each release bug fixes for 18 months and security fixes for two years, so the upgrade path belongs in the plan from the start.
How I do this
Legacy modernization starts with a fixed-price assessment of your current system and ends in a written plan for the move, priced stage by stage. If the platform is fine but slow, a performance audit finds where the time goes, from SQL to images, before anything is rewritten. The India market page covers working with me as an Indian team, on the same clock.
Sources
Related service
- Service: Legacy modernization · Product engineering
Move an aging system to a modern stack without stopping the business.
- Service: Performance and Core Web Vitals audit · Performance and reliability
Find out in five working days exactly why your application is slow, and what to fix first.
- Service: Laravel development and upgrades · Product engineering
Laravel applications and APIs built, upgraded and kept current by an engineer whose main stack is Laravel.
Related case study
- Case study: TopGear India CMS · CMS migration and modernization
- page load time, before → after
- 1–3 min → 3 s