If your company has been running VTiger for a few years, there’s a good chance you’re on 7.x, your PHP version is holding you hostage, and every conversation about upgrading ends with “it’s working, don’t touch it.”
We recently migrated a heavily customized VTiger 7.4 instance to 8.x for a client whose CRM had been upgraded two or three times before — badly. The first migration attempt failed within minutes, and the reason is the same reason most VTiger upgrades fail: the codebase you’re upgrading isn’t the codebase VTiger thinks it is.
This is the process that worked. If you’re planning a VTiger migration, it’ll save you the white screens.
Step 1: Audit Before You Touch Anything
Every successful migration starts in read-only mode. Before any upgrade script runs, document:
- Exact versions: VTiger, PHP, MySQL/MariaDB, OS, web server. “PHP 7.4” vs “PHP 8.0” decides which upgrade path is even possible.
- PHP configuration:
memory_limit,upload_max_filesize,max_execution_time. Upgrade scripts die silently on low limits. - Active and custom modules, plus every installed extension and its license status. Extensions are the first casualty of a major version jump.
- Cron jobs and their frequency — you’ll be disabling these later, and you need to know what to re-enable.
- Database size and record volume per module. A 2 GB database and a 60 GB database are different migration projects.
- Custom files. This is the big one — see below.
The deliverable is a written audit report, not a mental note. When the migration hits a wall at step six, the audit is how you know whether the wall was always there.
Step 2: The Core-File Drift Problem
Here’s what actually killed the first migration attempt, and what we now check on every VTiger project:
VTiger instances that have been customized — or migrated before by less careful hands — accumulate drift: core files that no longer match the official release. A function in vtlib/Vtiger/Deprecated.php gets patched to work around missing data. A record model gets a custom tweak. Someone “fixed” something in CRMEntity.php in 2021 and never wrote it down.
Then you run the official 7.4 → 7.5 migration patch, and it fails — because the patch assumes stock files, applies changes relative to them, and your files aren’t stock.
The fix is tedious but mechanical:
- Download a clean copy of your exact VTiger version (e.g., official 7.4).
- Diff it against the production codebase, file by file.
- For every difference, decide: legitimate customization (document it, reapply later) or accidental damage (restore the stock file).
- Reduce drift until the migration patch can run cleanly.
Yes, this takes days on a heavily modified instance. It’s also the difference between a migration and a rescue operation. A white screen after an upgrade is almost always a drifted core file — we watched CRMEntity.php, Tracker.php, and Logging.php from the stock package take down an entire instance until the customizations were reconciled.
Step 3: Never Migrate Production
This shouldn’t need saying in 2026, but: do not run migration scripts against your live CRM.
Copy the database and codebase to a staging environment — a separate server, a VPS, or at minimum an isolated subdomain with its own vhost. Then, on staging:
- Disable outbound email. A staging CRM that sends real customers “your invoice is overdue” emails is a story you tell once.
- Disable the cron. VTiger’s cron will happily trigger workflows and emails against your test data. Comment it out of
crontabentirely; re-enable deliberately at the end. - Anonymize sensitive data if anyone outside the core team will touch the staging environment.
Work through the migration on staging until it’s boring. Only then does production enter the picture.
Step 4: Upgrade Version by Version
There is no supported jump from 7.4 straight to 8.x. You move through the official or community migration patches one version at a time — 7.4 → 7.5 → 8.0 — and each step has constraints that will bite you:
- PHP version windows. The 7.5 → 8.0 patch expects PHP 7.4. Running VTiger 7.5 on PHP 8.0 is a different (also valid) path, but mixing them up mid-migration produces errors that look like database corruption and aren’t.
- Backup before every step. Database dump plus a full file copy, before each patch. Not one backup at the start — one per increment, so a failure at step three doesn’t send you back to step one.
- Test extensions after each step. We hit a reporting extension that refused to upgrade and blocked the whole process — until we noticed it wasn’t even enabled on the client’s production instance. We’d been fighting a module nobody used. Check what’s actually active before you debug what’s broken.
Log every change, every fix, every workaround as you go. The migration log is the deliverable your future self (or your client’s next developer) will thank you for.
Step 5: The Database Traps (MariaDB → MySQL)
If your migration involves moving a database between servers, you’ll likely hit the MariaDB-to-MySQL wall. MariaDB dumps use collations MySQL 8 doesn’t recognize, and the import fails with:
#1273 - Unknown collation: 'utf8mb4_uca1400_ai_ci'
The fix is a find-and-replace pass on the SQL dump:
utf8mb4_uca1400_ai_ci→utf8mb4_0900_ai_ciutf8mb3_uca1400_ai_ci→utf8mb4_0900_ai_ciCHARSET=utf8mb3→CHARSET=utf8mb4
Two more traps from the same import: ROW_FORMAT=COMPACT on older tables can blow past index size limits — replace with ROW_FORMAT=DYNAMIC. And if you get a key-length error on a unique index (we hit it on a file-manager table), prefix the indexed column: `name`(191) instead of the full column.
None of this is documented in VTiger’s migration notes. It’s the kind of thing you learn by watching an import fail at 95%.
Step 6: Validate Like a Checklist, Not a Vibe
“Migrated successfully” means a signed-off checklist, not “the login page loads.” Ours covers:
- Core flows: login/logout, record CRUD in every active module, PDF export, global search, SMTP test email.
- Workflows: every trigger, every time-based workflow, every automated email — tested against staging data.
- Cron: re-enabled deliberately, one entry at a time, with
grep CRON /var/log/syslogconfirming each run. If a cron task gets stuck, check the cron table in the database and reset its status rather than letting the queue rot. - Permissions: files at 644, directories at 755, owned by the web server user. Half of all “VTiger is broken after migration” reports are permission problems in disguise.
- Security: HTTPS forced, roles and password policies intact, audit trail working.
- Automated regression tests: for anything business-critical, we wire up a Playwright suite so the next upgrade is verified by machines instead of a long afternoon of clicking.
Step 7: Go-Live Is a Rollback Plan With a Deadline
The final sync from staging to production is scheduled, announced, and reversible:
- Production goes into maintenance mode at an agreed low-traffic time.
- Final delta of data (anything created since the staging copy) is migrated.
- DNS/vhost flips, smoke tests run, cron re-enables.
- The old environment stays untouched for a defined window. Not deleted, not repurposed — available. A rollback you can execute in fifteen minutes is what turns go-live from a gamble into a procedure.
The Honest Summary
VTiger migrations fail for boring reasons: drifted core files, the wrong PHP version for the patch, a database import that dies on collations, an extension nobody remembered installing. None of these are hard problems. They’re unknown problems — until an audit makes them known.
Budget your effort accordingly: roughly 30% audit and drift cleanup, 20% the actual version increments, 50% validation, testing, and go-live discipline. Teams that invert those numbers get the white screen.
If your VTiger instance is two major versions behind and held together by workarounds, this is exactly the kind of project we run through our CRM consulting & migration practice — audit, staged migration, regression testing, and a documented handover. It’s backed by the same discipline we bring to DevOps & infrastructure and automation projects. Book a call and we’ll tell you honestly what your migration will take — including whether you need one at all.