When WordPress Starts Costing More Than It Saves

Technology · 20 Apr 2026 · LavisTech

The bill that is not the hosting

WordPress is a good way to publish. It is a bad way to pretend you do not have a software problem. The hosting invoice stays small for a long time. The real bill is the plugin pile, the person who is afraid to click Update, the page builder that owns your markup, the security panic after a weekday exploit in a forgotten form plugin, and the afternoon it takes to add a field the theme never expected. At some point that bill is larger than a boring custom site that only does what you need.

We say this as a firm that still builds WordPress when it fits — a brochure, a small store, an editor who already lives in the admin and will not thank you for a new stack. We also say it as the people who moved lavistech.com off WordPress onto ASP.NET Core because the old install could not carry the content model and the SEO work we needed. That move is the example on this page. It is not a morality play. It is a sequence you can copy or refuse.

If anonymous visitors are the main users, you are still in website territory. Leaving WordPress does not turn the site into a product. It changes who owns the HTML, the URLs, and the Monday publish. Read website versus web application before you let a vendor sell you a rewrite because they prefer a framework. The user’s job decides the bucket. The plugin list decides whether WordPress is still cheap inside that bucket.

Plugin pile as a product decision

Every plugin is a vendor. It has its own release calendar, its own PHP assumptions, its own idea of a database table. A site with a SEO plugin, a form plugin, a cache plugin, a slider, a popup, a backup, a security scanner, a multilingual add-on, and a page builder is not “a CMS”. It is a small integration project you did not name. When two of those vendors disagree after a core update, your Tuesday is their support forum.

The pile grows because each request is cheaper than a developer day — until the tenth request. “Just add a plugin” is how you get three ways to insert a schema block and none that match the service page you actually ship. It is also how you get admin users who will not update anything because last time the header vanished.

  • Two plugins that both want to be the canonical URL manager.
  • A page builder whose export is not HTML you would hand a human.
  • A form plugin that stores enquiries in a table nobody backs up with the rest of the site.
  • A “security” plugin that emails theatre while an old PHP version sits underneath.
  • A slider on the homepage because the theme came with one.

Count the plugins that would take the site down if they stopped being maintained. That number is the risk, not the theme’s star rating. If the number is uncomfortable and the site is now a content system — knowledge articles, services, redirects, a blog you intend to keep for years — you are in the zone where WordPress starts costing more than it saves.

Security is a calendar, not a badge

Public CMS installs get scanned because they are public CMS installs. That is not a reason to panic. It is a reason to have a calendar: core, plugins, PHP, backups you have restored once, and who is on the hook when a CVE lands on a Thursday. Firms that “set and forget” a cheap WordPress host discover the calendar when Search Console shows injected pages or the host suspends the account.

A custom site is not magically safe. It is differently owned. You patch what you wrote and what you pulled in. You do not wait on a freelance plugin author who shipped last in 2021. You also do not get a thousand attack paths that exist only because a theme demo installed a contact widget you never used. The honest comparison is operational, not ideological.

If you stay on WordPress, pay for that calendar. Managed WordPress with a grown-up backup and a person who updates on a schedule can be cheaper than a rewrite. If you will not pay for the calendar, you are already paying in risk. Do not dress that up as frugality.

When the content model does not fit

WordPress pages and posts are a fine model for a brochure and a blog. They become a fight when you need services with a stable slug and a catalog, knowledge articles with categories and related keys, portfolio items with a sort order, redirects as first-class rows, and SEO fields that are not a sidebar of leftover meta boxes. You can force all of that into custom post types and ACF. Many people do. At some point you are maintaining a bespoke application that still reboots the world when you change a permalink setting.

Our old lavistech.com install used default permalinks. Search Console still reported /?page_id= and /?cat= URLs. That is a content-model smell: the public address of a thought was a query string on the homepage. You can fix permalinks inside WordPress. We also needed a knowledge hub, a service catalog, and a Monday blog series that must never collide with three already-live posts. Forcing that into the old themes and plugins was going to cost more than building the model in the stack we already use for business software.

That last sentence is the tell. When the site’s information architecture is closer to an application schema than to “pages and posts”, WordPress is a rental costume. You can keep wearing it. Budget the tailoring. Or change clothes.

Why we moved this site

lavistech.com is a public website: services, knowledge, blog, contact, admin for editors. It is not a staff workflow behind login except the CMS. We still moved it to ASP.NET Core because we needed HTML we own, URLs we can test, redirects we can reason about, and seedable content we can review in git. The old WordPress install could not carry that without becoming a second product we did not want to staff.

We did not move because WordPress is embarrassing. We moved because our publishing cadence and our SEO work are now part of the same codebase as the rest of the firm’s engineering habits. That is a luxury of being a software shop. It is also a concrete example: the cost that tipped us was not hosting. It was the content model, the permalink mess, and the time to ship a structured article without fighting a builder.

