• Resolved Pallieter

    (@pallieter)


    While profiling a WooCommerce site we traced a significant database write load to Mollie Forms 2.9.3. Every single front-end page view issues an UPDATE against the wp_options row for rewrite_rules — on our site a 47.4 KB autoloaded value containing 449 rules.

    **Cause**

    classes/Webhook.php line 28:

    php<br><br>add_action('init', &#091;$this, 'addEndpoint'], 0);<br><br>

    and lines 55–60:

    php<br><br>public function addEndpoint()<br><br>{<br><br>    add_rewrite_rule('^rfmp-webhook/(&#091;0-9]+)/first/(&#091;0-9]+)/?', '…', 'top');<br><br>    add_rewrite_rule('^rfmp-webhook/(&#091;0-9]+)/sub/(&#091;0-9]+)/?',   '…', 'top');<br><br>    add_rewrite_rule('^rfmp-webhook/(&#091;0-9]+)/?',                '…', 'top');<br><br>    flush_rewrite_rules();<br><br>}<br><br>

    flush_rewrite_rules() is called unconditionally inside a method hooked to init, so it runs on **every request**, regenerating and re-saving all rewrite rules each time. The WordPress documentation is explicit that this is an expensive operation which should only run on activation or deactivation.

    The method's own docblock is already marked @deprecated, but it is still registered on init at priority 0.

    **Impact**

    - One UPDATE of a large autoloaded option on every page load, including anonymous visitors who are only reading.

    - Under concurrency, requests serialise on that row while each holds a PHP-FPM worker, which contributes materially to pool saturation on busy sites.

    - We measured roughly 48 write queries per front-end page view; deactivating Mollie Forms removed the rewrite_rules UPDATE entirely and approximately halved writes per request. Reactivating restored the behaviour.

    **Suggested fix**

    Register the rules on init, but flush only on activation:

    php<br><br>// on init — register only<br><br>public function addEndpoint()<br><br>{<br><br>    add_rewrite_rule('^rfmp-webhook/(&#091;0-9]+)/first/(&#091;0-9]+)/?', '…', 'top');<br><br>    add_rewrite_rule('^rfmp-webhook/(&#091;0-9]+)/sub/(&#091;0-9]+)/?',   '…', 'top');<br><br>    add_rewrite_rule('^rfmp-webhook/(&#091;0-9]+)/?',                '…', 'top');<br><br>}<br><br>// once, at activation<br><br>register_activation_hook( __FILE__, function () {<br><br>    ( new Webhook() )->addEndpoint();<br><br>    flush_rewrite_rules();<br><br>} );<br><br>

    A version-stamped guard is a reasonable alternative if a flush is needed after upgrades:

    php<br><br>if ( get_option( 'rfmp_rewrite_version' ) !== RFMP_VERSION ) {<br><br>    flush_rewrite_rules();<br><br>    update_option( 'rfmp_rewrite_version', RFMP_VERSION );<br><br>}<br><br>

    **Environment**

    WordPress 7.0.2 · WooCommerce 10.9.4 · Mollie Forms 2.9.3 · PHP 8.4 · MariaDB · Divi 5.9.0 · also running TranslatePress (two locales), which enlarges the rewrite-rules set.

    Happy to test a patch.
Viewing 1 replies (of 1 total)
Viewing 1 replies (of 1 total)

You must be logged in to reply to this topic.