Skip to content

fix: keep analytics from ever slowing a WordPress site - #25

Merged
ranael-garem merged 5 commits into
mainfrom
fix/analytics-never-blocks-site
Oct 2, 2026
Merged

ranael-garem merged 5 commits into
mainfrom
fix/analytics-never-blocks-site

Conversation

@ranael-garem

Copy link
Copy Markdown
Contributor

Analytics can no longer slow down or take down a merchant's WordPress site, even when our ingest is slow or down. On a fresh install the queue was off, since turning it on needed a wp-config.php constant nobody documented. So every PHP request sent one POST with WordPress's 5s timeout. If our relay got slow, that held a PHP worker for up to 5s per request and could exhaust the pool.

Changes:

  • Turn the queue on by default. Defining SUPERTAB_CONNECT_USE_WP_QUEUE as false opts out.
  • Never POST from a visitor request in queue mode. A failed buffer insert drops the event instead of falling back to an inline POST.
  • Cap the per-request POST at 1s for sites that opt out. The SDK's own 1s cap never applied, because the plugin injects WP_Http_Client.
  • Drain every 15 minutes, up to 20 batches per run, instead of hourly with 10. That raises the ceiling from 5,000 to 40,000 events an hour.
  • Stop a drain at the first failed POST, so an outage costs one batch and one timeout per run.

Review notes (delete on merge)

With these changes, a visitor request in queue mode does two queries on the plugin's own table and no network calls.

The one thing to look at: why 15 minutes and not 5. WordPress.WP.CronInterval flags WP-Cron intervals under 15 minutes, and some of these merchants may be on VIP. The cron schedule array uses a literal 15 * MINUTE_IN_SECONDS so the sniff can read it. Existing installs get their hourly schedule replaced on the next admin or cron request, tracked by a new supertab_connect_flush_interval option.

Still deliver-once. I looked at keeping rows until the relay returns a 2xx, but doing it safely means holding row locks across the HTTP call. With a nearly empty table those locks block visitor inserts, which is the exact failure this PR removes. Doing it without locks needs a claim column and a schema bump, so it's left for a follow-up.

Not covered: the billing /events POST on token-bearing requests still runs synchronously on the visitor request with the 5s default. Today that's only the small slice of requests carrying a license token. It's an SDK-level change.

🤖 Generated with Claude Code

ranael-garem and others added 5 commits October 2, 2026 11:03
With the queue off, every PHP request on an active path sends one analytics
POST. The SDK caps its own client at 1s, but the plugin injects
WP_Http_Client, so the POST ran on WordPress's 5s default. A slow relay then
held a PHP worker for up to 5s per request (and the visitor too, without
FastCGI), enough to exhaust the worker pool.

Build the per-request transport in the plugin with a dedicated 1s client.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
When the queue insert failed (for example a site updated without
reactivation, before an admin or cron request creates the table), enqueue()
fell back to a synchronous POST on the visitor request, on WordPress's 5s
default timeout. On a missing table that is every request.

Queue mode now never makes a network call on a visitor request. A failed
insert drops the event with a debug log.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The queue keeps the visitor request down to one row insert, but it only ran
when a merchant defined SUPERTAB_CONNECT_USE_WP_QUEUE, which no doc
mentions. A fresh install sent one POST per PHP request instead.

The queue is now on unless the constant is defined false.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The hourly drain sent at most 5,000 events an hour (10 batches of 500), and
the 10,000-row buffer cap drops anything beyond that without a trace. A
publisher doing about 3 PHP requests a second already loses events.

Drain every 15 minutes, the shortest WP-Cron interval the VIP coding
standard accepts, with up to 20 batches per run: 40,000 events an hour.
A schedule left at another interval by an earlier version is replaced,
tracked by a new option that uninstall removes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
During a relay outage each run claimed and lost up to 20 batches, each
waiting out a 5s timeout, holding a PHP worker for most of two minutes. The
run now stops at the first failed POST: one batch and one timeout per run,
and the remaining rows wait for the next run.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟢 Approval recommended

The implementation matches the stated reliability goals and covers the changed behavior with focused tests.

Review effort: Balanced
Findings: None

What changed in this PR

Makes analytics delivery fail-open and prevents relay latency from blocking visitor requests.

Changes:

  • Enables queued analytics by default with faster, bounded draining.
  • Adds a one-second timeout for queue opt-outs.
  • Drops events on queue failures and expands tests.
File Description
uninstall.php Removes the flush interval option.
src/​class-analytics-dispatcher.php Updates buffering, draining, failure handling, and scheduling.
src/​class-analytics-queue-table.php Updates queue documentation.
src/​class-plugin.php Defaults to queued delivery and configures opt-out transport.
src/​utils/​class-wp-http-client.php Adds configurable request timeouts.
tests/​AnalyticsDispatcherTest.php Tests queue, scheduling, and failure behavior.
tests/​PluginTest.php Tests default queueing and short timeout transport.
tests/​WPHttpClientTest.php Tests timeout configuration.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@ranael-garem
ranael-garem marked this pull request as ready for review October 2, 2026 09:38
@ranael-garem
ranael-garem merged commit 0da4338 into main Oct 2, 2026
6 checks passed
github-actions Bot pushed a commit that referenced this pull request Oct 2, 2026
## [1.3.1](v1.3.0...v1.3.1) (2026-10-02)

### Bug Fixes

* keep analytics from ever slowing a WordPress site ([#25](#25)) ([0da4338](0da4338))
@github-actions

github-actions Bot commented Oct 2, 2026

Copy link
Copy Markdown

🎉 This PR is included in version 1.3.1 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants