@kitkit Each bulk update re-reads and re-indexes the whole document, so 150k updates/min is heavy on the data nodes that also serve your searches. You could consider the following on your 2.8:
Raise refresh_interval on the indices being updated while the updates run.
Send updates in smaller, steady batches, preferably off-peak.
Add more or larger data nodes, and faster storage (higher IOPS), if the cluster is still saturated.
You could also consider using search replicas; however, these are available in 3.x.
Search replicas isolate search from the update load. Dedicated search nodes serve the queries while the primaries take the updates. This needs remote-backed storage and segment replication: Separate index and search workloads | OpenSearch Documentation
one thing that jumps out is the bulk size of 10, thats very small for 150k a minute and the per request overhead will eat you alive. id try the opposite and tune by size instead, something like 5 to 10 mb per bulk with only a couple of bulk requests in flight at once, then watch for rejections and merge pressure. it wont make the updates themselves cheap since each one still reindexes the doc, but it should be a lot less wasteful than thousands of tiny requests. if the same candidate fields keep changing, moving those fields out into a separate small index is the bigger win long term.