Switching from FICO Xpress to Gurobi
Migrating an optimization application from FICO Xpress to Gurobi can be straightforward, as long as you remember to map concepts, not necessarily exact usage. The products expose similar modeling concepts, but their APIs, parameter values, default behavior, and stopping criteria are not always directly interchangeable. If you’ve used AMPL, GAMS, or another 3rd-party modeling language, you will likely have an easier time switching, perhaps even in one line of code.
As you scroll through this guide, you'll notice that most of the code snippets look very similar if you squint. This is by design, because at the end of the day we are doing the same mathematical modeling regardless of which solver it's written for.
This guide covers the main stages of a migration:
Building the model
Translating solver parameters
Optimizing and extracting solutions
Validating the migrated application
The examples focus on the Gurobi C, C++, C#, Java, and Python APIs. The exact migration path depends on whether your application uses the Xpress Optimizer API, Xpress Python, BCL, or Mosel.
Before you translate the code
Start by separating three parts of the existing application in your mind: the mathematical model; solver configuration; and surrounding application logic such as data loading, callbacks, logging, and deployment.
Migrate and validate the mathematical model before trying to reproduce Xpress performance. A parameter setting that helps Xpress may be unnecessary, or have a different effect, in Gurobi. Begin with Gurobi defaults and port only requirements that are required as part of the application, such as a time limit, accepted optimality gap, thread limit, or numerical tolerance.
Building the model
Environments and models
In the object-oriented Gurobi APIs, an environment manages shared resources and configuration, while a model represents one optimization problem. In C, the corresponding objects are created with routines such as GRBloadenv() and GRBnewmodel(). In C++, C#, and Java, they are represented by GRBEnv and GRBModel. Below (and for the rest of the guide) we'll be showing Python.
Create an explicit Python environment when you need to configure licensing or Remote Services before startup, manage cleanup, or manage separate environments in a multithreaded application. Environments (and thus license entitlements) can be tricky when attempting to rapidly open and close them for fast jobs, so be sure to review our documentation thoroughly if this is in your use case.
Adding variables
Gurobi supports continuous, binary, integer, semi-continuous, and semi-integer variables. Bounds, objective coefficients, types, and names can be supplied when a variable is created or changed later through attributes.
For indexed variables, Python offers addVars(), which returns a tupledict, and addMVar(), which provides a NumPy-compatible matrix interface. Choose the interface that best matches your data. For very large models, measure model-construction time and memory rather than assuming individual and bulk operations perform identically.
Properties such as a variable’s bounds, objective coefficient, or type are represented as attributes. For example, in Python: x.UB = 1.0. The same attribute system retrieves model statistics and solution information, so many Xpress query or modification calls translate to attribute access rather than a dedicated Gurobi method.
Adding constraints
C++, C#, and Python support operator overloading for common expressions. For example, the following Python statement represents x + y + 2z ≤ 2. In Java, build a GRBLinExpr and add terms before calling model.addConstr(). In C, specify variable indices and coefficients explicitly with GRBaddconstr(). Review quadratic, SOS, indicator, piecewise-linear, and other specialized constructs individually rather than assuming identical semantics.
Understanding lazy updates
Gurobi queues many model modifications and processes them when you call update(), optimize(), or write(). With the default UpdateMode=1, newly created variables and linear constraints can normally be used immediately while building the model. An explicit update is usually unnecessary.
You may still need update() when querying model information before optimizing or writing, copying a model with pending changes, setting attributes on SOS, quadratic, or general constraints, or when UpdateMode is 0. See the UpdateMode documentation for the current behavior.
Translating solver parameters
The following table identifies the closest Gurobi settings for commonly used Xpress controls.
Xpress control | Closest Gurobi setting | Migration guidance |
|---|---|---|
TIMELIMIT | TimeLimit | Both are wall-clock limits in seconds. Confirm whether setup time and surrounding application work are included. |
THREADS | Threads | Positive values represent thread counts in both products, but the automatic sentinel differs: Xpress uses -1 and Gurobi uses 0. |
PRESOLVE | Presolve | Setting 0 disables presolve in both products; other levels are not equivalent. |
MIPRELSTOP | MIPGap | The concepts are similar, but the formulas differ near zero and when incumbent and bound have different signs. |
MIPABSSTOP | MIPGapAbs | Both stop when the absolute difference between incumbent objective and objective bound reaches the specified tolerance. |
MIPTOL | IntFeasTol | Both define when an integer variable is considered integral. Review the value explicitly because defaults differ. |
DEFAULTALG | Method and NodeMethod | Method controls continuous models and the initial MIP relaxation; NodeMethod controls later MIP node relaxations. |
CUTSTRATEGY | Cuts | Both control overall cut aggressiveness, but their positive levels are defined differently. |
HEURSEARCHEFFORT | Heuristics, sometimes SubMIPNodes | Xpress uses a multiplier on local-search effort; Gurobi Heuristics targets a fraction of total MIP runtime. |
COVERCUTS | CoverCuts | Xpress specifies root-node rounds; Gurobi uses an aggressiveness level. Do not copy the value directly. |
CROSSOVER | Crossover | The concepts are similar, but the positive numeric codes differ and Gurobi also distinguishes cleanup methods. |
DUALIZE | PreDual | The automatic, prohibit, and force concepts align reasonably for -1, 0, and 1. Gurobi also provides setting 2. |
OPTIMALITYTOL | OptimalityTol | Closest match for the simplex reduced-cost optimality tolerance. |
BARGAPSTOP | BarConvTol or PDHGConvTol | Use BarConvTol for barrier. If the selected method is PDHG, review PDHGConvTol and the related feasibility tolerances. |
BARCRASH | CrossoverBasis | Both affect basis construction around crossover, but the strategies and numeric values are not equivalent. |
Legacy MAXTIME | TimeLimit, possibly custom termination logic | Xpress deprecated MAXTIME in version 9.0. Positive legacy behavior is not reproduced by simply copying the value. |
These are migration guides, not value-for-value conversions. For settings not listed here, consult the complete Gurobi Parameter Reference.
Set parameters on the model
Optimizing and extracting a solution
Diagnosing infeasibility
If the migrated model is infeasible, compute an irreducible inconsistent subsystem:
Gurobi also provides feasibility-relaxation routines when you want to find a minimum-cost relaxation of selected bounds or constraints. Review the infeasibility-analysis documentation before applying a relaxation because these routines may modify the model.
Validate the migration
A successful solve is not proof that the model was translated correctly. Compare objective sense and coefficients; variable counts, bounds, and types; linear, quadratic, SOS, indicator, and piecewise-linear constraints; multiple objectives; MIP starts; branching priorities; callback-added constraints; solver status; incumbent and bound; gaps; important variable values; feasibility and integrality violations; and stopping reasons.
Small numerical differences are normal. Large differences, different feasibility conclusions, or objective values outside configured tolerances require investigation. Write the translated model to LP or MPS when file-based inspection will help.
Benchmark fairly
Use the same formulation and input data on comparable hardware. Keep thread and resource limits consistent, separate construction time from solver time, compare equivalent termination requirements, run representative models, and avoid comparing a heavily tuned Xpress configuration only against Gurobi defaults. Establish a valid baseline first, then tune each solver independently on a representative training set. Remember that even free trials get access to our Experts for tuning.
Next steps
Once the migrated model has been validated, explore the current Gurobi Example Tour and Optimizer Reference Manual for callbacks, matrix modeling, multiple objectives, solution pools, infeasibility analysis, tuning, and deployment options.
Ready to benchmark your models with Gurobi? Request a free evaluation license or speak with a Gurobi expert.

