A while ago I used Gurobi and I added user cuts from within a callback. However, I got the feeling that my user cuts were not directly added to the model. Is it right that Gurobi can decide to postpone adding my inequalities? If yes, is there a way to force Gurobi to immediately add them?
Assuming you are using more than a single thread, then Gurobi performs all work you code in the callbacks with a single thread. All remaining threads process the branch and bound nodes (without doing the callbacks). When your user cuts are added is then determined by some black box magic of Gurobi.
To be specific, suppose we have 4 threads. Then, 3 of the threads are processing branch&bound nodes. If a particular branch&bound node is processed and there are valid inequalities (i.e. user cuts) to be separated, it is put in a pool of such nodes. This pool is processed by the 4th thread. Now suppose that some valid inequalities are separated by this thread for some particular branch & bound node. As these processes (of processing callbacks on the one hand and branch&bounding on the other hand) are more or less independent (which is what I presume, but please correct me if I am wrong), it is left to Gurobi to when/how to add the separated inequalities.
Luckily, they are good in that. If you want more control you can use CPLEX or if you want all control I suggest you the nice framework of SCIP:)
While lazy constraints must be added each time a node is expanded at a branch-and-bound tree, a solver is not obligated to add user cuts at any point in time; it chooses when to add user cuts.
If you want Gurobi to add them immediately, you are better off adding lazy constraints. See here: https://orinanobworld.blogspot.com/2012/08/user-cuts-versus-lazy-constraints.html for more details on the differences between the two approaches (note that CPLEX and Gurobi actually implement callbacks quite differently, so the blog post won't be entirely accurate for Gurobi).