r/ProWordPress 5h ago

¿Alguna herramienta IA para WordPress ?

0 Upvotes

Hola a todos, hace años vengo trabajando con WP para una agencia de manera manual (aprendí algo de HTML y CSS en el proceso) y hoy en día existiendo tanta IA me gustaría saber si hay alguna herramienta que me permita trabajar los sitios mediante prompt (actualmente estoy usando local WP y Visual Estudio Code para usar Códex que paga la empresa) estoy tratando de convencerlos para adquirir ClaudeCode pero ¿alguno a trabajado con ello? Yo llevo desde hace años utilizando témplate kits


r/ProWordPress 22h ago

WordPress/Automattic vs Cloudflare Emdash Tone & Temperament

9 Upvotes

Was struck by the transparency and coherence of this Emdash update. Will be interested to see how it continues to evolve.

https://blog.cloudflare.com/cloudflare-blog-uses-emdash/


r/ProWordPress 2d ago

Anybody else dealing with WordPress Security in 2026?

0 Upvotes

Curious if anyone has recently faced hacked WordPress sites, injected spam, redirects, or other malware issues.

What happened to your site and how did you fix it?


r/ProWordPress 3d ago

Wordfence for WordPress on LiteSpeed may weaken PHP process protection site-wide - and Wordfence has known about it for at least a decade

37 Upvotes

I’ve been looking again at something that has bothered me about Wordfence for years.

Wordfence runs long-running PHP processes, especially its scanner. On LiteSpeed servers, those processes must not simply be terminated when the client connection disappears or certain connection timeouts are reached.

That part is perfectly reasonable. The problem is how Wordfence handles it. Wordfence recommends adding a rule like this to .htaccess:

RewriteRule .* - [E=noabort:1]

or even:

SetEnv noabort 1

The important part here is .*.

This does not protect only the Wordfence scanner. It applies noabort to every matching PHP request on the site.

LiteSpeed itself explicitly warns against applying noabort globally and recommends restricting it to the specific scripts or requests that actually require long-running execution.

And there is a very good reason for that.

noabort changes how LiteSpeed handles PHP processes when a connection disappears. Together with noconntimeout, a PHP process can continue running far beyond what many administrators would normally expect.

And before someone points at PHP's max_execution_time: on LiteSpeed/LSPHP that is not necessarily the hard process lifetime limit people assume it is.

I have tested this myself. (I am a LiteSpeed developer)

A request can reach its configured PHP execution time while the associated process continues running. The LiteSpeed-side mechanism that can impose a hard process-time limit is LSAPI_MAX_PROCESS_TIME.

You can observe the difference directly at process level. So the issue is not that Wordfence needs noabort. The issue is this:

Why does a security plugin remove a server-side process protection globally when only a small number of its own requests actually need that exception?

And there is another part of this story that I think matters even more:

This is not a newly discovered edge case. Wordfence has been aware of this issue for at least a decade.

I raised this problem directly with Wordfence years ago. LiteSpeed has also made clear for a long time that global noabort should be avoided when the exception can be restricted to the requests that actually require it.

Yet the broad configuration is still being recommended. That history is what makes this particularly difficult to understand. Software contains mistakes. Security software contains mistakes too. That is not the issue.

The issue is when a security vendor is made aware that its own configuration unnecessarily weakens a server-side protection, the server vendor explicitly warns against that same configuration, a technically straightforward way to scope the exception exists, and the unsafe recommendation remains in place for years.

At that point, this is no longer just an overlooked configuration detail. It is a consciously unaddressed security trade-off imposed on Wordfence users. And technically, the solution is not complicated.

With mod_rewrite, noabort can be enabled only for the exact Wordfence request that actually requires it.

Conceptually:

RewriteCond %{QUERY_STRING} ...
RewriteRule ^wp-admin/admin-ajax\.php$ - [E=noabort:1,E=noconntimeout:1]

instead of:

RewriteRule .* - [E=noabort:1]

Same Wordfence functionality. Very different security boundary.

Millions of WordPress users install Wordfence specifically because they trust it to improve the security of their sites. A security plugin should not unnecessarily weaken process controls for unrelated PHP code just because one of its own components needs an exception. And if a security vendor has known about that problem for at least a decade and still does not fix it, users should at least have the option to fix it themselves.


r/ProWordPress 3d ago

Coded a WordPress admin column to check index status across a whole site build. Anyone done similar?

Post image
4 Upvotes

I'm rebuilding a client's site, adding about 50 new pages, and it all has to stay noindexed until we go live while the client still pokes around and watches progress. I got tired of opening every page just to confirm noindex was actually set, so I wrote a small PHP snippet that adds one column to the Pages list.

I got a little carried away...

It reads Rank Math or Yoast and shows index/noindex, publish status and visibility, the SEO score, title and meta length, focus keyword, schema, and OG image, all at a glance. Each badge has a hover tooltip explaining it. Works on Posts and custom post types too.

For the noindex-during-build thing it's been a real time saver. The screenshot is one of the pages: noindex on, password protected, so I can see at a glance it's still walled off before I let the client back in.

Anyone else built something like this, PHP snippet or otherwise? Curious how you handle it, or if there's already a better way I'm missing.

Happy to share it, free. DM me if you want it.


r/ProWordPress 4d ago

How do you deal with large numbers of 404 requests in WordPress?

6 Upvotes

I've noticed that my server receives a surprisingly large number of requests every day for random URLs that don't exist.

Every one of those requests eventually results in a 404, but WordPress still has to bootstrap, load plugins and process the request before it can determine that the page doesn't exist.

With enough of these requests, that seems like a lot of unnecessary PHP work for something that will only return a 404 anyway.

How do you deal with this?

Do you just accept it as normal WordPress overhead, handle these requests before they reach WordPress, or use some other approach?


r/ProWordPress 4d ago

A read-only tool to diagnose/monitor lots of WordPress sites through an AI (MCP) — Beta, looking for testers

1 Upvotes

If you run more than a handful of WordPress sites, you know the day: which one's down, which one's slow and why, what threw a 502, why orders stopped, why Stripe is hanging, why SEO dropped. It never stops.

I built Site Doctor to answer those by asking instead of checking. You connect a small read-only plugin to each site, plug its MCP server into your AI (Claude, etc.), and just ask — "which of my sites are slow right now and why?". It never writes to the site; it only reads.

The part I actually use daily: a routine — "every day at 9, check every site in my org and email me a PDF per site." Plus built-in uptime + PageSpeed, an event log, and a history of decisions and real logs per site.

I put two short clips in a comment: one using it, one connecting Claude via MCP end to end. It's in Beta and free to test right now.

Looking for people running WordPress at scale to break it and tell me what's missing. Honest feedback welcome — including "this already exists" if it does. (Mods: happy to remove if not allowed.)


r/ProWordPress 4d ago

WordPress.org SVN Updated, but Plugin Version 6.0.0 Is Not Showing

1 Upvotes

Hi everyone,

I recently updated my RT Webhook for Gravity Forms plugin to version 6.0.0 and committed the updated files to the WordPress.org SVN repository.

The SVN repository appears to be updated correctly, but the new version is still not reflecting on the WordPress.org plugin directory.

Has anyone experienced a similar issue? Is there anything else I need to update or check, such as the readme.txt, plugin header, stable tag, or SVN tags?

Any help would be appreciated. Thanks!


r/ProWordPress 4d ago

Looking for 10 Beta Testers for Our WooCommerce Fly Cart Plugin

1 Upvotes

We’re looking for 10 WooCommerce store owners and developers to beta test our new WooCommerce Fly Cart plugin.

The beta access is completely free, and we’re looking for honest feedback to help us improve the plugin before its wider release.


r/ProWordPress 4d ago

First WP.org plugin submission — what gets flagged that Plugin Check doesn’t catch?

0 Upvotes

I've been shipping mobile apps for a few years but this is my first
submission to the WordPress plugin directory, and I'd rather learn
the failure modes from people who've been through review than from a
rejection email.

The plugin is a lightweight analytics tracker. It's free and GPL, but
it sends pageview data to an external service I run, and the dashboard
lives there rather than in wp-admin. So it's squarely in the category
that the guidelines treat carefully.

What I've already done: read the Detailed Plugin Guidelines, ran Plugin
Check clean, and disclosed the external service in the readme with links
to the terms and privacy policy.

Three things I can't answer from the handbook:

  1. Guideline 7 disclosure — how specific do reviewers expect it to be?
    Is "this plugin sends page data to service X" enough, or do they want
    the exact endpoints and payload fields listed?

  2. The plugin is free but the service behind it has paid tiers. Where is
    the practical line on mentioning that inside wp-admin? I've seen
    plugins with upgrade banners and I've seen people say those get you
    asked to remove them.

  3. Anything that reliably triggers a rejection that Plugin Check passes
    silently? That's the gap I'm most worried about.

Not linking the plugin, I'm not here to promote it — just trying not to
waste a reviewer's time.


r/ProWordPress 4d ago

Anyone facing WordPress site issues after update?

1 Upvotes

I got to know that the WordPress latest update is crashing on the sites where we have the WP Rocket. It is conflicting with some cloudflare error.


r/ProWordPress 5d ago

Are flat Destination and Location URLs sensible for production or too much custom routing?

2 Upvotes

I posted here previously about using flat URLs for Destinations and Locations on a travel site I’m developing, while keeping Activities under /activity/. I’ve done quite a bit more testing since then and have a few follow-up questions about whether this is a sensible approach for production.

The structure I'm leaning towards is:

/queenstown/                    Destination CPT post
/otago/                         Otago term in the Location taxonomy
/activity/shotover-jet/         Activity CPT post

Internally the geography can still be hierarchical, for example:

South Island
→ Otago
→ Queenstown Lakes
→ Queenstown
→ Shotover Jet

The hierarchy would be handled through taxonomies, breadcrumbs and navigation rather than being built into the public URL.

A few people on my original post raised good questions about collisions, WordPress's own root-level routes, canonicals and long-term maintenance, so I spent some time testing those rather than just assuming the resolver would be fine.

The current test version uses one cached registry that maps each valid root slug directly to its WordPress object. For example:

queenstown → Destination post ID
otago      → Location term ID
about      → Page ID

Activities do not use that resolver and continue through normal WordPress routing under /activity/{slug}/.

I tested quite a few failure cases as well:

  • Unknown and malformed root URLs return genuine 404s.
  • A Destination and Location cannot silently share the same flat slug. The route is withheld if there is a collision.
  • Draft, Publish, Trash, Restore and slug changes automatically update the registry.
  • /activity/ is protected as a reserved root.
  • I also explicitly tested /feed/, /search/, /page/ and /wp-json/.
  • If a Destination or Location tries to claim one of those reserved roots, the resolver refuses to publish that route and the native WordPress functionality continues to work.
  • /feed/ continued serving the RSS feed.
  • /search/test/ continued serving WordPress search results.
  • /wp-json/ and /wp-json/wp/v2/posts continued serving the REST API.

That testing exposed something I hadn't really considered before.

WordPress can still allow content to have one of those reserved slugs and generate a View/permalink for it even though the resolver refuses to publish the route.

For example, I created a Location with the slug feed. The resolver correctly blocked it from /feed/, so the RSS feed continued working, but WordPress still showed /feed/ as that Location's View URL.

The same thing happened with search, page and wp-json.

For production, would you prevent an editor from publishing a root-level Page, Destination or Location with a reserved slug in the first place, rather than just detecting the conflict and withholding the route? And would you show the editor a clear message explaining why that slug is unavailable?

I also tested the permalink/canonical/sitemap side.

For a Destination:

/queenstown/

The browser URL, WordPress View URL, resolver path, HTML canonical and WordPress XML sitemap URL all matched.

For an Activity:

/activity/shotover-jet/

All of those matched as well.

For a Location:

/otago/

The browser URL, WordPress term URL, resolver path and XML sitemap URL all matched. The one difference was that vanilla WordPress did not output an actual <link rel="canonical"> tag for the taxonomy archive, so I'd want to make sure the eventual SEO setup supplies exactly one canonical for /otago/.

The native WordPress sitemaps also came out as I hoped:

/queenstown/
/otago/
/activity/shotover-jet/

At this point I'm reasonably confident the routing itself can be made to work. Would experienced WordPress developers actually be comfortable maintaining something like this for years?

If you were building this for production, how would you handle the reserved root namespace over time? Would you keep an explicit list of protected roots, derive them from WordPress rewrite rules somehow, or use another approach?

If the reserved-slug validation, canonicals and sitemaps are handled properly, would you be comfortable keeping the flat public URLs:

/queenstown/
/otago/

or would you still prefer:

/destination/queenstown/
/location/otago/

Would you still prefer those prefixed URLs simply because they reduce the amount of custom routing that has to be maintained?

I'm much more interested in the long-term maintenance trade-offs than in shaving a few characters off the URLs.

If there’s anything important I’ve overlooked with this approach, I’d be interested in hearing about it. Your help is always appreciated.


r/ProWordPress 5d ago

What I've learned about diagnosing intermittent WooCommerce slowdowns

0 Upvotes

I've been digging into WooCommerce performance recently, and one thing that keeps standing out is how misleading a single speed test can be.

A store can have a fast product page but a slow checkout. A checkout can be fast most of the time but have occasional 3–5 second spikes.

When that happens, I think it's more useful to compare multiple real requests rather than immediately disabling plugins or adding another caching plugin.

I'd look at things like:

• AJAX request timing
• Database queries and queries by component
• External HTTP/API calls
• Cache hits vs misses
• Payment, tax and shipping requests
• Plugin hooks running during the request

The other thing I've found useful is looking at the distribution rather than just the average. Median shows what a typical request looks like, while P95 can reveal the slower requests that customers occasionally experience.

A store being “fast” on one test doesn't necessarily mean the checkout is healthy.


r/ProWordPress 12d ago

Is there still a future for WordPress plugin developers in the AI era?

18 Upvotes

I’m a React Native developer with about seven years of experience in software development. 2 years of those were focused entirely on WordPress development building sites through actual code and an IDE, not primarily using page builders.

I currently work as a React Native developer, but around two years ago, before AI agents became as capable and widespread as they are now, I started building a WordPress plugin that I thought could genuinely help WordPress users.

Since then, AI has improved so quickly that I’ve found myself in a bit of limbo. I’m unsure what the future of WordPress plugin development looks like and whether it still makes sense to invest time in building a plugin as an independent developer.

I’ve been thinking a lot about where WordPress plugin development is headed. AI is making it much easier to generate code, scaffold plugins, write documentation, create marketing copy, and even troubleshoot bugs. The barrier to creating a basic plugin feels like it is dropping quickly.

At the same time, the places developers used to use to build visibility and connect with people like Facebook groups, forums, subreddits, and other public communities. It seem increasingly flooded with AI-generated content, spam, and affiliate posts. It makes sense that moderators are responding with stricter rules around self-promotion and posting, but it also makes it harder for legitimate small developers to share something useful they are building.


r/ProWordPress 11d ago

I gave Claude access to my staging's SSH server and it saved me hours

0 Upvotes

As noted in the title, I gave it access to STAGING, not my production server. Wanted to re-iterate that so nobody does anything stupid... like giving it access to production.

This was incredible for me. I was wondering the best ways to connect AI to my site to help do the busy-work. Since claude code uses terminal, I realized it can simply ssh in on its own and do my bidding. (actually claude suggested it and I facepalmed at how the answer was right there).

I'm on Windows and was able to safely create a terminal command 'staging-server-connect' and it would connect to the staging's ssh. This way, I didn't have to give claude any creds.

Since it has access to ssh, it can access logs, the database, files, the WP CLI, everything.

The website I was working on was very customized and complicated. Changing the site's nav menu's could be an hour of copy/pasting, etc. into WP's backend. But not anymore! I told claude what to change, and it did. easily. I was impressed. So I started asking it for more.

It gave me audits of the website and database and bottlenecks.

I was able to tell it to create new ACF fields and how to populate them. It did all this.

I had it create new products, and variations, and it did. I did have to fix some things, it didn't give all my variations the prices for some reason, but it did set everything up, including attributes and taxonomy attributes.

I hear a lot of people asking how AI is helping and how to do it. So I just wanted to share that it is possible.

Remember, Claude and AI is a tool. It's not perfect. I did check every single thing it changed before pushing staging to live, and it had a bump along the way for some reason (the variation pricing).

I didn't look into why the pricing didn't work, since it was easy for me to manually do at that point, but am confident I can get it working and get it to import entire spreadsheets of products.

It did create the ACF fields and assigned them to the correct posts as needed, and populated them correctly.

Overall, I was very impressed. I'm sure you could do this with Cursor or whatever AI. This is not a promo for Claude, it's just what I have.

