What ongoing WordPress maintenance covers
WordPress maintenance consists of four kinds of work that are only loosely connected: core updates, plugin and theme maintenance, maintenance of the underlying platform, and support for the editorial team. For the first two, the order is decisive. Before the core update comes the check whether the plugins in use support the target version — not after it. In the maintenance window we therefore work in steps: take a backup, bring the staging copy up to the live state, update the plugins individually or in small groups, then the core, then rebuild the theme. Anyone who instead clicks „Update all" once has twelve suspects and no findings if something goes wrong. The rollback route is defined before the window, not searched for during the incident.
Backups are the part of maintenance with the most trust and the least checking. A backup consists of three things: the database dump, the wp-content directory with uploads, themes and plugins, and the wp-config.php. A restore test involves more: the archive is actually restored on a staging environment, and then the login, the media library, a form submission and the home page are checked. Only then is it proven that the chain works. We set the retention period in writing, keep the backups separate from the production system and log every test. A backup that sits on the same server as the installation covers technical failures, but not a compromise.
The underlying platform ages independently of WordPress and is therefore regularly overlooked. On its own requirements page, WordPress recommends PHP 8.3 or newer and MariaDB from 10.11 or MySQL from 8.0 (retrieved 17 August 2026). The technical minimum values are much lower at PHP 7.4 and MySQL 5.5.5 — these are versions that no longer receive security updates themselves, and WordPress points this out explicitly on the same page. This part of the work also covers TLS certificates and their renewal, the question of whether WP-Cron runs through page views or through a system cron, and mail delivery: wp_mail() sends through PHPMailer, by default through the PHP function mail(), which regularly fails with today's recipients — an authenticated SMTP route with SPF, DKIM and DMARC belongs in the maintenance, not in a separate project. Monitoring therefore means more than a ping for us: availability, status codes, certificate validity, cron jobs, mail delivery and error rates in the log.
The attack surface sits in the plugin environment
The WordPress core is not the problem child, and it helps nobody to make it one. Minor releases have been distributed automatically since version 3.7, security fixes with a forced update if necessary — that is how it worked with 7.0.2 on 17 July 2026. Of the 11,334 vulnerabilities that Patchstack counts for 2025 in the WordPress environment, 91 per cent were in plugins and 9 per cent in themes; the core accounted for six reports in the whole year, all of them low priority. 1,966 reports, that is 17 per cent, were rated high, which means: with a realistic prospect of being exploited in automated mass attacks. This does not mean that nothing happens in the core — 7.0.3 from 6 August 2026 brought around a dozen security corrections at once, some of them to code that reaches back into older main versions. The difference lies in the route: with the core, the fix appears together with the report and is distributed automatically. Anyone who talks about WordPress security and talks about core versions is talking about the smaller part of the problem.
The most uncomfortable figure from the same report for day-to-day operation: for 46 per cent of the vulnerabilities, no patch was available at the time of publication. For a maintenance window this means that „wait until the update arrives" is not a strategy. There are then three options — switch the function off temporarily, replace the affected component, or block the attack route further upstream. Which of these works is decided by the specific case. On top of this comes the structural problem of unmaintained extensions. WordPress.org puts a notice on the plugin page when an extension has not been tested with the last three main versions. This notice depends on the „Tested up to" field in the readme.txt — a developer can remove it without touching a single line of code. As a warning signal it is useful; as an approval it is worth nothing.
For a plugin without a maintainer there are four ways forward, and we name them one by one: use a maintained alternative, move the function into your own theme, take over the code yourself and maintain it further, or drop the function because nobody uses it anyway. The last case happens more often than people think. What does not belong here: replacing every plugin across the board that has had no release for a year. A small helper plugin whose code you can read in one sitting is a different risk from a form or shop plugin with its own database table and access to order data. We base the assessment on the code, not on the date. If the outcome is a custom development, that is a project of its own — there is more about this on our page on WordPress plugins and extensions.
Why „it works, though" is especially misleading with WordPress
With a system that does not update itself, you notice the standstill at some point. WordPress, by contrast, moves even when nobody is looking. Minor releases have arrived automatically since 3.7. Since version 5.6, new installations additionally have automatic updates for major releases switched on by default, provided WordPress does not detect a version control checkout; existing installations keep the old behaviour until an administrator, a constant or a filter changes it. In practice this means: some installations have moved from 6.x to 7.0 without anybody making a decision. The core is therefore up to date. The plugins, the theme and the custom code are not — and no automatic process checks whether they still fit together.
Where this breaks is not visible from outside. WordPress 7.1 is announced for 19 August 2026 and brings three breaking points that mainly affect the back end and the editor. First: the post editor will then always run in an iframe — regardless of the theme type, the block API version of the registered blocks and the blocks used in the content. Code that accesses the global document or window no longer finds the editor content there; the route runs through ownerDocument and its defaultView on an element in the canvas, and event listeners through useRefEffect. Second: in the list tables, the leading th with scope="row" moves from the checkbox column to the title column — the checkbox cell becomes a td, the title cell a th with aria-label. This is markup that has been essentially unchanged there since 2010; extensions that select on th.check-column or on th input[type="checkbox"] will find nothing. Third: the __next40pxDefaultSize property has become ineffective, and form elements render at 40 pixels unconditionally — even __next40pxDefaultSize={ false } no longer switches back to 36 pixels. One widespread misunderstanding should be corrected: React 19 is not coming in 7.1. The upgrade was withdrawn after incompatibilities appeared between the old and the new React version and in the way plugins include React. 7.1 stays on React 18.3; Gutenberg offers an experimental flag for testing. What the step itself means in terms of work is on our page about the WordPress update to 7.1 — here we are looking at the consequences for ongoing operation.
These errors affect editors, not visitors — and editors often do not report them but work around them. The silent failures in operation behave in the same way: the mail delivery of the contact form fails, but the thank-you page appears anyway. WP-Cron no longer runs, so scheduled posts do not appear and backups do not start. A redirect plugin loses its table, and old URLs end in a 404. All of this lets a website look normal. That is why maintenance does not check whether the home page loads, but the functions that money or enquiries depend on. And that is why the sentence „it works, though" is not a finding with WordPress, but an assumption.
When an installation is compromised
A compromised WordPress is rarely recognisable by its appearance. The typical patterns are built to be inconspicuous: redirects that only trigger with a search engine referrer or with certain user agents, while the direct request looks normal. Links to third-party sites inserted into the footer or into post content, pushed out of view with CSS. Mail sent through the server until the IP address lands on blocklists and your own business mail no longer arrives. Plus the traces you have to look for: PHP files under wp-content/uploads, an unexpected wp-content/mu-plugins directory whose contents WordPress loads without activation, obfuscated code at the beginning of functions.php, an administrator account with an unremarkable name and a recent registration date, an additional cron entry. In practice the first indication comes from outside: from Search Console, from the hosting provider, or from a customer whose virus scanner raises an alert.
The order of steps in a suspected case is fixed, because otherwise the wrong things happen first under time pressure. First: put the installation into maintenance mode or take it off the network. Second: save a snapshot of the compromised state instead of overwriting it — it is the only basis for the question of what happened, and, if a report to the supervisory authority is needed, the only evidence. Third: withdraw access. Passwords of all editorial and administrator accounts, application passwords, database users, SFTP and SSH keys, plus the salts and keys in the wp-config.php, which ends all existing sessions. Fourth: take stock against a known state — compare core files and plugins against the originals, and go through the user list, the cron entries and the scheduled tasks. Only after that is the site restored or rebuilt, and the content is taken over, not the files.
A cleanup without clarifying the cause is pointless, and an uncomfortable limitation belongs here: on an installation that has not been maintained for years and whose logs have rotated, the entry route often can no longer be determined. We say so in that case, instead of selling an assumption as a finding. The consequence is a clean rebuild on a current basis with the content taken over, because that is the only way to know what is on the system — and not a second cleaning run after which the same redirects reappear in four weeks. If personal data is affected, the 72-hour reporting period under Article 33 GDPR applies; whether a report is necessary is assessed by your legal advisers, not by us. We can be reached Mon–Fri 9:00–16:00, outside these hours only with an agreed on-call service.
What a maintenance contract looks like with us
At Sharpness a maintenance contract consists of a fixed part and an agreed part. Fixed are: watching the security reports for the core, plugins and theme, including an assessment of whether your installation is affected; updates on staging first, then live; backups with a documented restore test; maintenance of PHP, the database, TLS and mail delivery; monitoring; support for the editorial team; and a log of the work carried out that you can present to a data protection officer or in an audit. What is agreed is the response time. There are four tiers for this: BASIC with 24 hours, STANDARD with 8 hours, ADVANCED with 4 hours, PREMIUM with 2 hours — each as a monthly flat rate net per project. We name the flat rate in the quotation, not on a website, because it depends on the scope of the installation. Without an agreement our basic commitment applies: processing in order of arrival within 48 hours during business hours, Mon–Fri 9:00–16:00.
Not included in ongoing maintenance are projects that need their own quotation. This includes catching up an installation that has not been touched for years: that is not a maintenance window but a project with an inventory, plugin replacements and test runs — you can read about it on our page on WordPress updates. The same applies to redesigns, new functions and the development of your own plugins and Gutenberg blocks. Regular version steps on a maintained system, for example from 7.0 to 7.1, are part of the maintenance. This distinction sounds like less service than with providers who include everything. It is more honest: anyone who names a flat price for an unknown backlog builds in a surcharge that you pay for every month.
Operation runs on our own servers in Germany — Proxmox cluster, server location Germany — or on your existing hosting. Both work. On third-party infrastructure we need SSH access, a usable deployment route, a staging environment or the option to create one, and access to the backups. If that is missing, every maintenance window becomes more expensive than a migration, and we say so in advance. We set up the ongoing support so that you can end it: access details and licences in your company's name, domains in your name, theme code in your repository, the installation documented. And if a maintenance contract does not pay off for you — a small company website with four standard plugins on decent hosting that you click through yourself every month — we say that too. A contract that only sells peace of mind does not last long.