MIP Benchmark: MIPLIB

Previous benchmarks have covered LP and QP solvers, but never MIP solvers. The November 2025 report gave two reasons: there was no other pure Java MIP solver to compare with, and no suitable set of test models. With MIP, a tiny model can be harder than a very large one, so size alone is not a useful filter. Finding models that are hard enough to be meaningful but tractable enough that the benchmark finishes in reasonable time is a problem of its own.

Since then we found a pure Java alternative in SSC-LP, and worked on constructing a suitable test set. Here is our first-ever MIP benchmark:

The solvers

  • ojAlgo v57.3.0 (Java)
  • HiGHS v1.15.1 via ojAlgo-highs v2.0.0 (native code)
  • SCIP v10.0.3 via ojAlgo-scip v1.0.0 (native code)
  • SSC-LP v4.7.8 via ojAlgo-ssclp v1.0.0-SNAPSHOT (Java)

All four solvers are open source. ojAlgo and SSC-LP are pure Java. HiGHS and SCIP are native code. All are invoked through ExpressionsBasedModel — the three third-party solvers via ojAlgo solver integrations maintained by Optimatika. HiGHS and SCIP are also both available through the Optimisation Service. This is the first time we include SCIP in a benchmark — it is widely regarded as the strongest open-source MIP solver, with HiGHS as the up-and-coming challenger.

SSC-LP is an ambitious project — not just an LP solver but a MIP solver, with an online solver GUI as well. It is the only other pure Java solver we could find with MIP support, which is why it is included here. We have built an ojAlgo integration, but SSC-LP is licensed under GPLv3 without a linking exception, so the integration cannot be released.

The test set

The MIPLIB models are tough. It contains models no solver has ever solved, and models labeled "easy" are defined as those that at least one of the top commercial and/or academic solvers can solve within an hour — that's far beyond the scale where LP and QP benchmarks operate, and far beyond the time and compute resources we're willing to invest.

To construct our test set we started with the MIPLIB 2017 "easy" and "benchmark" models, then added models from earlier MIPLIB editions hoping to find more workable instances. Filtering to models with at most 1,000 variables and 1,000 constraints gave us 148 models. That size limit is an attempt to keep the benchmark runnable in reasonable time, but with MIP models size is a poor predictor of difficulty.

We ran preliminary benchmarks on all 148 models to determine which ones are genuinely "easy". (When doing this we also included some commercial solvers we had access to.) No solver handles all of them, and every solver succeeds on some that others fail on.

We use a time limit of 300 seconds (5 minutes) per model. A solver that does not find a proven optimal solution within that limit is marked as FAILED. There is no distinction between not being able to solve a model at all and requiring just over 5 minutes to do so.

MIPLIB solvability by solver category

Top commercial solvers typically solve around 90% of these models. Open source native code solvers like HiGHS and SCIP handle roughly 75%. ojAlgo reaches just under 50%.

There were 103 models that all native code solvers in our test could solve — most importantly both SCIP and HiGHS. If every native solver handles a model, it is reasonable to call it easy. This gives clean execution time comparisons, but it somewhat tilts the set in favour of native code: there are models in the full collection that ojAlgo solves and some native solvers do not (gen-ip002 and gen-ip054 are two), and those are excluded from the test set we used here.

Results

SolverSuccess RateSolvedFastest
SCIP100%10341
HiGHS100%10328
ojAlgo62%6434
SSC-LP25%260

Both native code solvers solve all 103 models (as expected from the definition of the test set). ojAlgo solves 64 of them — every model with under 100 variables (21 of 21), and decreasing from there as models grow. SSC-LP, the other pure Java option, manages 26.

MIP benchmark  relative execution time

The x-axis is the geometric mean of SCIP and HiGHS execution times and the y-axis is each solver's execution time for the same model. Both axes are logarithmic. Because the x-axis is the native solver average, HiGHS and SCIP dots naturally scatter around the implicit diagonal — points above it are slower than the average, points below are faster. Trend lines are shown for ojAlgo and SSC-LP. The ojAlgo trend line sits below the native solvers, meaning ojAlgo is typically faster on the models it solves. SSC-LP sits well above.

SCIP edges out HiGHS overall, finishing faster on 41 models to HiGHS's 28.

SSC-LP solves 26 models — all of them small, and even on those it is the slowest solver by a wide margin. On the stein27 model SSC-LP takes over 4 minutes where ojAlgo finishes in 48 milliseconds.

Discussion

On the models ojAlgo can handle, it is remarkably fast. Of the 64 models it solves, it is the outright fastest solver — faster than both HiGHS and SCIP — on 34 of them, just over half. The median execution time for ojAlgo on those 64 models is roughly half that of HiGHS and half that of SCIP. On models with fewer than 100 variables ojAlgo solves everything, and it is the fastest solver more often than not.

That is worth repeating: on the models ojAlgo can handle, it is often faster than native code.

The gap grows with problem size and structural difficulty. Between 100 and 300 variables ojAlgo still solves most models (21 of 31) and remains competitive on speed. Above 500 variables the success rate drops — only 5 of 16 models between 500 and 750 variables, and 3 of 13 between 750 and 1,000. When ojAlgo does struggle, it struggles badly. On a handful of models — enlight_hard, vpm1, pigeon-08 — it finds the optimal solution but takes orders of magnitude longer than SCIP or HiGHS to get there.

SSC-LP, despite its ambitious scope, is not a practical alternative. Between the GPLv3 licence that prevents releasing an integration, and performance that trails every other solver by a wide margin, it does not offer a path forward for users who need more than ojAlgo alone can provide.

This does not mean ojAlgo cannot handle models with more than 1,000 variables. MIPLIB models are deliberately hard — they are curated to challenge solvers, not to represent typical workloads. And this benchmark uses a 5-minute time limit, where MIPLIB itself allows a full hour just to classify a model as "easy." Many real-world MIP models with thousands of variables have structure that solvers exploit well, and ojAlgo handles those routinely. What the benchmark does show is that on structurally difficult models, the gap between pure Java and native code widens as models grow.

Where ojAlgo is not the answer

The benchmark is clear about the limits. On very large models, structurally difficult formulations, and numerically challenging problems, ojAlgo will not match the native solvers. The 39 models it cannot solve here — and the wider set it cannot reach in the full MIPLIB collection — are not edge cases. They are the kind of models that appear in production when a business grows, a formulation tightens, or data scales up.

That is why all four solvers in this benchmark were invoked through the same ExpressionsBasedModel API. The model you write does not encode which solver runs it. Optimatika maintains a large set of third-party solver integrations — including the top commercial solvers and the best open source native solvers. Your model code does not change; you choose the solver that fits the problem.

Even with free solvers, using them directly means interfacing with native code, packaging platform-specific binaries for every target environment, and ongoing maintenance as JDK versions and solver versions move independently. That is real engineering work, and it never stops. The Optimisation Service exists to absorb it — it puts a suite of native solvers in a server you deploy in your own cluster, so your application stays pure Java while the solving moves to native code. No native code in your build, no platform-specific binaries to package, no solver licences to manage.

Methodology

The benchmark was run on a MacBook Pro with an M5 Pro chip and 48 GB of RAM. Each model-solver combination is evaluated with a time limit of 300 seconds (5 minutes). If a solver finds a proven optimal solution within the time limit, the execution time is recorded. Otherwise the model is marked as FAILED.

All solvers are invoked via ojAlgo's ExpressionsBasedModel. The time measured corresponds only to the solver-specific code — model parsing and presolve are excluded.

The benchmark code and raw results: