Yoast / wordpress-seo

Yoast SEO for WordPress
https://yoast.com/wordpress/plugins/seo/
Other
1.75k stars 885 forks source link

Performance issues link_suggestions classic editor large site #15869

Closed stayallive closed 2 years ago

stayallive commented 4 years ago

Please give us a description of what happened.

When editting a post (using the classic editor) we can see that every pause in typing a request is fired of to the link_suggestions API endpoint. On our site these requests take anywhere from 15 seconds to 3 minutes and up. This means that a lot of requests are created when typing and slowing those requests even more down (because server constraints) to the point they start to time out.

image

We are hosted on https://servebolt.com/ and have been told the resources for the database or PHP are not the bottleneck.

Please describe what you expected to happen and why.

I expected 1 maybe 2 link_suggestions API requests per editor instance at most and the performance of those endpoints to be quite good.

How can we reproduce this behavior?

  1. Open WordPress classic editor
  2. Type some word like foo
  3. Wat a bit for the link_suggestions API request
  4. Type some more words like foo
  5. Repeat until many link_suggestions API requests are observed

Technical info

Used versions


If the link_suggestions requests are indeed not supposed to be super fast the only issue here might be that there are many of them active at the same time. If it should be fast I'd like some pointers on how to profile/debug to find the root cause of that since I have no clue where to start digging.

Djennez commented 4 years ago

@stayallive did you run any conflict checks? It looks like other requests are taking waaaaay too long as well (looking at the _fs_admin request taking 30 seconds) so this may be unrelated to Yoast.

stayallive commented 4 years ago

Those requests are actually "blocked" by the Yoast requests.

I say this because both before and after the link_suggestions calls these come back <1s (autosave for a fairly large article) which is around what I would expect.

Before: image

After: image

It looks like which I missed the last time testing that the link_suggestions endpoint is not called anymore as soon as I wait for all the "queued" requests to finish for a little while.

Is this just a mechanism not tracking if it already fired a request? It looks like 1 active link_suggestions request should all I would be expecting at a time?

This is what happens if I stop editing as soon as I see the first request: image

As you can see if just a single link_suggestions call is active the other calls are unaffected and link_suggestions itself is a little bit faster.


_fs_blog_admin looks kinda shady but it's from the Freemius tools and according to them it's to track the origin of the admin-ajax.php calls, they just appended it to the global admin-ajax.php url instead of only their own calls.

Djennez commented 4 years ago

What responses do you receive when one of the requests finally finishes? If you install the Query Monitor plugin, what information can you find in the return headers of the request (QM adds some timing-related headers there).

Did you perform a conflict-check as well?

stayallive commented 4 years ago

I have just retested is with Yoast 14.9 and it still looks like this:

image

I just typed "a a a a a a a a a a a a a" in the editor... not much special but every a causes a identical to the one before it link_suggestions call before the other link_suggestions call is finished or cancelled. I even noticed that after typing "aaa" I have 9 requests, so sometimes it even generates multipel requests on it's own.

Example request url:

/wp-json/yoast/v1/link_suggestions?prominent_words%5Bappl%5D=19&prominent_words%5Blocatie%5D=15&prominent_words%5Bbeoordelingssysteem%5D=13&prominent_words%5Bkaart%5D=9&prominent_words%5Bkrijg%5D=9&prominent_words%5Bfoto%5D=5&prominent_words%5Buploa%5D=5&prominent_words%5Bgegevent%5D=4&prominent_words%5Bios%5D=4&object_id=1258127&object_type=post

The requests and results are all identical:

image


I did do a conflict check and I can still replicate it with these plugins active:

+------------------------+--------+-----------+---------+
| name                   | status | update    | version |
+------------------------+--------+-----------+---------+
| classic-editor         | active | none      | 1.6     |
| duplicate-post         | active | none      | 3.2.5   |
| wpseo-news             | active | none      | 12.6    |
| wordpress-seo-premium  | active | none      | 14.9    |
+------------------------+--------+-----------+---------+

I have not had the chance to install query monitor in production yet.

jphorn commented 4 years ago

Is this being actively looked at? Last night with the Apple Event we were almost unable to update and publish any article due to continuous timeouts. I'm the site owner for which this issue has been reported (@stayallive is our freelance dev). This is a huge issue for large sites and I don't really understand how this has been labeled as Severity:Minor.

