Guide
SQL Server 2025 upgrade: a schema checklist
Before upgrading to SQL Server 2025, capture the schema, check what the new edition drops (SSRS, Express limits), and compare the schema after the upgrade.
Guide
Before upgrading to SQL Server 2025, capture the schema, check what the new edition drops (SSRS, Express limits), and compare the schema after the upgrade.
An in-place upgrade to SQL Server 2025 does not rewrite your tables, and that is exactly why schema problems after an upgrade are hard to explain. The databases come across intact, and what changes is everything around them: the components installed next to the engine, the limits of the edition, the jobs and reports that used to run on the old instance. Most post-upgrade incidents are a dependency nobody wrote down.
This checklist is about the schema and the things that depend on it, not about the setup wizard.
1. Write down what the schema is today. A data dictionary per database, or at least a scripted copy of the schema, gives you something to compare against afterwards. The SQL Server data dictionary query produces one in a few seconds, and Generate Scripts in Management Studio or sqlpackage /Action:Extract produces a full script. Store it outside the server you are about to upgrade.
2. List what runs on the instance besides the databases. SQL Server Agent jobs, Database Mail profiles, linked servers, logins with server roles, and above all Reporting Services. SQL Server 2025 consolidates on-premises reporting into Power BI Report Server, so an SSRS instance does not come along with the upgrade. The SSRS subscription guide covers sorting the subscriptions that need a report server from those that only ever emailed a CSV.
3. Check the edition limits that changed. Express 2025 raises the database size limit to 50 GB and absorbs what used to be Express with Advanced Services, but it still has no SQL Server Agent and no Database Mail. Standard 2025 goes up to the lesser of 4 sockets or 32 cores and 256 GB of buffer pool. A server moving between editions during the upgrade should be checked against Microsoft's edition table rather than against memory.
4. Look for deprecated features in use. The Deprecated Features counters show what the workload actually calls:
SELECT instance_name AS feature, cntr_value AS uses
FROM sys.dm_os_performance_counters
WHERE object_name LIKE '%Deprecated Features%' AND cntr_value > 0
ORDER BY cntr_value DESC;
Counters reset on restart, so read them after the server has run a normal business cycle.
5. Note each database's compatibility level. Upgraded databases keep their current level until someone raises it. Record the levels now so that raising them to 170 later is a deliberate, separate change with its own testing, rather than something nobody remembers doing.
6. Compare the schema with the snapshot from step 1. An upgrade should produce no differences in user objects. If it does, something ran during the upgrade window: a vendor script, a deployment that was not paused, a maintenance job. Finding that out on the first morning is much cheaper than finding it when a report breaks two weeks later.
7. Recreate what lived outside the databases. Agent jobs, mail profiles and report subscriptions on a new instance need to be scripted from the old one. On Express there is nowhere to recreate jobs or Database Mail, which is covered in the Express scheduling guide.
8. Raise compatibility levels one database at a time, with Query Store capturing plans before and after, and keep the previous level written down in case a regression forces a rollback.
Steps 1 and 6 are the part most teams skip, because producing and comparing two schema snapshots by hand is tedious. Taavik's schema change detection turns it into a side effect: an agent inside the network scans each database with a read-only login on a schedule, the generated documentation keeps a revision per change, and any difference after the upgrade shows up with a severity, likely breaking for a dropped column or a changed type, attention for a modified view or procedure. Alerts can send those changes to Slack, email or a webhook.
A scan the day before and a scan the day after give the comparison for free, and the same scans keep watching once the upgrade is long finished. What it does not do is check instance-level objects such as Agent jobs, logins or linked servers: it reads databases, not the server configuration.