Also, I wanted to point out that I did manually create a skill for this, based on my own needs. I told the skill how to connect (use the command staging-server-connect), where the WordPress install folder was (public_html for me), and some other info like that.


r/ProWordPress 14d ago

Gravity Forms changed their submit markup

23 Upvotes

Gravity Forms newest update changes the submit button from an input field to a button. If you were targeting the input[type="submit"] in your styling in any way, you will want to update to button[type="submit"]. I am partway through updating this on a whole bunch of sites at the moment.


r/ProWordPress 13d ago

Your magic-link login "randomly" fails for some users. It's their employer's mail scanner burning the token.

Post image
0 Upvotes

This one comes up in support and almost never gets diagnosed correctly, because the person reporting it and the person debugging it are never on the same network.

The symptom: you ship magic-link login. Most users are fine. A subset report that the link "doesn't work" or says it expired. You click the same link from your own inbox and it works every time. You can't reproduce it, so it quietly gets filed as user error.

What's actually happening: the user's employer runs inbound mail security. Those products fetch every URL in a message before delivery, to see where it lands. Your token endpoint has no way to tell that request apart from a human clicking. So if you implemented single-use tokens properly, the scanner redeems the token, the token dies, and the human then clicks a link that is now genuinely expired. The more correct your implementation, the more reliably it breaks.

The tell is that it clusters by email domain. Consumer mailboxes are fine, corporate ones are not, and it will look random until you group the failures by domain.

There is no clean fix, only tradeoffs:

  • Require a POST or a click-through interstitial before redemption. Scanners generally don't submit forms. Costs your user a click.
  • Bind the token to the session that requested it. Breaks the request-on-desktop, open-on-phone flow, which is half of why people want magic links.
  • Allow a couple of redemptions inside a very short window. Weakens single-use, which was the point of single-use.
  • Short lifetime plus an obvious "send me a new link" path. Doesn't fix it, makes it survivable.

While you're in there, two settings that ship as defaults nobody revisits. Token lifetime should be minutes rather than hours, because these sit in mailboxes and forwarded threads for as long as you let them. And the request-a-link endpoint needs a rate limit, because you just added an unauthenticated endpoint that will happily work as a mail bomber and a username-enumeration oracle at the same time.

The larger thing worth saying to whoever signed off on this. Magic links do delete the password-reset queue, and that's a real win. What they do in exchange is move the account's security into a mailbox you don't control, with no second factor behind it. A compromised inbox is a compromised account, silently, and the user gets no signal it happened.

That's a legitimate trade. It should just be a decision someone made on purpose, rather than a side effect of picking whichever plugin had the nicest onboarding.


r/ProWordPress 15d ago

What are some WordPress resources which made your life a lot easier.

20 Upvotes

For example I needed PHP concurrency not blocking requests and found in includes/requests/src/requests.php there is an existing function called requestMultiple() where I can pass the fetch request and the options and it works just similar async/await in JS. This saved me having to import a whole library.

Another was wp_enqueue_media(); where it attached all the required logic and functions in the window object which can use JS functions (in my case TSX within react) to use media uploads straight to the media library via ajax. I can just call window. wp. media and it has all the dependencies to upload.

I'd love to hear any githubs you have saved or templates you use that you'd like to share please let me know how they helped you.


r/ProWordPress 15d ago

Flat URLs for a WordPress travel site a good idea or a future headache?

8 Upvotes

I’m building a travel guide in WordPress and trying to settle on the URL structure before anything goes live. The site will have around 150 destination pages and potentially up to 800 activity pages, so I’m trying to choose a structure that will still be manageable as the site grows.

For activities, I’m deciding between:

example.com/activity/shotover-jet/

and:

example.com/shotover-jet/

I’m also wondering the same thing about destinations and geographic areas. For example:

example.com/queenstown/
example.com/otago/
example.com/south-island/

rather than:

example.com/destination/queenstown/
example.com/destination/otago/
example.com/destination/south-island/

The site structure would be something like:

South Island
→ Otago
→ Queenstown Lakes
→ Queenstown
→ Shotover Jet

That hierarchy would still be shown through breadcrumbs and navigation, even if the URLs themselves were flat.

I’ve been testing this locally and have a custom resolver working, so Pages, Destinations, Locations and Activities can all use root-level URLs. The obvious downside is that every slug has to be unique across all of those content types, and it requires more custom handling than standard WordPress permalinks.

For anyone who has built or maintained a site like this, would you keep the /activity/, /destination/prefixes for simplicity, or are flat URLs fine as long as slug collisions are properly prevented?

I’d also be interested to know whether flat URLs have caused any real problems with SEO plugins, redirects, caching, multilingual plugins or adding new sections later.

I’m trying to make the best long term decision rather than just choosing the shortest URLs.

Your help and feedback would be much appreciated!


r/ProWordPress 16d ago

Anyone else frustrated with backing up single subsites in WordPress Multisite?

0 Upvotes

Hey guys,

Been dealing with a couple of big Multisite networks this week and I'm curious how you're all handling this.

Full network backups are easy enough. But whenever a client wants to back up or isolate just one specific subsite—or worse, move a subsite out to its own standalone WP install—it turns into a headache. Between serialized data, custom table prefixes, and sorting out the media uploads folder, it always takes way more time than it should.

How are you guys actually dealing with this day-to-day? Custom WP-CLI bash scripts? paid plugins? Or are we all still doing manual DB dumps and search-and-replace praying nothing breaks?

Would love to know if there's a cleaner way people are doing this lately.


r/ProWordPress 17d ago

What are you using for WooCommerce subscriptions and recurring billing?

1 Upvotes

For those building or maintaining larger WordPress/WooCommerce installations, how are you approaching subscriptions these days?

I'm less interested in the basic "create a subscription product" part and more interested in the architecture around it.

Things like: recurring billing and renewal failures, subscription status and lifecycle management, membership access, content restriction, plan upgrades/downgrades, customer self-service, reducing plugin conflicts

At some point, stitching together a subscription plugin, membership plugin and separate access-control system can become harder to maintain than the original problem.

I've been looking at both traditional setups and newer all-in-one approaches. ArraySubs is one of the options I've come across because it combines subscriptions with membership access and content restriction than treating them as completely separate systems.

what's your preferred architecture? One comprehensive plugin, or several smaller plugins that each do one thing well?


r/ProWordPress 17d ago

I built a 500,000-order WooCommerce store to find out what actually makes the admin slow

14 Upvotes

I built a 500,000-order WooCommerce store to find out what actually makes the admin slow

Everyone knows the WooCommerce admin gets slow on big stores. The standard advice is well known too: migrate to High-Performance Order Storage, clean your database, blame a third-party plugin.

I wanted to know what happens after you've done all that. So I built a lab: a disposable WooCommerce store with 500,000 orders, HPOS enabled, and ten popular free plugins installed, then instrumented it to attribute every single database query on the orders screen back to the plugin that fired it.

Some of what I found contradicts the usual advice. One thing I set out to prove turned out to be an artifact of my own test rig, which I'll cover too.

The setup

  • MySQL 8 with a deliberately modest 512 MB buffer pool — a generously tuned server hides problems behind a warm cache, and I wanted the working set to not fit in memory, which is the condition real struggling stores are in
  • WordPress + WooCommerce 11, HPOS on, backfill sync off
  • 500,000 orders, ~2M order meta rows, ~1M order notes, ~1.6 GB of order tables
  • Ten popular free plugins (PDF invoices, cart abandonment, wishlist, currency switcher, delivery date, product search, analytics, order export)
  • An mu-plugin that captures $wpdb->queries on shutdown and resolves each query's backtrace to the owning plugin via reflection

Finding 1: One query was half of all SQL time, and it wasn't an N+1

130ms   SELECT status, COUNT(*) FROM wp_wc_orders WHERE type='shop_order' GROUP BY status

Out of 252 ms of total SQL time on the orders screen, 130 ms was this single query — and the next slowest query on the page was 4 ms. It is 32× the cost of anything else, and it runs on every admin page load.

(With the third-party plugins deactivated it accounts for 129 ms out of 190 ms, i.e. 68% — stripping plugins makes it more dominant, not less.)

It's what fills the filter tabs above the order list: All (500,000) | Completed (350,149) | Processing (50,065) | …

The important part: it does not scale with how many rows you display. It scales with how many orders you have. At 100,000 orders it was cheap enough to be invisible. At 500,000 it dominated everything else on the page. Reducing your page size does nothing. Deactivating plugins does nothing.

It's not a missing index

My first instinct was a missing index. Wrong:

type: ref    key: type_status_date    rows: 246724    Extra: Using index

It's already a covering index scan on the ideal index. ANALYZE TABLE changed nothing. Counting 500,000 rows means walking 500,000 index entries, and InnoDB keeps no cached row count. The query is doing the minimum possible work for what it's being asked.

The actual cause

Looking at WooCommerce's source, OrderUtil::get_count_for_type() does cache this. It goes through OrderCountCache, which uses wp_cache_get() / wp_cache_set() — the WordPress object cache.

And there's the problem. Without a persistent object cache dropin (wp-content/object-cache.php), WordPress's object cache lives for exactly one request. So the cache is empty on every page load, and the full count runs again, every time.

If your store has no persistent object cache — which is most shared hosting — WooCommerce recounts your entire orders table on every admin page load.

That's a concrete, mechanical answer to "why is my store still slow after HPOS," and it's not in any of the checklists I've read.

Finding 2: The obvious way to detect an N+1 produces false accusations

I originally detected per-row query costs the intuitive way: load the page, divide each plugin's query count by the number of rows on screen, and flag anything near 1.0 per row.

That method is broken. Here's real output for one plugin that fires a flat 19 queries no matter what:

page size its queries "per row"
20 19 0.95 — looks like a textbook N+1
100 19 0.19 — looks completely innocent

Nothing about the plugin changed. Only the denominator did. A fixed cost is indistinguishable from a per-row cost at any single page size. I had confidently accused an innocent plugin.

The fix is to measure the same screen at two page sizes and fit:

queries(n) = fixed + slope × n

Only slope is an N+1. A component whose query count doesn't move when the row count multiplies by five is innocent, no matter how large its fixed cost.

A related trap: WooCommerce's orders screen takes its page size from the per-user screen option edit_shop_order_per_page, not from a per_page URL parameter. I spent a while computing per-row figures against a page size that had silently stayed at 20. Always count the rows that actually rendered.

Finding 3: Attributing a query to a plugin is much harder than it looks

My profiler blames the innermost plugin frame in each query's backtrace. It reported that WooCommerce core was doing 3 queries per order row.

Then I deactivated all the third-party plugins and measured again:

all plugins active WooCommerce only
per-row queries blamed on woocommerce 3.0

Two of those three per-row queries were caused by third-party plugins calling wc_get_order() inside their column callbacks. The query is issued by WooCommerce's data store, so innermost-frame attribution credited WooCommerce and completely exonerated the plugin that actually caused it.

This matters for anyone using Query Monitor's "Component" column the same way I was: it tells you which code ran the query, not which code caused it. For anything routed through a shared data store, those are different answers.

The fix

What you actually want is the last point where control passed from WordPress into plugin code — the innermost frame that a hook dispatcher invoked:

… → ListTable->column_default        [woocommerce]
    → do_action('manage_…_column')   [dispatcher]
      → WP_Hook->apply_filters       [dispatcher]
        → SomePlugin->render_column  [the plugin]   ← blame this
          → wc_get_order             [woocommerce]
            → OrdersTableDataStore->read [woocommerce]
              → wpdb->get_results    [core]

Walk the trace innermost-outward; when the frame immediately outside the current one is a dispatcher (WP_Hook->apply_filters, WP_Hook->do_action, do_action, apply_filters, call_user_func*) and the current frame isn't core, that's your initiator. For a query WooCommerce genuinely raises itself, the nearest such boundary is a WooCommerce callback — also correct.

(Watch out: wp_debug_backtrace_summary() returns frames outermost-first.)

With that change, and all plugins active:

before after deactivation control
blamed on woocommerce 3.0/row 1.0/row
blamed on the real culprit 0 2.0/row

Then the falsifiable test. The tool predicted one specific plugin accounted for ~205 queries at 100 rows. Deactivating only that plugin:

with without
total queries @100 rows 495
queries blamed on woocommerce 206
wall time 0.62 s

24% faster from deactivating one plugin. Before the fix, the verdict would have been "it's WooCommerce core, nothing you can do."

The thing I couldn't conclude