Are we able to safely rollback to pre 14.7? This is affecting our editors very badly to the point they're growing increasingly frustrated with their job. Not a good look.

Djennez commented 4 years ago

Is this being actively looked at?

Nope, unfortunately we have too little information about the circumstances under which this occurs. And without a way to reproduce the issue, we can't investigate it.

Are we able to safely rollback to pre 14.7?

You may always do so, however, we don't support older versions of our plugin.

Djennez commented 3 years ago

Issue was reproduced. Internal tracker opened here.

yjwong commented 3 years ago

We are also facing this problem with Yoast Premium 15.3 on a large site. With the "Link suggestions" feature enabled, we're seeing a similar pattern as described by @stayallive, where each request takes > 15 seconds to complete. Additionally, it was tying up MySQL, causing it to consume 100% CPU usage and WordPress to be unable to serve other requests.

coolrecep commented 3 years ago

I can't believe that this is still not fixed. There are spikes on our website and the site is unable to serve.

SoyFerrer commented 3 years ago

Hello, For your awareness that that the issue is ongoing and affecting multiple sites, please note the issue is persisting on BlackBookMag.com as well.

On 12/24/2020 the CMS and website frontend both were knocked out for a few minutes. We were able to see several 504s returned by requests to "blackbookmag.com" in HTTP request logs between 20:25 UTC and 20:40 UTC. There was a pattern of those 504s being returned by requests to the Yoast REST API endpoint for "link suggestions", such as this one:

/wp-json/yoast/v1/link_suggestions?prominent_words%5Baspen%5D=7&prominent_words%5Bholiday%5D=4&prominent_words%5Bw%5D=4&prominent_words%5Bapple%5D=3&prominent_words%5Bblackbook%5D=3&prominent_words%5Bchristmas%5D=3&prominent_words%5Bskiing%5D=3&prominent_words%5Bswish%5D=3&prominent_words%5B1.5oz%5D=2&prominent_words%5Bcider%5D=2&prominent_words%5Bcocktail%5D=2&prominent_words%5Bdegrees%5D=2&prominent_words%5Bdehydrated%5D=2&prominent_words%5Bdomes%5D=2&prominent_words%5Bfeet%5D=2&prominent_words%5Bgarnish%5D=2&prominent_words%5Blounge%5D=2&prominent_words%5Bpeople%5D=2&prominent_words%5Brecipes%5D=2&prominent_words%5Bseason%5D=2&object_id=249988&object_type=post

They drop off suddenly at 20:32 UTC which is likely when the editor experienced issues accessing the site.

Hope this is useful to you. If there is an ETA on when this issue could be solved, we'd appreciate knowing as our editor is experiencing frequent "stuck Updating" issues when editing posts and we believe that issue is related to this "link suggestions" issue.

jonsnowpt commented 3 years ago

Hi!

This feature turns our website unresponsive, not sure if it is because we have more than 500.000 articles.

Leeonard commented 3 years ago

Hello I am having the same issue. The ajax functions put my server on high CPU consumption and mainly the sources are the link suggestions. This is causing spinning and limitation over a shared hosting and affecting performance of whole website. There is something I can do?

Method Duration URL
GET 0.6s siteXXX/wp-admin/admin-ajax.php?action=rest-nonce
POST 1.8s SITExxx/wp-admin/admin-ajax.php
GET 0.9s siteXXX/wp-json/yoast/v1/link_suggestions?prominent_words%5BHIDDENPRODUCTBRANDHERE%5D=10&prominent_words%5BANOTHERWORD%5D=5&prominent_words%5Bdc265sl%5D...
GET 1.2s siteXXX/wp-json/yoast/v1/link_suggestions?prominent_words%5BAWORD%5D=6&prominent_words%5BANOTHERWORD%5D=5&prominent_words%5Bdc262sl%5D=...
GET 0.4s psiteXXX/wp-admin/post.php?post=nuberofthepostid&action=edit

This other is even more performance affecting:

Method Duration URL
GET 5.7s siteXXX.com/wp-admin/admin-ajax.php?action=rest-nonce
GET 1.4s siteXXX.com/wp-json/yoast/v1/link_suggestions?prominent_words%5BWORD%5D=8&prominent_words%5BOTHERWORD%5D=7&prominent_words%5B190-230v%5D...
GET 5.8s siteXXX.com/wp-admin/admin-ajax.php?action=rest-nonce
GET 5.7s siteXXX.com/wp-admin/admin-ajax.php?action=rest-nonce
GET 2.9s siteXXX.com/wp-admin/admin-ajax.php?action=rest-nonce
POST 7.2s siteXXX.com/wp-json/wp/v2/product/53683/autosaves?_locale=user
GET 4.6s siteXXX.com/wp-admin/admin-ajax.php?action=rest-nonce
GET 3.1s siteXXX.com/wp-admin/admin-ajax.php?action=rest-nonce
GET 5.7s siteXXX.com/wp-admin/admin-ajax.php?action=rest-nonce
GET 5.7s siteXXX.com/wp-admin/admin-ajax.php?action=rest-nonce
GET 5.7s siteXXX.com/wp-admin/admin-ajax.php?action=rest-nonce
GET 3.1s siteXXX.com/wp-admin/admin-ajax.php?action=rest-nonce
Leeonard commented 3 years ago

Little update: as other commenter proposed, I tried to disable link suggestions from yoast features.

I am using PHP 8 and getting this PHP error, just to state:

Deprecated usort(): Returning bool from comparison function is deprecated, return an integer less than, equal to, or greater than zero 1 +wp-content/plugins/wordpress-seo/admin/views/class-yoast-feature-toggles.php:175 Plugin: wordpress-seo
Deprecated usort(): Returning bool from comparison function is deprecated, return an integer less than, equal to, or greater than zero 1 +wp-content/plugins/wordpress-seo/admin/views/class-yoast-integration-toggles.php:102 Plugin: wordpress-seo
coolrecep commented 3 years ago

Severity: Minor? Really? This is killing my website every hour! Wasn't this supposed to be fixed with 16.1?

image

jonsnowpt commented 3 years ago

Severity: Minor? Really? This is killing my website every hour! Wasn't this supposed to be fixed with 16.1?

image

You need to disable it.

Djennez commented 3 years ago

Wasn't this supposed to be fixed with 16.1?

Not that I know.

I am seeing this issue creep up in more places and will raise this internally.

coolrecep commented 3 years ago

Wasn't this supposed to be fixed with 16.1?

Not that I know.

I am seeing this issue creep up in more places and will raise this internally.

OK, my bad. Mistook it with the indexing issue. It was fixed with 16.1

coolrecep commented 3 years ago

This didn't make it to 16.3 right?

paulocoghi commented 3 years ago

We have an AMD EPYC 7451 with 24 cores / 48 threads almost dedicated to one Wordpress site with Yoast SEO Pro. This site receives an average of 60-100 million requests per month, with access peaks in specific hours of the day.

When no new article is being written, the processing capacity is more than enough.

But the worst part occurs when editors are working on new articles, and the queries mentioned by @jonsnowpt (which are created by YoastSEO Pro) are eating our server processing capacity, making MySQL go crazy.

See an example below:

SELECT *, ( SELECT COUNT(*) FROM wp_yoast_prominent_words WHERE wp_yoast_prominent_words.stem = prominent_words_table.stem ) AS `df` FROM `wp_yoast_prominent_words` `prominent_words_table` WHERE `indexable_id` IN ('73198', '73473', '73499', '73511', '73537', '73538', '73559', '73562', '73681', '74382', '74590', '74452', '74660', '74686', '74676', '74709', '74718', '74725', '74752', '74757', '74781', '74785', '74787', '74795', '74797', '74803', '74812', '74837', '75736', '75896', '75944', '75949', '75954', '75966', '75970', '76042', '76065', '76071', '76082', '76083', '76879', '76948', '77105', '77108', '77158', '77168', '77183', '77190', '77197', '77220', '77232', '77355', '78039', '78177', '78291', '78342', '78357', '78380', '78384', '78392', '78430', '79220', '79391', '79394', '79413', '79417', '79422', '79420', '79432', '79487', '79564', '3521', '5819', '6465', '6491', '6828', '7085', '7216', '7660', '7694', '7711', '7715', '7751', '7753', '7856', '8165', '8061', '8220', '8481', '8567', '8784', '9914', '12...

The amount of indexable_id inserted by YoastSEO is really big, and many of such queries are launched in parallel, generating a load on MYSQL processing that surpasses, many times, 300% up to 4000% of CPU usage.

We allocate much more RAM to MySQL than the size of the whole database, to ensure a better cache and performance, and we use NVMe storage only. But, even this way, MySQL is unable to handle so many SELECT COUNT(*) queries.

JoeyBol commented 3 years ago

Is this fixed in 16.4? One of my clients is starting to have more and more trouble with editing their articles on their website.

jphorn commented 3 years ago

After updating to 16.4 (since reverted) typing in Yoast's own meta boxes (specifically SEO Title and SEO Description) is unbearably slow. Like seeing every character printed one by one to the screen. I'm not sure what Team Yoast is doing, but they really need to improve their unit testing and account for sites with massive amounts of posts and attached post_meta. I just don't trust the updates anymore.

paulocoghi commented 3 years ago

A better timeout handler on Yoast will help. Instead of launching a new query in real-time, every time a new character is typed, it could reset the timer, which needs to wait at least 500ms to do a query.

This way not only it reduces the load on server because of useless queries, but it will improve the editor's experience.

stayallive commented 3 years ago

As an addendum on what @jphorn & @paulocoghi already mentioned above.

A debounce on the back-end calls that are triggered by inputs would be a great idea! Wait until the user stops with "input" (typing) for a specified amount of time (even 500ms is a great start) before firing of a new request to the back-end.

Also making sure only 1 request of a type is in-flight per page to prevent sending multiple of the same requests (of which some are already made redundant because of previous queries). Cancelling the "older" requests and replacing it with a new one would also make sense even if you already know you are going to make another back-end call for newer data because the input changed anyway. This way the data is still correct but you are only making 1 concurrent back-end request instead of 1 per character input šŸ˜„

This above seems like the bare minimum to prevent excessive load on the back-end and front-end, implementing a debounce and "cancel previous request" is also not extremely hard (jQuery, lodash and many, many others have built-in functions too achieve this) and can all be accomplished client side without changes to the back-end logic.

After that making sure the back-end call do not take this long as they do on larger sites would of course also be nice, but that doesn't matter if the front-end essentially DDoS'es the back-end with a high number of concurrent calls that all do pretty heavy database work.

paulocoghi commented 3 years ago

Implement "debouncing" on every feature provided by Yoast which provides feedback after typing would make a huge positive impact.

I would like to also improve my suggestion about the debounce time. After some analysis, I suggest 750ms as the minimum, and 1s to 1.5s as ideal.

laurent-le-graverend commented 3 years ago

Any workaround by any chance? We also have pretty large RDS databases suffering a lot from these SQL requests in Yoast Pro.

volneanschi commented 3 years ago

Got hit by the same issue after updating to the latest to date Yoast 16.6. Very high CPU load numbers on MariaDB dedicated server, 1000% and more getting Load Average to the sky, with a normal load on Web Server at the same time. APM Monitoring shows ONLY MySQL queries "dbname_yoast_prominent_words select" with tens of seconds in processing times. After turning Text Link Counter & Link suggestions off the problem just disappeared. We were using these features for years, is there anything we could do to get features back without CPUs getting fried? =)

Also, tried to reindex indexables via WP-CLI, it changed nothing.

2021-06-30 - 11 32 36
paulocoghi commented 3 years ago

It is important to understand what was added from v16.6 (maybe with a git bisect) since the same features (mainly Text Link Counter & Link suggestions) were working perfectly fine before.

ps: we are paying for the Pro version, to help the development of Yoast.

coolrecep commented 3 years ago

It'll be a year in August and still no word on a fix.

paulocoghi commented 3 years ago

@volneanschi , do you know which version was installed before your update? Because, as we can see on this thread, many users faced the same issue even before v16.6

volneanschi commented 3 years ago

Sure, it was the latest available release version before the 16.6, so, it was 16.5 or 16.5.x if there was such a version.

Djennez commented 3 years ago

16.6 was released with this PR which should have fixed some cases of slowness. However, I understand from the comments here that people are still experiencing this with 16.6 and that, in some cases, it even introduced a related issue. So this will still be an ongoing investigation.

laurent-le-graverend commented 3 years ago

Can't see this PR, the repo is private, right @Djennez ?

Djennez commented 3 years ago

Ah yes, since this is a Premium bug. Didn't realize that.

ArrayIterator commented 3 years ago

Any info?

I found select count with many words on where IN query (I also found 997 words list executed on sql query), even try to increase join_buffer or query cache disabled on database server and also improve speed with adding index on database schema (from 30 seconds or more to 7 seconds)

