Drupal 7 to 11, what it really costs

There is no upgrade button. What the number is actually made of, and how to count it before you quote.

Every quote for a Drupal 7 migration is really a quote for a rebuild with a data import bolted on, and most of the variance between a good estimate and a bad one comes from five things you can count in a day. This is what they are, how to count them, and where the estimate goes wrong when nobody does.

Why there is no upgrade button

Drupal 7 was the last release built on Drupal's own procedural architecture. Drupal 8 replaced it with Symfony components, an object-oriented plugin system, Twig templates and configuration management. Nothing carries across untouched.

That break has one useful consequence and one expensive one. The useful one is that once you are on Drupal 8 or later, major upgrades are ordinary maintenance: Drupal 9 to 10 to 11 is a composer update, a deprecation sweep and a test run. The expensive one is that getting from 7 to 11 is not an upgrade at all. You build a new site, then move the content into it with the Migrate API.

So the honest framing for a client is this: you are buying a new Drupal site, and roughly a fifth to a third of the budget is the cost of bringing the old content with you. Once you say that out loud, the estimate stops being a guess and becomes an inventory.

The deadline that actually matters. Drupal 7 reached end of life on 5 January 2025, so it has had no community security support for over a year and a half. Commercial extended support can be purchased, and for some organisations that is the right stopgap, but it is a rental, not a fix. Meanwhile Drupal 12 is scheduled for the week of 7 December 2026, and no new releases of Drupal 10 will be made after that date. If you are planning a migration now, the target is 11, not 10.

The five things that drive the number

1. Contrib modules with no Drupal 11 equivalent

This is the single largest source of variance between two sites that look identical from the front end.

How to count it: list the enabled modules on the live site, not the ones in the codebase. For each one there are four outcomes, and only the fourth costs real money:

Count the fourth category precisely. Twenty modules where nineteen are ports and one is a rebuild is a very different job from twenty where four are rebuilds. The temptation is to average it. Do not.

2. Custom code volume, and its shape

Lines of code are a weak proxy. What matters is how much of the custom code is business logic and how much is glue that core or a modern contrib module now does for free.

How to count it: read the custom modules and sort each one into rewrite, replace or delete. In my experience a meaningful share of a Drupal 7 custom module is glue: a block that a view now does, a form alter that a field setting now handles, a cron job that a queue worker should have been. Deleting those is fast. Porting them because nobody read them is slow and expensive.

Two specifics that are routinely underestimated:

3. Content model complexity

The Migrate API is genuinely good, and the standard migrations for nodes, users, taxonomy terms and files do a great deal of the work. The cost sits in everything that is not standard.

How to count it: export the field list. Every content type, every field, every field type. Then flag:

4. Whether Commerce is involved

If the site takes money, treat it as a separate project with its own budget line.

Ubercart or Commerce 1 to Commerce 3 is not a version bump. The entity model is different, the order workflow is different, and there is no supported path that carries historical orders, line items and payment transactions across cleanly. The usual answer is to migrate products, customers and a defined window of order history, and archive the rest as read-only data outside the new site.

Payment gateways get rebuilt in every case, because the Drupal 7 payment modules do not exist for Commerce 3. That is also the moment to re-take the PCI decision rather than reproduce whatever the old site did, since a hosted fields or redirect integration can keep the merchant at SAQ-A instead of SAQ-A-EP. I maintain two published CyberSource gateways on drupal.org, and that scope question comes up on every one of these jobs.

5. The integration and editorial surface

The last driver is everything that is neither code nor content: views to rebuild, editorial workflow, user roles and permissions, search, and any integration with a CRM, ERP, SSO provider or payment processor.

How to count it: count the views on the live site and count the integrations. Views are quick individually and slow in aggregate, and nobody remembers there are seventy of them until the fortieth one. Integrations are the opposite: few in number, and each one capable of consuming a week on its own if the remote end is old, undocumented or owned by a third party who has to be scheduled.

An estimating model you can actually apply

Here is the shape I use. It is a model, not a price list: the point is that each line is something you counted rather than something you felt.

PhaseTypical shareWhat moves it
Discovery and module map5 to 10%Fixed and small. Skipping it is what makes every other line wrong.
Site build: content types, fields, views, permissions20 to 30%Number of content types and views; whether the content model is being redesigned at the same time.
Custom and contrib gap work10 to 40%The count of modules in category four and the volume of genuine business logic. The widest band on the table.
Theme15 to 30%Whether the design is being kept, refreshed or replaced.
Migration build and re-runs15 to 25%Field type mismatches, multilingual, media, and how many times you re-run before launch.
QA, content checking and launch10 to 15%Content volume and how much of it a human has to look at.

Two rules that keep this honest. First, the migration is built to be re-run: you will run it a dozen times or more, and the final run happens on launch day against live data, so anything manual in that path is a defect. Second, discovery is quoted separately and delivered as a document. A fixed price for a migration written before anyone read the custom modules is not an estimate, it is a bet.

Rebuild or migrate: the decision most agencies face

Every one of these projects reaches a point where someone asks whether to run the Migrate API at all, or simply build the new site and copy the content across by hand. It is a legitimate question and the answer is usually decided by three numbers.

The usual answer is a hybrid: migrate the high-value, high-volume content types with the Migrate API, redesign the models that need it, and hand-carry the small handful of landing pages that are really design work anyway.

Where the estimate overruns

Five places, in roughly the order they bite.

  1. Files and media. The file count is bigger than the estimate, a meaningful share of them are orphaned or missing from disk, and mapping them onto media entities involves decisions about alt text and media types that nobody made in 2011.
  2. URLs and redirects. Path aliases, old redirect rules, and the search rankings attached to them. This is cheap to do at the start and expensive to do after launch when traffic has already dropped.
  3. The module nobody mentioned. Something with data in its own tables, no Drupal 11 equivalent, and one person in the client organisation who depends on it daily. Always found in discovery if you look; always found in week six if you do not.
  4. Content clean-up promised for later. Duplicate taxonomy, half-finished drafts and inconsistent field usage. The migration exposes all of it, and the argument about who fixes it happens in the middle of the project instead of before it.
  5. Third-party scheduling. The payment provider, the SSO team, the CRM vendor. Your team can be ready and still lose two weeks.

None of these are technical surprises. They are all things that a week of discovery would have surfaced, which is exactly why the discovery phase should be a paid deliverable rather than a free part of the sales process.

What I would tell a client asking for one number

That the number depends on four counts they can get in an afternoon: how many enabled modules, how many custom modules, how many content types and fields, and whether the site takes payments. Any developer who gives a price without asking for those four things is pricing a different site.

And that the cost of waiting is not zero. A Drupal 7 site today is running unsupported code with a paid stopgap at best, on PHP versions that hosting providers are steadily retiring, with a shrinking pool of developers who remember how it works. Drupal 11 needs PHP 8.3 or newer, which for most Drupal 7 sites also means the server estate moves at the same time.

If you want this done

I take Drupal 7 to 11 migration work as fixed-price pieces for agencies: module and custom-code porting, migration builds, and PHP 8.x upgrades priced per site, delivered under your name. That is set out on the white-label Drupal for agencies page, and the end-of-life background for site owners is on the Drupal 7 support page.

If what you actually need first is the count rather than the build, a fixed-price site audit produces the module map, the custom code inventory and the content model review as a written document you can take to any developer, including one who is not me.

© 2026 Graith Internet.

Graith Internet is a UK web development company specialising in PHP, Drupal, and AI-assisted development.

Find this useful? Tell Google to show you more from Graith Internet in Search, Discover and News.