facebook/Ax: Bayesian Optimization Without the BoTorch Boilerplate
Adaptive Experimentation Platform
At a glance
- What is it?
- Ax is Meta's adaptive experimentation platform for Python. It wraps BoTorch in a Client API that runs a closed optimization loop, and the trade-off is that the model layer stays behind the abstraction unless you reach for the full API.
- Who is it for?
- Adopt Ax if you have a Python 3.11+ environment, a search space you can express as parameters and bounds, and an evaluation function you can call programmatically, because the Client loop in the README is the shortest path from a black-box function to a suggested best configuration.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 8 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 24, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The problem Ax solves, and the person it is written for
Some optimization problems do not come with a gradient. You have a function that takes a configuration and returns a number, the function is expensive enough that you cannot grid-search it, and the observations are noisy. Tuning a model's hyperparameters, choosing reaction conditions, or picking parameters for a simulator all fit this shape. Ax is built for that loop: propose a configuration, evaluate it, feed the result back, propose the next one.
The README frames the scope as "adaptive experimentation," which it defines as the machine-learning guided process of iteratively exploring a parameter space to identify optimal configurations in a resource-efficient manner. Two exploration strategies are supported: Bayesian optimization and bandit optimization. The Bayesian side is powered by BoTorch, a library built on PyTorch.
The intended user is not necessarily an optimization researcher. The README's second selling point is that Ax abstracts away optimization details that are important but obscure, with sensible defaults, so that practitioners can use techniques otherwise only accessible to optimization experts. The fourth point pulls in the other direction: Ax is configurable enough that researchers can plug in novel algorithms, models, and experimentation flows. That tension between a one-line default path and a deep research surface is the central design fact about this project, and it explains why the codebase ships both a Client and a full API.
How the Client loop actually moves data
The README's getting-started example is a closed loop with a client object at the center. You call configure_experiment with a list of parameters, each a RangeParameterConfig with a name, bounds, and a parameter_type. You then call configure_optimization with an objective string. In the example the objective is "-1 * booth", which tells the client that the Booth function is being minimized.
The loop then alternates two calls. get_next_trials(max_trials=1) returns a dictionary keyed by trial index, and each value is a dictionary of parameter values. You evaluate those values outside Ax and pass the result back through complete_trial, with trial_index and a raw_data dictionary whose keys match the objective expression. After twenty iterations the example calls get_best_parameterization.
The important structural detail is that Ax never sees your evaluation function. It sees parameter values going out and raw_data coming back. That keeps the platform agnostic about what you are optimizing, and it is also why parallel and asynchronous evaluation are possible: the README states that Ax supports suggesting multiple designs to evaluate in parallel, both synchronously and asynchronously, and that it supports early-stopping evaluations. A single max_trials argument is what controls how many designs come back at once.
Underneath, the objective string is parsed and the parameter configs become a search space. BoTorch supplies the surrogate model and the acquisition function. The README does not describe the acquisition function selection logic in the getting-started section, so the default behavior at that layer is not documented there.
Installing Ax and running a first optimization
Ax requires Python 3.11 or newer, and the README recommends pip even inside a Conda environment. The package name on PyPI is ax-platform, not ax. Wheels are published for macOS, Linux, and Windows.
pip install ax-platformIf you use Conda, the README warns that the pip you invoke must be the one from the newly created environment, and suggests which pip on a Unix-based system to confirm. Optional extras exist for Jupyter, MySQL storage, running tutorials locally, and development. The fully_bayesian extra pulls in the optional JAX and NumPyro backend needed for SAASBO, SAAS_MTGP, or the API's method="quality" generation strategy.
pip install "ax-platform[notebook]"A minimal first run follows the README's Booth example. Two float parameters on (-10.0, 10.0), an objective of "-1 * booth", and a loop that completes one trial per iteration.
from ax import Client, RangeParameterConfig
from ax.core.parameter import ParameterType
client = Client()
client.configure_experiment(
parameters=[
RangeParameterConfig(name="x1", bounds=(-10.0, 10.0), parameter_type=ParameterType.FLOAT),
RangeParameterConfig(name="x2", bounds=(-10.0, 10.0), parameter_type=ParameterType.FLOAT),
],
)
client.configure_optimization(objective="-1 * booth")After completing trials, get_best_parameterization returns the best configuration found. The README's example runs twenty iterations, which is a demonstration count, not a recommended budget. What you should see is the returned parameterization converging toward the Booth minimum as trials accumulate; the README states that Ax delivers strong performance across a variety of problem classes but gives no convergence numbers for this example.
Where Ax is the wrong tool
The README's dependency list is the first constraint. Ax requires Python 3.11 or newer, and it depends on BoTorch, pandas, scipy, scikit-learn, plotly, sympy, graphviz, and jinja2. That is a heavy install for a problem that does not need a surrogate model. If your objective is cheap to evaluate and you can afford a grid or a random search, Ax adds a model-fitting step between every batch of trials and buys you nothing.
If your objective is differentiable, Ax is also the wrong layer. Bayesian optimization is designed for black-box functions; when you have gradients, a gradient-based optimizer will use information Ax deliberately ignores.
The MySQL extra is a concrete compatibility trap. pyproject.toml pins SQLAlchemy==1.4.17 for that extra, while the rest of the dependency set is unpinned. Mixing Ax's MySQL storage into an application that already depends on a newer SQLAlchemy means resolving a conflict by hand or isolating Ax in its own environment. The README does not document a migration path for this.
There is also a boundary in the API split itself. The Client path exposes configure_experiment, configure_optimization, get_next_trials, complete_trial, and get_best_parameterization. Anything beyond that (custom models, custom acquisition functions, custom experimentation flows) requires moving to the full API, and the README does not document how to migrate a running Client experiment to it.
Ax against raw BoTorch
The most direct alternative is BoTorch itself, which Ax depends on. The difference is where the loop lives. In BoTorch you construct the model, fit it, define an acquisition function, optimize that acquisition function to get candidate points, and manage the training data tensor yourself. In Ax, the Client owns that sequence: you supply parameter configs and an objective string, and the platform decides the model and the acquisition step.
That is a real trade in both directions. The Client path is shorter and the README argues it produces strong results out of the box, which matters if nobody on the team wants to reason about kernels or acquisition trade-offs. Raw BoTorch gives you control over the surrogate and the acquisition function, which is what you want when the default model class is a poor fit for your response surface.
Ax's answer to that is the plug-in surface: the README states that researchers can plug in novel optimization algorithms, models, and experimentation flows. So the honest comparison is not Ax versus BoTorch as competing libraries. It is whether you want BoTorch's control surface exposed directly, or mediated by Ax's experiment abstraction, which adds storage, trial bookkeeping, and orchestration on top. If you only ever run one model fit and one acquisition optimization, Ax's bookkeeping is overhead. If you run many trials over weeks and need to track them, it is the point.
Maintenance, releases, and the licence
The repository is not archived, and the last push was on 2026-09-21, one week before this writing. Recent releases are 1.3.1 on 2026-06-09, 1.3.0 on 2026-06-04, and 1.2.4 on 2026-03-05. The cadence in that window is a minor release in June followed by a patch three days later, then nothing tagged until September's push. The pyproject.toml classifier says Development Status :: 5 - Production/Stable.
The upgrade cost is concentrated in the BoTorch pin. Ax declares botorch[pymoo]>=0.18.1,<0.18.2dev9999, a range narrower than one minor version. A BoTorch release outside that window will not satisfy Ax's resolver, so an upgrade of one usually forces an upgrade of the other. The same comment in pyproject.toml notes that as of BoTorch 0.18.1 the JAX and NumPyro NUTS backend stopped being a required dependency and moved behind the fully_bayesian extra. If you relied on SAASBO before that change, the fix is installing the extra, not changing your code.
Installing from source means tracking bleeding-edge BoTorch and GPyTorch from GitHub first, which the README recommends explicitly because the bleeding edge of Ax depends on bleeding-edge versions of both. That is a development workflow, not a deployment one.
The licence is MIT, declared in pyproject.toml with license-files pointing at LICENSE, and the README carries an MIT badge. MIT is permissive: it allows commercial use and modification with attribution and no warranty. This is a description of the licence text, not legal advice; if you redistribute Ax inside a product, read the LICENSE file and your own counsel's guidance.
Editorial conclusion
Adopt Ax if you have a Python 3.11+ environment, a search space you can express as parameters and bounds, and an evaluation function you can call programmatically, because the Client loop in the README is the shortest path from a black-box function to a suggested best configuration. Do not adopt it if your problem is a single deterministic evaluation with an analytic gradient, or if you need MySQL storage on a modern SQLAlchemy stack, since the mysql extra pins SQLAlchemy==1.4.17. Before committing, verify your Python version, confirm whether you need the fully_bayesian extra for method="quality", and check that the BoTorch version resolved by pip falls in the >=0.18.1,<0.18.2dev9999 range declared in pyproject.toml.
Frequently asked questions
What is facebook/Ax used for?
It is a platform for adaptive experimentation, which the README defines as iteratively exploring a parameter space to find optimal configurations efficiently. It supports Bayesian optimization and bandit optimization, with the Bayesian side powered by BoTorch.
How do I install Ax-platform?
The README recommends pip install ax-platform, and notes that Ax requires Python 3.11 or newer. Extras are available for notebooks, MySQL storage, tutorials, and development, and the fully_bayesian extra adds the JAX and NumPyro backend.
What is the relationship between Ax and BoTorch?
The README states that Bayesian optimization in Ax is powered by BoTorch, a library for Bayesian optimization research built on PyTorch. pyproject.toml pins botorch[pymoo] to a range between 0.18.1 and 0.18.2dev9999.
Does Ax support running multiple trials in parallel?
Yes. The README states that Ax supports suggesting multiple designs to evaluate in parallel, both synchronously and asynchronously, and that it supports early-stopping evaluations. In the Client API this is controlled by the max_trials argument to get_next_trials.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/facebook-ax)