WordPress site freezes when sending FCM notifications to large topics via wp_remote_post()

4 weeks ago 23
ARTICLE AD BOX

I'm developing a WordPress plugin that sends push notifications via Firebase Cloud Messaging (FCM v1 API). The plugin works perfectly when sending to small topics (1-2 devices), but causes the entire site to freeze for 4-5 minutes when sending to a topic with hundreds of subscribers.

Environment

WordPress: 6.9

PHP: 8.x

Server: Shared hosting (cPanel)

FCM API: HTTP v1

Small topic (1 device, for testing):

Response time: ~600ms

Site remains responsive

No issues

Large topic "all" (hundreds of devices, prod):

Site freezes for 4-5 minutes

CPU usage: 96-100% (normally ~20%)

Memory: 1.2GB (normally ~400MB)

No PHP errors in logs

Current Implementation

AJAX Handler

public function handleAjaxSendNotification() { check_ajax_referer('send_notification_' . $_POST['post_id'], 'nonce'); if (!current_user_can('edit_posts')) { wp_send_json_error('Insufficient permissions'); return; } $post_id = intval($_POST['post_id']); $post = get_post($post_id); $notification_data = array( 'post_id' => $post_id, 'title' => $post->post_title, 'body' => $this->generateExcerpt($post->post_content), 'topic' => 'all', // ← Freezes with this topic 'type' => 'article' ); $result = $this->sendNotificationToFCM($notification_data); if ($result) { wp_send_json_success('Notification sent!'); } else { wp_send_json_error('Error sending notification'); } }

FCM Request

private function sendNotificationToFCM($data) { $settings = get_option('my_plugin_settings'); $access_token = $this->getAccessToken($settings['service_account']); // ~45ms $message = array( 'message' => array( 'topic' => $data['topic'], 'notification' => array( 'title' => $data['title'], 'body' => $data['body'] ), 'data' => array( 'post_id' => (string)$data['post_id'], 'type' => $data['type'] ) ) ); $response = wp_remote_post( "https://fcm.googleapis.com/v1/projects/{$settings['project_id']}/messages:send", array( 'headers' => array( 'Authorization' => 'Bearer ' . $access_token, 'Content-Type' => 'application/json' ), 'timeout' => 5, 'body' => wp_json_encode($message) ) ); if (is_wp_error($response)) { error_log("FCM Error: " . $response->get_error_message()); return false; } $response_code = wp_remote_retrieve_response_code($response); return $response_code === 200; }

What I've Observed

Token generation is fast (~45ms) - not the bottleneck

The freeze occurs during wp_remote_post()

Topic size is the key factor:

1 device: Fast

Hundreds of devices: Freeze

Server resources spike during the freeze

No PHP errors - the code works, it's just slow

Questions

Why does FCM topic size affect WordPress performance?

Does FCM take longer to process large topics server-side?

Is PHP waiting for FCM to finish processing all devices?

Is wp_remote_post() the right approach for this?

Should I use 'blocking' => false to prevent waiting?

Would native curl with timeout settings work better?

What's the recommended pattern for fire-and-forget HTTP requests in WordPress?

Queue system (WP Background Processing)?

External service/webhook?

Different HTTP client?

Could this be a hosting limitation?

Shared hosting timeout restrictions?

PHP-FPM configuration?

I expect the AJAX request to return quickly (~1 second) regardless of topic size, since I'm just sending one HTTP request to FCM. FCM should handle the fan-out to devices asynchronously on their end.

Read Entire Article