Aim: a self-hosted experiment tracker for teams with thousands of runs
Aim 💫 — An easy-to-use & supercharged open-source experiment tracker.
At a glance
- What is it?
- Aim is an Apache-2.0 Python experiment tracker that stores runs locally, serves a comparison UI, and exposes a query API. It targets the run volume problem, not the hosted-service problem, and the trade-off is that you operate the storage yourself.
- Who is it for?
- Adopt Aim if your training runs live on machines you control and you want the metadata queryable from Python rather than locked in a hosted dashboard. Do not adopt it if your team needs a managed service with no local storage to operate, or if you already depend on a platform whose pipeline integration you cannot replace.
- Can I use it commercially?
- Yes. Apache-2.0 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 1 day 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 15, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
The problem Aim picks: run volume, not run setup
Most experiment trackers are pleasant at ten runs and painful at ten thousand. The README states the design target directly: Aim is "designed to handle 10,000s of training runs." That number is the whole thesis. Everything else about the project follows from it.
The audience is a team that runs training on its own hardware, wants to compare runs in a browser, and also wants to pull the same numbers into a notebook or a script without scraping a dashboard. The README describes two surfaces for the same data: a UI "to compare, observe them" and "an API to query them programmatically." If you only ever need the first surface, Aim is heavier than you need. If you need the second, it is the reason to look at this project at all.
Aim is self-hosted. There is no account, no upload step to a vendor, and no per-seat pricing in the repository. The cost moves to you: you run the server, you keep the storage, and you own the backup story. That is a real shift in responsibility, and it is the first thing to weigh.
What happens between aim.Run and the UI
The README describes the flow in one sentence: "Aim logs your training runs and any AI Metadata." The unit is the run. You create one, attach metrics and other metadata to it, and the SDK writes that record to a local store. The server reads the store and serves the UI and the query API from it.
The storage layer is the part that has moved most recently. The v3.29.1 release notes describe "reading from single unified database and constant data indexing" as a query performance improvement. That is a change to how reads are served, not a new user-facing feature, and it tells you the project is still tuning the read path for large run counts. If you are evaluating Aim against a store you already have, the shape of that database matters more than the UI screenshots.
Metadata is not limited to scalar loss curves. The README says Aim logs "any AI Metadata," and the repository topics include prompt-engineering and metadata-tracking alongside the usual ML terms. The practical reading is that a run can carry text and structured values, not just floats. The README does not spell out the schema, so treat the exact set of trackable types as something to confirm against the documentation before you design around it.
Integration is by logger rather than by protocol. The README shows a wall of framework logos under "SEAMLESSLY INTEGRATES WITH," and the release notes name specific ones as they change: a "new callback for hugging face distributed runs" in v3.28.0, and "Enhancements for PytorchLightning logger and S3ArtifactsStorage" in v3.27.0. Those two entries are worth reading together. They show that integrations are maintained individually, one at a time, and that a framework being listed does not mean its logger is finished.
Installing and starting the server
The README's quick start section is the only place in the supplied material that gives commands, and it is truncated before the code block. What can be confirmed from the badges is the constraint set: Python >= 3.7, and platform support for Linux and macOS. Windows is not listed on the platform badge.
The package name is aim on PyPI, so the install is a pip install of that name. The server is started with the aim up command, which the README's quick start references. Because the README text was cut before the example block, I cannot quote the exact flags or the default port from this material, and I am not going to guess them. Check the quick start page and the readthedocs documentation for the current invocation.
Two configuration points are visible. The first is the storage location: a self-hosted tracker writes runs somewhere on disk, and that path is what you back up. The second is S3 artifact storage, named in the v3.27.0 release notes as S3ArtifactsStorage. If your artifacts are already in object storage, that is the path to look at, and the release notes indicate it received fixes in that version, which is worth knowing before you rely on it for a first deployment.
For remote tracking, v3.28.0 mentions "remote tracking exception handling" as a fix. That phrasing implies remote tracking exists as a mode, and that its error paths were being corrected as recently as March 2025. If your runs execute on a different host from the one serving the UI, test that path early rather than assuming it.
Where Aim is the wrong tool
The clearest limitation is the one the README states as a feature. Self-hosted means you operate it. A small team that wants a hosted dashboard, SSO, and someone else's uptime guarantee is not the audience for this project, and no amount of UI polish changes that.
The second limitation is integration depth. Aim's value at the point of logging depends on a logger for your framework. The release notes show those loggers being fixed individually across three consecutive releases: a Hugging Face distributed callback added in v3.28.0, PyTorch Lightning logger enhancements in v3.27.0, and a Jupiter/Colab integration fix in v3.29.1. That cadence is normal for a project of this kind, but it means the integration you need may be at a different maturity level than the one in the screenshot. Verify yours before you migrate a training pipeline onto it.
The third is the storage change itself. Moving to "single unified database and constant data indexing" in v3.29.1 is a read-path change, and read-path changes are the kind that surface as slow queries or wrong aggregations rather than as crashes. The same release notes list "fixes in min/max calculation in UI," which is exactly that category of bug. If you are on an older version and your dashboards depend on min and max values, read the v3.29.1 notes before upgrading.
Finally, the README makes no claim about access control, multi-tenancy, or audit. For a self-hosted tool serving a single team that may be fine. For anything where run metadata is sensitive across groups, that absence is a gap you would have to fill yourself, and the material here does not say how.
Aim against TensorBoard and MLflow
Both TensorBoard and MLflow appear in the repository topics, so the project positions itself in that space. The difference in approach is worth stating plainly.
TensorBoard is a visualization layer over event files. It is excellent at scalar curves and image grids, and it is bundled with the frameworks that emit those files. Its comparison model is built around loading multiple event directories into one view. Where it gets awkward is programmatic access: pulling a specific metric from a specific run into a script is not the primary interface. Aim's README puts the API next to the UI as a first-class surface, which is the opposite emphasis.
MLflow is closer in ambition. It is a tracking server with a model registry and a packaging story attached. The registry is the dividing line: if your problem is "which checkpoint is in production and how do I promote the next one," that is a registry problem, and Aim's README describes tracking, comparison, and query, not promotion. If your problem is "I have ten thousand runs and I need to find the ones where the loss spiked," that is a query problem, and that is the one Aim is aimed at.
The honest summary is that these are not substitutes so much as different centers of gravity. Aim centers on querying run metadata at volume. If your bottleneck is deployment lineage rather than run comparison, adopting Aim will not address it.
Upgrade cost and the licence you are accepting
Aim ships frequently. The supplied release list shows v3.27.0 in December 2024, v3.28.0 in March 2025, and v3.29.1 in May 2025, with the repository's last push in September 2026. That is a steady cadence, and it means an upgrade is a recurring task rather than a one-time install.
The upgrade cost is concentrated in two places. Storage format changes, like the unified database read path in v3.29.1, affect how your existing runs are read. Logger changes, like the PyTorch Lightning and Hugging Face entries in v3.27.0 and v3.28.0, affect how new runs are written. Neither is free, and the release notes are short enough that you should read them before each bump rather than after.
On licensing: Aim is Apache-2.0. That is a permissive licence, and the repository also points to commercial enterprise support via hello@aimstack.io for what the README calls "enterprise support that's beyond core Aim." If your organization has rules about which open source licences it accepts, or about the boundary between the community project and a paid support offering, that is a question for your own counsel. Nothing here should be read as legal advice.
The practical point is that Apache-2.0 gives you the freedom to run and modify Aim, and self-hosting gives you the responsibility to keep it running. Those two facts are the same fact viewed from different sides.
Editorial conclusion
Adopt Aim if your training runs live on machines you control and you want the metadata queryable from Python rather than locked in a hosted dashboard. Do not adopt it if your team needs a managed service with no local storage to operate, or if you already depend on a platform whose pipeline integration you cannot replace. Before committing, verify two things: that the storage backend you are actually deploying matches the unified-database path described in the v3.29.1 release notes, and that your framework integration is one the README lists, since the project ships many and they are not equally maintained.
Community notes