The longer argument for the stack on a business site is the existing post Why ASP.NET Core for business websites. That URL stays where it is. We are not renaming live blog slugs to make a migration story tidier. If you found that article last year, it should still open. That discipline is the point of a migration, not a new theme on a new host with new permalinks and a shrug.

Stay or leave

SignalStay on WordPressLeave
EditorsThey already work in wp-admin and are productiveNobody wants to open it; a freelancer holds the admin
Content modelPages, posts, a simple storeCatalogues, hubs, seeded series, redirects as data
PluginsA short list you update on a calendarA pile you are afraid to touch
URLsPretty permalinks, one host, working 301sQuery-string leftovers, mixed www, soft 404s
SecurityManaged host, backups restored onceUnknown PHP, unknown authors, no restore test
Next six monthsCopy changes and a few landing pagesA knowledge system you will keep for years

If four rows point to “stay”, stay. Buy the calendar. Fire the slider. That is cheaper than a rewrite you will not maintain. If four rows point to “leave”, you are not abandoning a CMS. You are admitting you already have a software project.

A migration sequence that does not lose the old URLs

  1. Inventory. Crawl what Google already knows: Search Console pages, the XML sitemap, the query-string leftovers. Export posts, pages, media URLs. List the three or ten URLs that already have impressions. Those must 301, not “we will add them later”.
  2. Freeze the IA. New slugs for new work. Old slugs stay for old work. Do not “clean up” a live article slug because the title changed. We keep /blog/aspnet-core-for-business-websites exactly because people and Search Console already use it.
  3. Build the new site in parallel. Same public URLs where they still apply. Host it on a staging name. Do not switch DNS to an empty theme.
  4. Redirect table. One row per old address, including /?page_id= if that is what WordPress shipped. Test the ones Search Console still reports. Never add a rule that sends / to itself.
  5. Content move. Copy what still earns. Leave the festival posts that were only plugin-fodder if they have no impressions — or 301 them to a sensible parent. Do not invent a new blog home that 404s the old one.
  6. Cutover. DNS, certificates, www versus apex, sitemap submitted, Search Console property covering the host you actually serve. Watch the 404 report for two weeks like a hawk.
  7. Turn off the old install. After the 301s are proven. Leaving WordPress up on a subdomain “just in case” is how you get two indexes and a malware copy you forgot.

That sequence is the job. A redesign that also changes every slug is two jobs, and the second one quietly destroys the first. If a designer wants a new URL scheme, they can have it on pages that never ranked. Money URLs keep their path.

What week one of an inventory looks like

Export the post list with slugs, titles, dates, and status. Crawl the live site. Diff the two. The URLs that exist in Search Console but not in the export are the query-string ghosts and the old attachments. Put them on the redirect spreadsheet before anyone argues about the new header. Then open the ten URLs with impressions and write what must not change: title if it ranks, slug always, H1 if it is already the query.

Media is the part people skip. Old image URLs in articles will 404 if you only move the HTML. Either keep the uploads path with a redirect or rewrite the src attributes as you migrate. Broken images are CLS and they are also how a “clean new site” looks unfinished in the first week, which is when you are staring at the 404 report anyway.

Forms: where do enquiries go today? A plugin table, an email, both? The new site needs a destination on day one or you will hear about it from a human, not from Search Console. We store enquiries in the application database with the usual antiforgery and rate limits. Your version can be simpler. It cannot be “we will add the form in phase two” if the old form was the business.

After the move: who edits, who deploys

WordPress trained a generation of editors to log in and type. A custom site needs an admin that is good enough or you will get a revolt and a shadow WordPress on a subdomain. Budget the editor screens. A knowledge article with excerpt, HTML, and related links is a CMS feature, not a “we will use git” fantasy unless the only editors are developers. We are developers. Most of our clients are not. Do not copy our workflow unless you have our staffing.

Deployments should be boring: a release you can roll back, backups you have restored, and no FTP of a plugin zip at 11 p.m. That is .NET development when the site is an application-shaped CMS. It is still web development when the job is public pages, SEO, and a contact path. We estimate them as related jobs that share a brand. We do not estimate them as “a theme, plus whatever”.

If you stay on WordPress after reading this, good. Cut the pile, pay for updates, fix the permalinks, and write the service pages. If you leave, leave for a model you can own, and take the old URLs with you. The expensive version is a new stack and a new slug scheme and a Search Console property that looks like a crime scene. We refused that version for lavistech.com. You should refuse it too.

The stack essay is already live at the ASP.NET Core blog URL above. This page is only the leaving criteria and the sequence. Use both. Do not let a vendor collapse them into “WordPress is dead, sign here”. WordPress is not dead. It is just no longer the cheapest way to run this particular site. That sentence is allowed to be true for you later, or never. April is a fine time to decide which, before another year of plugin renewals lands on the same leftover budget as the rewrite.

← All posts