Why an EspoCRM 9 to 10 upgrade needs a plan before anyone runs a command
If your team runs EspoCRM 9.x with custom entities, formula logic, extensions and integrations, the question is not whether to move to 10.0 but when and how. The safe answer is to plan the move around a tested copy of your instance, not to run the upgrade on production. EspoCRM 10.0.0 was released on July 2, 2026, after 9.0.0 on January 20, 2025, and the 10.0 line has continued with patch releases, including 10.0.10 on October 14, 2026. Start by inventorying what your instance actually depends on, then pick a target patch release and a date for the staging rehearsal.
The release notes for 10.0.0 list removal of SelectManager support, backend and frontend deprecations, deprecated link access in the ORM Entity::get, jobs defined by serviceName, the deprecated Espo.ui and Espo.utils frontend helpers, and changes to the AuthToken interface. Any custom PHP code, custom frontend script, or extension that calls these APIs can fail after the move even when the core application starts. The first task is a code search of your custom directory and every installed extension for these removed or deprecated APIs, and a list of owners who can fix each hit. Confirm the exact list against the EspoCRM 10.0.0 release notes before you scope the work.
EspoCRM 10.0 also changes how the upgrade is run. As of version 10.0, upgrading through the web interface is disabled by default, so the command line path is the default route. Your operations team needs to confirm that it can run that path, that the server prerequisites for 10.0 are met, and that a rollback plan exists using a verified backup of files and database. Extension compatibility must be checked separately for each package, because a release date alone does not confirm that a third-party or custom extension supports 10.0. Ask each extension vendor for a written statement of compatibility, and treat any unconfirmed extension as a blocker until it passes in staging.
Which 10.0 changes break custom code and which are new features
This table separates the EspoCRM 10.0.0 changes that can break custom code from the new features you can adopt on your own schedule. Read the first group as a checklist for code review and the second as product decisions. The main takeaway is that every removed or deprecated API needs a search of your custom code before the upgrade, and the exact replacements are in the 10.0.0 release notes.
| Change | Impact | Action needed |
|---|---|---|
| SelectManager support removed | Custom code that builds queries through SelectManager may fail or return different results after the upgrade. | Search custom code for SelectManager calls and rewrite them using the replacement listed in the 10.0.0 release notes. |
| Backend deprecations removed | Deprecated backend classes and methods that custom hooks or services call may no longer exist. | Run the code through a staging instance and fix every error in custom services, hooks and controllers. |
| Frontend deprecations removed | Custom views and client scripts that rely on deprecated frontend code may stop rendering or throw errors. | Test each custom view and button in staging and confirm the replacement API in the release notes. |
| Deprecated link access in ORM Entity::get | Code that reads related records through the older link access path may return empty values or fail. | Find Entity::get calls that read links and switch them to the current link access method documented in the release notes. |
| Jobs defined by serviceName | Custom scheduled jobs registered by service name may stop running after the upgrade. | Confirm each custom job is registered the new way and run it manually in staging before go-live. |
| Deprecated Espo.ui and Espo.utils | Custom frontend scripts that call these helpers may break in the browser. | Replace calls with the current frontend utilities listed in the release notes and test every affected page. |
| AuthToken interface changes | Custom authentication code, integrations or token handling may fail or behave differently. | Review any custom code that issues or reads auth tokens and test API and login flows end to end. |
| Multiple pipelines (new) | Teams can run separate sales pipelines, which changes how stages and reports are organized. | Decide whether separate pipelines match your sales process, then design stages, layouts and reports before enabling them. |
| Cascading links (new) | Related records can be linked through chains of relationships, which affects data structure and permissions. | Decide whether you need chained links, then check how they interact with your roles and existing relationships. |
| Record locking (new) | Only one user can edit a locked record at a time, which changes daily editing habits. | Decide whether locking suits your team and test it with real workflows in staging. |
| Categories for custom entity types (new) | Custom entities can be grouped into categories, which affects navigation and administration. | Decide how to group your custom entities and plan this alongside your Entity Manager changes. |
| Transactional save (new) | Saves can be grouped so related changes succeed or fail together, which affects custom save logic. | Decide whether custom scripts should rely on it and test error handling for multi-record saves. |
| TypeScript support (new) | Framework developers can write frontend code in TypeScript, which matters only for custom development. | Adopt it for new custom frontend work if your developers need it. Existing code does not require it. |
How removed APIs break custom PHP and JavaScript
The removed and deprecated APIs in EspoCRM 10.0.0 are the main reason custom code fails after an upgrade, so the first task is to find every place your deployment calls them. Custom hooks, services, jobs, before-save scripts, frontend views and extensions can all depend on backend or frontend interfaces that the 10.0.0 release notes list as removed or deprecated. These include SelectManager support, deprecated link access in the ORM Entity::get, jobs defined by serviceName, the deprecated Espo.ui and Espo.utils frontend helpers, and changes to the AuthToken interface. Code that uses these calls may not throw an error at install time, so a clean upgrade does not prove the customizations still work.
Failures often appear only in specific workflows. A PHP hook that reads a related record through the old link access may work for a simple form save but fail when a bulk action, an API request or a scheduled job runs the same logic under a different user. Scheduled jobs defined by serviceName may stop running silently, which means the symptom can be a missing report or a stalled assignment days later. Formula scripts used in before-save scripts, API before-save scripts, workflows and BPM need review wherever they read or write links, because they run in different contexts and are easy to overlook in a test that only opens a single record.
Start with a complete inventory of the custom directory and every extension package installed on the instance, then record which files reference the affected APIs. Ask your DeployOpen team or your developers to confirm which of these items are your own code and which come from third-party extensions, since the fix and the owner differ. Test each formula-driven workflow and BPM process with a non-admin user and with an API user, and confirm the outcome in the database as well as on screen. Compare findings against the EspoCRM 10.0.0 release notes before you decide which fixes to make.
What to prepare before touching the production instance
Most EspoCRM 9 to 10 upgrade problems start before the upgrade command runs. These six items establish a restorable baseline, show what the new major version can break, and assign who signs off. Work through them in order, because the staging test depends on the inventory and the go or no-go decision depends on the staging result.
Tested full backup
Take a complete database dump and a copy of the file directory, including custom code, uploads and configuration, then restore both to a separate host. Confirm that logins work, records open and attachments download. A backup that has never been restored is an assumption, not a rollback plan. Record the EspoCRM version and PHP version alongside the backup so the restore target is unambiguous.
Inventory of customizations
List every custom entity, layout, formula script, workflow, hook, custom directory file and installed extension. Version 10.0 removes support for SelectManager and deprecates several backend and frontend APIs, including link access in ORM Entity::get and the Espo.ui and Espo.utils helpers. Mark which items call those APIs, since they are the most likely to fail after the upgrade.
PHP and database prerequisite check
Compare the current server against the server configuration docs: PHP 8.3 to 8.5, MySQL 8.0 or newer, MariaDB 10.6 or newer, or PostgreSQL 15. Check the PHP extensions the application needs, the web server (Apache, Nginx or IIS), and that cron or a scheduled task is running for background jobs. Confirm the target versions with the 10.0 release notes before changing anything, because an upgrade can stop midway if the runtime is too old.
Production-like staging copy
Build a staging instance on the same PHP, database and web server versions as production, then load a recent copy of production data. Run the CLI upgrade there first and walk through the workflows that matter most to sales and service teams. Staging is only useful if its data volume, extensions and scheduled jobs resemble production, so note any differences you cannot remove.
Integrations and API user register
List every integration that reads or writes EspoCRM, including email, telephony, identity sync and any scripts calling the REST API. For each API user, record the authentication method in use: API key, HMAC or basic authentication. The security docs describe HMAC as the most secure option and basic authentication as not recommended. Test each integration against staging and plan credential rotation where needed.
Named go or no-go owner
Assign one person who can approve or stop the upgrade, and name the people who must be consulted: the business owner of the CRM, the administrator who runs the upgrade, and whoever owns the custom code. Define the staging results that count as a pass and the rollback trigger before the production window opens. Without a named decision maker, a failed staging test tends to become an undecided production change.
How the CLI upgrade runs from staging to production
This sequence moves EspoCRM 9 to 10 from a frozen, backed-up copy through a tested staging upgrade to a scheduled production cutover, with a rollback point at each stage. Each step closes with a check that tells the team whether it can move forward.
Freeze changes and record the baseline
The customer's administrator and the EspoCRM owner agree on a change freeze for customizations, extensions and configuration on the production instance. The team records the current EspoCRM version, PHP version, database engine and version, installed extensions with their versions, and any files in the custom directory. This baseline is the reference for comparing staging and production later. The step is complete when the baseline is written down and signed off by the owner, and when the freeze is announced to everyone who edits layouts, workflows or formulas.
Take and verify a full backup
The implementation engineer takes a backup of the application files and the database, and stores it outside the server being upgraded. Restoring it to a separate host is the test that matters, so the engineer restores it and confirms that users can sign in, records load, and attachments open. The rollback point for the whole project is this verified backup. The step is complete when a restore has been run successfully and the result is recorded, not when the backup job reports success. Confirm backup and restore commands with the official EspoCRM administration documentation for your installation method.
Upgrade PHP and dependencies if required
EspoCRM 10 has its own PHP and database prerequisites, which the team checks against the official server configuration documentation before touching production. If the server runs an older PHP version, the engineer upgrades PHP on the staging host first, reinstalls required extension modules, and confirms that the web server and cron still work. The rollback point is the previous PHP package, which the team keeps until production is stable. The step is complete when the staging host reports the required PHP version, the EspoCRM system check passes, and scheduled jobs still run under the new PHP version.
Upgrade a staging copy from the CLI
The engineer restores the verified production backup to a staging host that matches production as closely as possible, then runs the upgrade from the command line. The UI upgrade is disabled by default in 10.0, so the CLI is the expected path. The exact commands should be taken from the official EspoCRM 10.0 upgrade documentation, not from memory or older guides. The step is complete when the upgrade finishes without errors and the version shown in the administration area matches the target release. Keep the upgrade log, because it is part of the evidence for the production change.
Update or replace extensions and custom code
The team checks each installed extension against its compatibility information for EspoCRM 10 and installs an official or vendor release that supports it. Custom code in the custom directory is reviewed for use of APIs removed or deprecated in 10.0, including SelectManager, legacy link access in the ORM, jobs defined by serviceName, and the deprecated frontend utilities. Affected code is rewritten or disabled, and each change is recorded against the baseline. The step is complete when every extension is either at a compatible release or removed, and no custom code references removed interfaces. If an extension has no 10.0 release, the decision to keep it, replace it or remove it goes to the business owner before production.
Run the regression test list on staging
The QA lead runs a written regression list that covers the workflows the business depends on: lead and opportunity conversion, quote or document generation, email sending, scheduled jobs, logins including any SSO or two-factor setup, imports, and reports or dashboards. Each test has an expected result and a named tester. Failures are logged with the fix, the retest, and the owner who accepted the result. The step is complete when every test in the list passes or has an approved exception, and the owner signs off on the staging results. A failed critical test returns the project to the extension or code step, not to production.
Review logs and background jobs
Before the production decision, the engineer reviews the application logs and the queue of background jobs on staging for errors, repeated warnings, and jobs stuck in a failed or pending state. Cron or the scheduled task runner must be confirmed as active, because background work such as email and workflows depends on it. Any new warnings are traced to a cause and either fixed or accepted in writing. The step is complete when the logs show no unexplained errors during a defined observation period agreed by the team, and the job queue behaves as it did on the baseline.
Schedule and execute the production cutover
The team agrees a production window with the business, repeats the freeze, takes a fresh backup, and runs the same CLI steps used on staging against production. The engineer repeats the critical regression tests and checks the logs and background jobs immediately after the change. If a blocking failure appears, the rollback is to restore the verified pre-upgrade backup and revert the PHP version if it was changed. The step is complete when production passes the same checks as staging, the owner accepts the result in writing, and the freeze is lifted. Ask the implementation partner to state the rollback time and responsibilities in the written scope before the window is set.
What to test in staging and how to roll back
Custom code is the most likely source of failures after a major upgrade, because EspoCRM 10.0.0 removed SelectManager support and deprecated several backend and frontend interfaces. Before cutover, every custom PHP class, hook, custom frontend view and formula script should run against the staging copy of your data. Formula Script runs in before-save scripts configured in the Entity Manager, API before-save scripts, workflows and BPM, so test each of those paths separately.
- Removed SelectManager calls: Search the custom directory for SelectManager usage and confirm each call still returns the expected records.
- Deprecated link access: Check every
Entity::getcall that reads a link, since that access pattern is listed as deprecated in the release notes. - Jobs defined by serviceName: Trigger each custom scheduled job manually and confirm it runs and writes the expected output.
- Deprecated frontend utilities: Load each custom view and layout that calls
Espo.uiorEspo.utilsand check the browser console for errors. - Formula scripts: Save a test record that fires each before-save script and compare field values with the production result.
Record the results per script, because a single silent failure in a before-save script can corrupt data without raising an error in the interface.
Extensions and integrations depend on internal APIs and manifest version ranges, so an extension that loads in 9.x may fail to load in 10 even when its own code is unchanged. Install the 10-compatible release of every extension in staging, not the release you run today, and check each one's declared version range against the target version. The Advanced Pack provides reports, Business Process Management and workflows, so workflows and reports belong in the same test pass.
- Version ranges: Compare each extension's declared compatible version range with the target EspoCRM version before installing.
- Advanced Pack workflows: Run each workflow and BPM process end to end, including any external calls and signals.
- Mail and calendar connectors: Confirm sync for Google, Outlook or other connectors you use, with a test account.
- Payment and telephony integrations: Send test transactions and calls through staging endpoints only, and confirm callbacks land on the staging URL.
- Outbound webhooks: Confirm the payload format and the receiving system's acceptance of it.
Ask each extension vendor to confirm 10.0.x support in writing, because the release notes describe framework changes rather than per-extension compatibility.
Authentication breaks quietly after an upgrade. A single misconfigured identity provider can lock out every user, and an API user with the wrong authentication method can stop an integration without any visible error in the interface. Test sign-in paths before any user works in the upgraded system. EspoCRM supports OpenID Connect since version 7.3, LDAP including Active Directory and OpenLDAP, and API key, HMAC and basic authentication for API users.
- OIDC sign-in: Test login, first-login user creation, group-to-team mapping and backchannel logout against the staging identity provider.
- Fallback login: Confirm the fallback method works for an administrator, since OIDC failures should not leave you locked out.
- LDAP sign-in: Test an Active Directory or OpenLDAP account, including a disabled account that must be refused.
- API users: Call the API with each configured method, and confirm HMAC works while basic authentication is not used, as the security docs do not recommend it.
- Role permissions: Confirm API users still receive only the permissions their role allows.
Note that EspoCRM's own two-factor authentication is not compatible with OIDC, so confirm your second factor sits at the identity provider.
Background jobs run through cron or a scheduled task, and they stop silently when the schedule is missing or points to the old PHP binary. Email depends on those same jobs, so a broken cron entry can stop outbound mail, inbound fetching and scheduled reports at once. Confirm the scheduler runs under the new PHP version before testing anything else in this area.
- Cron execution: Confirm the scheduled task runs every interval and logs the expected entries under the target PHP version.
- Outbound mail: Send a test email from a user, a workflow and a scheduled report, and confirm delivery to a test mailbox.
- Inbound mail: Confirm mailboxes fetch new messages and that email-to-case creates the expected records.
- Idle and large jobs: Start a long-running import or rebuild and confirm it completes without timing out.
- Background queue: Check the job queue for failed entries after a full test run.
Keep the staging mail server and fetch accounts separate from production, so test mail never reaches a real customer.
Data integrity checks confirm that the upgrade did not change, drop or duplicate records. The CSV import supports Create Only, Create and Update, and Update Only modes, duplicate matching on chosen fields, and reverting imported records, so those features are the best tools for proving the staging data matches production. Run the same import in staging on the old and new versions and compare the results.
- Record counts: Compare counts per entity type between the production backup and the upgraded staging copy.
- Field values: Spot-check calculated fields, links and custom fields on a sample of records from each entity.
- Import modes: Run a small Create and Update import with duplicate matching, then confirm the match results.
- Export files: Export key entities and compare column headers and sample rows with the pre-upgrade export.
- Revert: Revert a test import and confirm the imported records are removed.
Keep the comparison results as dated evidence, since they also support your change record.
Rollback means restoring the verified backup of files and the database, then returning to the previous PHP version. Test the full procedure in staging before production, and treat the backup as a tested artifact rather than a file someone assumed was complete. Rollback is only clean if no writes happened after the backup was taken, so freeze user activity and background jobs before the backup starts.
- Verified backup: Restore the file and database backup to a separate host and confirm the application loads and shows expected records.
- Write freeze: Stop user logins, integrations and scheduled jobs before the final backup, and confirm nothing writes during the window.
- PHP version: Record the previous PHP version and its extension modules, and confirm you can switch back to them.
- Upgrade through the CLI: Keep the command-line upgrade steps and the exact version you started from in the change record.
- Data written after cutover: If users wrote records after the upgrade, decide in advance whether those records are re-entered, exported or lost, because a restore discards them.
Ask your team to document the restore time in staging, so the go or no-go decision uses measured data rather than an estimate.
What makes a 9 to 10 upgrade longer or shorter
This table lists the factors that change how much work a 9 to 10 upgrade takes, why each one matters, and what to check in your own installation before you plan. Read each row against your current environment, since a short list of custom code and extensions usually matters more than the size of the database.
| Driver | Why it matters | What to check |
|---|---|---|
| Custom PHP and JavaScript code | Code that calls removed or deprecated backend and frontend APIs must be found and rewritten before the upgrade can succeed. | Count custom files in the custom directory and client code, and list every call to deprecated APIs named in the 10.0.0 release notes. |
| Use of SelectManager | SelectManager support was removed in 10.0.0, so custom queries built on it will fail after the upgrade. | Search custom code, formula scripts and extensions for SelectManager usage and plan a rewrite for each hit. |
| Deprecated link access in ORM Entity::get | Code that reads links through the deprecated access path must move to the supported method before go-live. | Search for direct link reads in hooks and services, then test each affected record type in staging. |
| Jobs defined by serviceName | Scheduled jobs that rely on the old serviceName definition need to be redefined under the 10.0 job structure. | List all custom scheduled jobs and confirm which ones still run after a staging upgrade. |
| Extension count and 10.0 compatibility | Each extension either has a release that supports 10.0 or it becomes a blocker, a replacement project or a removal decision. | For every extension, confirm a 10.0-compatible release exists, check its PHP range and note any extension with no current release. |
| AuthToken interface changes | Custom authentication code or integrations that touch token handling may need updates for the new interface. | Identify any custom authentication, API or SSO code that uses AuthToken and review it against the release notes. |
| Integrations and API users | External systems that call the REST API depend on API user permissions and authentication methods, so each one needs retesting. | Inventory every API user, the authentication method used, and each external system that depends on it. |
| Data volume and cron-driven jobs | Large record counts and long background queues extend rebuild, reindex and job verification time after the upgrade. | Check record counts per entity, confirm cron or scheduled tasks run on staging, and review queue backlogs before the upgrade window. |
| PHP and database versions on the server | The next version requires PHP 8.3 to 8.5 and a supported database, so older server stacks need upgrading first. | Compare your PHP version, extension modules and database version against the server configuration docs before scheduling any work. |
| Number of environments to validate | Each environment, including staging, test and any disaster recovery copy, needs its own upgrade rehearsal and verification. | Count the environments that must match production and decide who signs off on each one. |
Questions buyers ask before upgrading EspoCRM 9 to 10
What drives the cost of an EspoCRM 9 to 10 upgrade?
The cost depends on how much custom code, how many extensions and how many environments the upgrade touches. Work is usually split into a scoping review, a staging rehearsal, the production upgrade and post-upgrade fixes. Your organization pays its own staff for time spent with business owners who approve test results. An implementation partner is paid for the work in the written scope, which is agreed before work starts and quoted from that scope. Costs rise when custom code calls APIs removed in 10.0.0, when extensions lack a 10.0 release, when PHP modules are missing on your servers, or when integrations need retesting. The upgrade and fixes are one-time costs. Support or a retainer recurs if you choose one. Ask every provider for separate line items: review, code changes, extension work, staging tests, cutover and rollback support.
How long does an EspoCRM 9 to 10 upgrade take?
No public duration is available for this upgrade, so treat any figure you hear as a question to put back to the provider. The timeline is set by the size of your custom layer, the number of extensions still awaiting 10.0 compatibility, how many staging test cycles your business owners need, and how long change freezes last in your organization. Environments with few customizations and a clean extension list generally move faster than those with custom code that reads deprecated interfaces. Start from the release history: 10.0.0 was released on July 2, 2026, and later 10.0.x patch releases followed, so confirm which patch release you will target. Ask for the phases, the dependencies on your team and the dates each phase depends on, written into the scope.
What does the upgrade need from our internal team?
Your team supplies access, decisions and testers. Name an owner for the EspoCRM instance, someone who can provide a staging copy of production data under your privacy controls, administrators who can run the upgrade commands on the servers, and business users who will test sales, service and reporting flows. An engineer who knows your reverse proxy, database and cron setup is needed for the production window, because EspoCRM background jobs depend on scheduled tasks. Developers who wrote custom code must review each change that touches removed interfaces. Agree in advance who accepts test results and who can call a rollback. Confirm that your server administrator can install the PHP version and modules required before the schedule is fixed, since the server documentation lists PHP 8.3 to 8.5.
Can our team upgrade EspoCRM 9 to 10 without a partner?
Yes, a team with Linux, PHP, database and EspoCRM administration skills can perform the upgrade alone. The open-source edition can be self-hosted for free and is licensed under AGPL-3.0. The harder part is the code review. Custom code that relies on removed SelectManager support, deprecated link access in ORM Entity::get, jobs defined by serviceName, or the deprecated Espo.ui and Espo.utils must be found and rewritten. Your team also needs a staging rehearsal built from restored backups. Ask whether your people have the time, testers and skills to cover each of these in parallel with normal operations. If they do not, a fixed-scope engagement lets DeployOpen plan, implement, test and document the upgrade inside your own infrastructure, with the scope agreed in writing first.
Can we use the web interface to upgrade to version 10?
Plan on the command line. Upgrading through the UI is disabled by default as of version 10.0, so the standard path is the CLI process described in the EspoCRM documentation. Check your own configuration before the window to see whether UI upgrades are enabled, but do not depend on it. The CLI route still requires a verified backup of files and database, a staging run against a copy, a PHP version within the supported range and a written rollback plan. Confirm which installation method you use, whether the installation script with its command.sh utility, Docker, or a manual setup, because each changes the exact steps. Ask the provider to document the commands you will run in each environment. The EspoCRM security documentation is a useful reference for the access settings to review during the same window.
Should we turn on record locking or multiple pipelines during the upgrade?
Usually not during the upgrade window. Keep the move to 10.0 focused on getting the platform running and tested, then adopt new features as a separate change. Record locking, multiple pipelines, cascading links, categories for custom entity types and transactional save each change how users work or how data is saved, so each needs its own design, role review and test cases. Enabling them at the same time as removing deprecated code makes failures harder to trace. A practical sequence is to upgrade, stabilize, then pilot one feature with a single team. For each feature, confirm how it interacts with your layouts, workflows and permissions, and what happens to existing records when it is switched on.
What happens if our extensions are not compatible with 10.0?
Hold the production upgrade until each extension has a compatible release, or plan to replace or remove it. Check each extension's manifest for the EspoCRM versions and PHP ranges it accepts, and confirm with its vendor whether a 10.0 release exists. Official extensions, such as the Advanced Pack that provides reports, workflows and Business Process Management, should be checked against their 10.0 releases before scheduling. Abandoned extensions need a decision: rebuild the function with core features and custom code, or accept the gap. Custom code in the custom directory also needs review, because it may depend on removed interfaces. Ask for a compatibility matrix in the scope that lists each extension, its owner, its status and the chosen action.
How DeployOpen scopes and delivers an EspoCRM 10 upgrade
DeployOpen plans, builds, tests and documents EspoCRM 9 to 10 upgrades inside infrastructure you control. Engagements are fixed-scope, with scope, deliverables and timelines agreed in writing before work starts, and ongoing support is available as a retainer.
How we scope
- Inventory every custom entity, formula script, hook and custom directory file that calls deprecated 9.x APIs.
- List each installed extension with its acceptableVersions and PHP range, and confirm a 10.x-compatible release exists.
- Confirm the current PHP version against the 10.x server requirements and agree who installs any missing modules.
How we build
- Rebuild a copy of production on staging, then run the CLI upgrade path there first, since UI upgrades are disabled by default in 10.0.
- Refactor deprecated backend and frontend calls such as Espo.ui and serviceName-defined jobs, then test each change against real workflows.
- Trial new features like record locking and multiple pipelines in staging before deciding which to enable for users.
How we hand over
- Deliver a written runbook covering the backup, CLI upgrade steps, rollback point and post-upgrade checks for your team.
- Document every changed custom file, extension version and configuration key so future upgrades start from a clear baseline.
- Walk your administrators through the cron-driven background jobs and verification checklist before production cutover.
How we support
- Offer ongoing support, upgrade and testing work as a retainer after the initial upgrade is complete.
- Track extension releases and PHP support changes so the next upgrade decision is based on current compatibility data.
- Agree in the quote who owns extension vendor coordination, production scheduling and post-cutover incident response.

