Hi hbk747,
Those execution times are definitely concerning, especially on a 2 vCPU setup where a few concurrent requests can lock up your entire worker pool. The "mark all read" functionality is inherently expensive because it typically needs to process read-tracking data across potentially thousands of topics and forums for a single user in one transaction. Let me walk you through a systematic approach to diagnose and resolve this.
Step 1: Identify the Exact Bottleneck
First, you'll want to pinpoint whether the slowness is coming from database queries, PHP processing, or both. Enable query logging on your database to capture the actual SQL being executed during a foro=allread request. Look specifically for:
- How many UPDATE queries are being run
- Whether there are any full table scans or missing indexes
- If the queries are running sequentially or in bulk
You can enable this in your database configuration or use a tool like MySQL Workbench to monitor queries in real-time during a test request.
Step 2: Check for Missing Indexes
The read-tracking tables likely need proper indexes on user_id, timestamp, and forum/topic identifiers. Run an EXPLAIN analysis on the queries being executed. If you see "type: ALL" or "type: INDEX" without using a covering index, that's your culprit. Work with your hosting provider or database administrator to add composite indexes on the columns used in your WHERE and JOIN clauses for these queries.
Step 3: Implement Rate Limiting and Crawler Protection
While you're optimizing the backend, you should immediately protect yourself from automated crawlers hammering this endpoint. You can:
- Add rate limiting rules in your web server (nginx/Apache) to restrict requests to
foro=allread per IP address
- Block or throttle user agents known to be aggressive crawlers
- Require authentication and add a CSRF token to the mark-all-read action to prevent automated abuse
This will buy you time while you optimize the actual functionality.
Step 4: Consider Asynchronous Processing
If the optimization doesn't bring execution time down to acceptable levels (under 2-3 seconds), consider making this operation asynchronous. Instead of processing all reads in a single request, queue the task and process it in the background using a job queue system. Return a success response to the user immediately while the actual marking happens behind the scenes.
Have you already checked the database query logs to see what's actually being executed during these requests? That would give us much more specific insight into whether this is a query efficiency issue or something else entirely.