Even though a single PHP-FPM worker handles one request at a time, concurrent requests across multiple workers can race when reading and writing shared state such as database rows or files, causing lost updates or double-processing. Database-level solutions like SELECT ... FOR UPDATE (pessimistic locking) or a version column with optimistic locking prevent two requests from corrupting the same row.
For cross-process coordination outside the database, tools like flock() on a file, or a distributed lock built on Redis (SET key value NX PX ttl), ensure only one process performs a critical section at a time, which matters for tasks like processing a payment webhook exactly once.