Skip to content

Default API request timeout of 60s can exhaust PHP-FPM workers; consider lowering it #861

Description

@alewolf

Summary

The SDK issues every API request with a 60s timeout (and a 10s connect timeout) in Freemius_Api_WordPress::MakeStaticRequest() (includes/sdk/FreemiusWordPress.php):

$pWPRemoteArgs = array(
    'method'           => strtoupper( $pMethod ),
    'connect_timeout'  => 10,
    'timeout'          => 60,
    ...
);

On hosts with a small PHP-FPM worker pool, if api.freemius.com is slow or unreachable, these synchronous (blocking) wp_remote_request calls can each hold a PHP worker for up to 60s. Background calls that run unattended (the plugin update check via pre_set_site_transient_update_plugins, and the daily data_sync cron) then accumulate stuck workers and can exhaust the pool. The result is wp-admin returning 503 Service Unavailable, while the (full-page-cached) front end keeps working.

This is amplified by the fact that a non-404 API error is not negatively cached: FS_Api::get() returns without caching on error (includes/class-fs-api.php), so subsequent requests re-attempt the slow call instead of backing off.

Why 60s seems too high for today's environment

In normal operation the API responds in well under a second. A 60s ceiling only matters in pathological cases, and in exactly those cases it is actively harmful: it turns a slow upstream into site-wide admin worker exhaustion. A few seconds of slack is plenty for a healthy request.

Suggestion

  • Lower the default request timeout to something sane, e.g. 10 to 20 seconds.
  • Ideally differentiate: a short timeout for background / idempotent GETs (update checks, sync cron) versus a longer one only for user-initiated POSTs (activation, opt-in, large syncs), where a human is waiting and a slower response is tolerable.
  • And/or make the timeout filterable, e.g. apply_filters( 'fs_api_request_timeout', $timeout, $method, $canonized_path ), so integrators can tune it without patching the vendored SDK.
  • Consider briefly negative-caching transient API failures so a degraded api.freemius.com is not retried on every request.

Observed

WordPress 7.0, a plugin bundling the SDK, managed host with a small FPM pool: admin returned 503 while the cached front end stayed up; deactivating the plugin (which removes the SDK) immediately restored the admin.

References

  • includes/sdk/FreemiusWordPress.php - MakeStaticRequest(), 'connect_timeout' => 10, 'timeout' => 60
  • includes/class-fs-api.php - get(): the non-404 error path returns without caching

Happy to open a PR if you are open to a direction here.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions