JuMP solve_time not matching actual time

I am executing an algorithm that iteratively executes the following function to solve a problem:

function solve_subproblem(model, z, q, v)
    fix.(model[:z_copy], z)
    fix.(model[:q_copy], q)
    fix.(model[:v_copy], v)
    optimize!(model)
    is_solved_and_feasible(model; dual = true)
    return (
        obj = objective_value(model),
        solve_time = solve_time(model),
        z_rc = reduced_cost.(model[:z_copy]),
        q_rc = reduced_cost.(model[:q_copy]),
        v_rc = reduced_cost.(model[:v_copy]),
    )
end

Every iteration the values of z, q, v are different, and the model is always the same one.
I have noticed that the first iteration, the optimize!() call takes significantly longer and that is not reflected when quering it with solve_time(model). I have read that it may be related to how Gurobi updates the model, but I do not know if this extra time in the first iteration can be reduced.
I am running Julia 1.10, using JuMP v1.23.5 and Gurobi v1.6.0

solve_time reports the time spent inside the solver, as measured by the solver itself.

The total time in optimize! may be longer, for example, if we need to copy the problem from JuMP into the solver, perform any reformulations, etc.

There’s also some Julia compilation latency on the first solve. Try updating to Gurobi.jl v1.7.0. I pushed a few changes recently that might make the latency smaller.

is_solved_and_feasible(model; dual = true)

Unrelated, but this isn’t doing what you think it is doing. It’s just returning true or false. But if false, nothing happens.

JuMP v1.24.0 introduces assert_is_solved_and_feasible(model; dual = true), which will error if the return is false.

I upgraded the packages and the first optimize!() does not seem faster. Is there a way of pre-process the elements that apparently only happen during the first call (e.g., copy the problem from JuMP into the solver, etc.)?
In the following iterations the durations of optimize!() and solve_time(model) are nearly identical.

*true: is_solved_and_feasible(model; dual = true) is useless in this case.

How much longer is the first call?

Why is it a problem if solve_time does not match the time spent in optimize!?

You can remove the overhead of JuMP copying the problem by using direct mode: Models · JuMP

model = direct_model(Gurobi.Optimizer())