It still run slow cause too many query created on many requests. Make 20 Cpu Threads 90 - 100%, make sites.

SEO Premium 16.6 with Yoast 16.6.1 - got facing the issue, when hundreds thousand prominent words on database.

Maybe limit words list and or split words collection based on request will reduce cpu usage.

linuxgameconsortium commented 3 years ago

I also tried to reindex indexables via WP-CLI, it changed nothing.

jphorn commented 3 years ago

Still on 16.3 and refuse to update unless I have absolute confirmation of Team Yoast they're dedicated to investigate and solve their major performance issues affecting large sites.

webw4tcher commented 3 years ago

This function ist a performance Killer for big sites! Is where any bugfix? The SQL queries are very, very slow Very bad performance! The site is beiing hanging.

linuxgameconsortium commented 3 years ago

This function ist a performance Killer for big sites! Is where any bugfix? The SQL queries are very, very slow Very bad performance! The site is beiing hanging.

It's a huge performance hog for big sites. The SQL queries alone are exceedingly slow, to the point of maxing out the server CPU.

Djennez commented 3 years ago

The next 2 versions (after next weeks release) will see some work being done on the performance of our indexables.

laurent-le-graverend commented 3 years ago

You might want to have some tests blogs with a few hundred thousand posts and run automated tests and benchmarks against them each time you release an update šŸ™ šŸ™ šŸ™

jphorn commented 3 years ago

The next 2 versions (after next weeks release) will see some work being done on the performance of our indexables.

Will our findings with debouncing also be taken into account? Because our issues don't seem to stem from indexables but rather from your JavaScript parsing in editor fields. https://github.com/Yoast/wordpress-seo/issues/15869#issuecomment-857630792

Djennez commented 3 years ago

Will our findings with debouncing also be taken into account?

I don't believe it will be. However, I found a similar issue with our estimated reading time live updates so I will raise https://github.com/Yoast/wordpress-seo/issues/15869#issuecomment-857630792 together with that to see if those can be fixed in another sprint.

paulocoghi commented 3 years ago

@jphorn The performance issue seems to be related both from indexables, the lack of debouncing, algorithm optimization and performance regression. After the report from @volneanschi above, it is clear that a regression was made.

webw4tcher commented 3 years ago

The Problem is a missing index in prominent word table , bad joins and distinct query with very large tables over 100 in a loop. Why Distinct in Select ?

You can clear double entries mich faster in php after SQL select! The sql queries would be much faster. You can subselects instead of Joins. ;)

jphorn commented 3 years ago

Any internal performance PRs fixed in today's 16.7 release? Could you please elaborate which ones?

mossifer commented 3 years ago

Same issue here on a client site with over 25k articles. Out of memory errors, disconnecting from server. YOAST needs to address this ASAP.

Offending query on our server: SELECT DISTINCT pw.indexable_id FROM wp_yoast_prominent_words pw JOIN wp_yoast_indexable i ON pw.indexable_id = i.id WHERE pw.stem IN ('season', 'netflix', 'series', 'fantasy', 'curse', 'cancele', 'july', 'nimue', 'fan', 'power', 'character', 'debute', 'magical', 'news', 'original', 'red', 'renew', 'wait') AND i.post_status NOT IN ( 'draft', 'auto-draft', 'trash' ) OR post_status IS NULL LIMIT 100 OFFSET 6200

Djennez commented 3 years ago

Any internal performance PRs fixed in today's 16.7 release? Could you please elaborate which ones?

No related performance fixes in the 16.7 release.

Edit: there is a performance fix for larger WooCommerce sites in the free plugin (we now skip generating indexables for WooCommerce orders).

mossifer commented 3 years ago

Any internal performance PRs fixed in today's 16.7 release? Could you please elaborate which ones?

No related performance fixes in the 16.7 release.

This is unfortunate - it's crippling my client's server when our authors are editing. I hope this is a priority for your dev team. As a stop-gap, we have turned off text link counter and link suggestions and hope that helps.

ArrayIterator commented 3 years ago

Any info? after update the cpu more and more eat resource. 21 Core used!

volneanschi commented 3 years ago

Well, it looks like the one and only way to get resource usage back to normal is to turn the text link counter and link suggestions off. And, it seems, we have nothing else to do but to turn it off and wait for a solution from Yoast team.