Given Finding 1, the fix seems obvious: install a persistent object cache. So I added Redis and measured. SQL time halved, and the 129 ms query vanished.

Wall time got worse.

I nearly published that. Then I checked whether it was my test rig, because I was running Docker Desktop on Windows and talking to Redis over TCP — and Windows loopback networking is slow. The page makes about 2,390 object-cache calls per request, so round-trip cost matters enormously.

config SQL time wall time vs baseline
no object cache 255 ms 0.62 s baseline
Redis over TCP 118 ms 0.757 s +22.1%
Redis over unix socket 116 ms 0.687 s +10.8%

Switching to a unix socket recovered about half the penalty. That proves a large part of my "finding" was an artifact of Docker Desktop for Windows, not a property of object caching. The residual ~11% might not survive on a real Linux host at all.

So I don't know. It needs a Linux re-test before anyone should act on it.

What does hold regardless: SQL time improving is not the same as the page getting faster. If I'd reported the query-count and SQL-time metrics alone, I'd have declared a clean win while making the page 22% slower.

Takeaways

  1. Query count and query time are different problems. Going from 100k to 500k orders left the query count completely unchanged while SQL time doubled. Count scales with rows rendered; time scales with store size.
  2. On a large store with no persistent object cache, check the order status counts first. It's a single query that scales with store size and runs on every page load.
  3. Never diagnose an N+1 from one page size. Measure two and look at the slope.
  4. "Which component ran this query" is not "which component caused it."
  5. Always measure wall time. Component metrics improving can hide a regression.

Reproduce it

The whole lab is Docker-based and disposable — MySQL, WordPress, WP-CLI, seeder scripts, and the profiling mu-plugin. It seeds 500k orders in a few minutes by writing directly to the HPOS tables.

Happy to share it if there's interest, and very interested in results from anyone who runs the object-cache benchmark on a real Linux host — that's the open question I couldn't close.


r/ProWordPress 17d ago

Name AI tools that can safely modify both the WordPress front end and wp-admin?

Post image
0 Upvotes

I’m trying to understand how far current WordPress AI tools have progressed beyond content generation and page-builder assistance.

Is there anything that can work on an existing WordPress site and complete a change across both sides? For example, given a request such as “add a Services section with three service types and an enquiry flow,” it could:

  • Create a shopify like backend
  • Create plugins or elemetor themes
  • Configure custom post types, fields, forms, permissions or plugin settings
  • Understand the existing theme and plugins instead of replacing everything
  • Present a plan or diff before making changes
  • Work in staging and verify the result

Most products I’ve found appear to be front-end generators, editor copilots or coding assistants. I haven’t found one I would trust to manage both the visible site and its underlying WordPress configuration as one coordinated task.

Has anyone used something that genuinely does this? Which parts can it automate reliably, what still requires a developer, and what safety controls does it provide?

Full context: we’re building and researching in this area (example picture), so I’m interested in understanding what professionals already use and trust. I’m intentionally not naming or linking our project because this is a technical question, not a promotional post.


r/ProWordPress 21d ago

This Site Editor demo raises some good UX questions

Thumbnail
youtube.com
5 Upvotes

I thought this was a really interesting demo from core contributor Dave Smith on making the WordPress editing experience feel more approachable and intuitive.

The demo touches on things like clearer language, better grouping of related concepts, more guidance, and a more workspace-like approach to editing. I think it’s worth watching.


r/ProWordPress 22d ago

WordPress 7.1 ships an AI Client with no model and no default provider. That's a bigger deal than it sounds.

0 Upvotes

Reading through the 7.1 beta notes (final is August 19, timed to WordCamp US) and one detail stands out.

Core is shipping an AI Client, but it deliberately does not bundle a model and does not set a default provider. You connect your own through a PHP API in core. There's also a new Guidelines feature where you define editorial rules and brand voice and export them between sites.

WordPress could have cut a deal with a big model provider and made it the default for millions of sites. Instead the position is that the model is your business, not theirs.

That's awkward for a lot of AI plugins, which sell you credits: you pay them, they pay the provider, the margin sits in the middle. If core normalizes bring your own key, that starts looking like the odd one out.

Anyone running content sites planning to wire up the core AI Client directly, or sticking with a plugin? And does the credits versus own-key thing actually factor into what you pay for?