What is the best practice regarding calling flush() method of Doctrine?

You are correct that to call flush() on every instance of persist() would be considered an anti-pattern[1], however you need to think more broadly in the terms of Unit of Work:

Single Persist to Flush situations: Sometimes this work unit is simply a single persist statement — such as creating a user, and then you’re done with that work, and on to something completely different. In those cases, yes, you’ll call flush() immediately after persist.

Multiple Persists to Flush situations: Waiting to call flush() comes into play when we’re talking about a unit of work containing multiple tasks. For example, I might create a new company which results in new objects and created database updates for the company table, contact table, and perhaps a few other, all related to the “work” of adding a new company to the CRM. When persisted those objects become available (in memory so to speak) but have not yet been committed to the database. When you flush() it will now persist everything to the database (or in the terms of doctrine, they become synced with the database).

Minimum Flush Interval: Doctrine says you should have 0-2 flush() for a HTTP request — meaning that you shouldn’t be flushing multiple times per HTTP request, because, conceptually, a single HTTP request consists of a single unit of work. And it should succeed or fail as a “unit”.

It can be dangerous to decuple your flush from a single HTTP request because that means that you have persisted data, that is currently available in the ORM, but it can get lost if it is never flushed at a later point.

Overlapping Work: While I cannot think of a specific situation it seems like you might be implying that you’ve got more than one bit of overlapping work being performed, so you only want to flush certain work but not others. That would present a problem for the approach of a global flush. But it can be dangerous to have unflushed data at the end of a specific HTTP request (or perhaps even outside of a function/class). I would imagine that what you’re describing would be the bigger anti-pattern, of leaving unflished work on the table, while beginning a new task.

[1] Official Doctrine Docs under Persisting Document – https://www.doctrine-project.org/projects/doctrine-mongodb-odm/en/latest/reference/working-with-objects.html#persisting-documents