---
title: Licensing
order: 6
description: What is free and what needs BoxLang+, a side by side comparison, why Plus is worth it, how to activate it and how Lens detects it.
icon: lucide:badge-check
---

# Free and BoxLang+

BxLens is **freeware with limits**. Everything you need to see what one request did, and most of what you need to run one server, is free, including in production. BoxLang+ lifts the limits and adds the features that keep history, act on the server, read other servers and call a model.

**Free is one server only.** Multi server observability is BoxLang+.

This page is the one place that says what is free and what is not. It describes the current split and may change. The server checks one list, `Licensing.PLUS_FEATURES`, in one place, `Licensing.has()`.

## At a glance

| | Free | BoxLang+ or trial |
|---|---|---|
| **The bar** | | |
| All tabs: timeline, queries, exceptions, HTTP, messages, timers, request, runtime, scopes, BIF timing, your own panels | Yes | Yes |
| Request cost (CPU time and memory allocated) and the slow request sample | No | Yes |
| Save or reset the bar layout | Look only | Yes |
| **The console** | | |
| Overview, Executors, Datasources, Logs (browse and the last 200 lines), Environment, Modules, Configuration, System | Yes | Yes |
| In flight: requests running right now, with the stack of each | No | Yes |
| Threads and thread dumps | No | Yes |
| Logs: search and live tail | No | Yes |
| Settings: read every value | Yes | Yes |
| Settings: change or reset them in the console | No | Yes |
| Viewer role (read only login) | No, admin login only | Yes |
| Requests kept in memory | Last 25 | As configured (default 50) |
| Queries (including the SQL of the ORM) | The 10 heaviest statements, in memory | Every statement kept (up to 500), in memory |
| Errors and Reports | In memory, 60 minute series | Saved to disk, totals since first install, series up to 3 days |
| HTTP page: outgoing calls by host and endpoint, p50, p95, p99, what needs attention | Last hour of this server | 24 hours, 7 and 15 days from the saved rollups |
| HTTP: the list of single calls with the request that made each | No | Yes |
| ORM page: event totals, failures and Hibernate statistics | No (the SQL itself is free) | Yes |
| System: heap, GC, threads, disk volumes and the folders Lens writes to (this server) | Yes | Yes |
| Mail page for bx-mail: message viewer with a safe preview, delivery attempts, servers, queue | Three counters and the last ten messages | Yes |
| Email alerts (15 rules, your SMTP, recipients) and daily, weekly and monthly reports | No | Yes |
| **Many servers** | | |
| **Multi server observability:** the server selector, the Servers table and the pages of other servers (HTTP, Reports, Errors, AI, Mail, System and more) | No, **one server only** | Yes |
| **Acting on the server** | | |
| Scheduled tasks: view | Yes | Yes |
| Run now, pause, resume, reload | No | Yes |
| Caches: statistics and the key list | Yes | Yes |
| Read a cache value, evict, reap, clear | No | Yes |
| Heap dump (also needs `console.allowHeapDump`) | No | Yes |
| **Taking data away** | | |
| Download a log file | No | Yes |
| Diagnostic bundle for a support ticket | No | Yes |
| **AI** | | |
| Copy a redacted prompt, open ChatGPT or Claude | Yes | Yes |
| Explain with AI, Ask Lens and Lensy, the Box Agent (chat, tools, approved actions, MCP servers) | No | Yes |
| AI observability: runs, agents, MCP servers, models, cost, registries | Three counters for the last hour | Yes |
| **Security and operations** | | |
| Live settings, read only mode, viewer role, audit log, proxy header trust, `console.requireHttps` | Yes | Yes |
| All `lens*` BIFs and the extension API | Yes | Yes |
| Air gapped: no request to any other site | Yes | Yes |

## Why BoxLang+

* **History that survives a restart.** Errors, reports, HTTP rollups and AI runs are saved to disk, so Monday morning still knows what happened on Saturday. Free forgets when the server stops.
* **Longer and deeper.** Ranges of 24 hours to 15 days, series up to 3 days, more requests in memory, and totals since first install.
* **See every server.** Servers that share a store folder appear in one selector. Totals add up and the p95 is merged from the histograms, not averaged. Read only, with no agent to install.
* **Know what a request cost.** CPU time and allocation per request, and a sample of the slow ones, so you find the request that burns the server and not only the one that waits.
* **Act, with a record.** Run a task, clear a cache, reap, evict or take a heap dump from the console. Admin only, and every action is in the audit log.
* **Hand support a complete picture.** The diagnostic bundle and log downloads in one click, secrets hidden.
* **Ask the server.** Lensy answers questions with the real numbers of this server, proposes actions you approve one by one, and can read the documentation through MCP servers you allow.
* **Watch your agents.** Runs, traces, tokens, cost, failing tools and the MCP servers you host, with what to check when something fails.
* **A subscription for the whole platform.** The same license unlocks the other BoxLang+ modules, and it comes with the support described on the [BoxLang plans page](https://boxlang.io/plans).

## Get BoxLang+

You need the `bx-plus` module and a license. A trial license works the same way and shows as `Trial` in the console. Plans and trials are on [boxlang.io/plans](https://boxlang.io/plans).

1. **Install bx-plus** on the server that runs Lens.

   ```bash
   # BoxLang binary
   install-bx-module bx-plus

   # CommandBox
   box install bx-plus
   ```

2. **Activate** with the email of the subscription and the license key. Pick one way.

   ```bash
   # Command line
   boxlang module:plus activate --email "$BX_LICENSE_EMAIL" --licenseKey "$BX_LICENSE_KEY" --serverType Production

   # CommandBox, for example when you build a Docker image
   box boxlang cli module:bx-plus activate --email=$BX_LICENSE_EMAIL --licenseKey=$BX_LICENSE_KEY --serverType=Production
   ```

   ```javascript
   // From code, once
   boxlangLicenseActivate( email = "you@company.com", licenseKey = "your-license-key", serverType = "server" );
   ```

   Keep the key out of source control: read it from an environment variable or a secret store. The license is a token that bx-plus refreshes by itself on the day it expires. You can refresh it by hand with `boxlangLicenseRefresh()` or `boxlang module:plus refresh`.

3. **Check it.** `boxlang module:plus info` or `boxlangLicenseInfo()` shows the status. In the console header the label changes to `BoxLang+ active` (or `Trial`, with the days left). Lens asks again at most every 5 minutes, so the locked items open without a restart.

   ```bash
   boxlang module:plus info
   ```

4. **Turn on what you want.** Some Plus features are also off until you choose them: AI needs `ai.enabled`, the AI page needs the bx-ai integration switched on, heap dumps need `console.allowHeapDump`, and the disk store needs `store.enabled` (on by default).

If bx-plus is missing or the license is not valid, Lens reports Free and carries on. Nothing breaks, the locked items show a BoxLang+ note.

## How a locked item behaves

On Free, a locked item shows a "BoxLang+" note or chip next to it, and the server answers 403 with a message that names BoxLang+ (the AI chat answers 409). A trial or a valid license unlocks all of it. If a trial ends or a license expires, the locked features stop at the next license check. The disk store stops writing, the request history returns to 25, and request cost and the slow request sample stop being collected. Data already on disk stays on disk.

### Details per feature

| Feature | Free | BoxLang+ or trial | Where the lock shows |
|---|---|---|---|
| Request cost (CPU time and allocation) and the slow request sample | Not collected | Collected | Bar: the `cpu` and `alloc` chips are hidden, and the Runtime tab has a BoxLang+ note. |
| Scheduled task actions | View only | Run now, pause, resume, reload | Tasks page: a BoxLang+ note, and the action buttons are disabled. Server: 403. |
| Caches | Statistics and the key list | Read a value, evict, reap, clear | Caches page: a BoxLang+ note, and the buttons are disabled. Server: 403. |
| Download a log file | Browse, search and live tail | Allowed | Logs page: the Download button is disabled with a Plus chip. Server: 403. |
| Diagnostic bundle | No | Allowed | Environment page: the link is disabled with a Plus chip. Server: 403. |
| Heap dump | No | Allowed, and still off until `console.allowHeapDump` is `true` | System page: a BoxLang+ note replaces the controls. Server: 403. |
| Save or reset a bar layout | Look at the designer | Allowed | Bar designer: the buttons are disabled, with a "BoxLang+ to save a layout" chip. Server: 403. |
| AI calls from the server: Explain with AI, Ask Lens, [Lensy](console/ai.md) | No | Allowed, with `ai.enabled` | The assistant button and the bar's Ask link are hidden, and the AI settings are locked. Server: 409 for a chat, 403 for the AI settings and the connection test. |
| Disk store | In memory, 60 minute series | Saved to disk, series up to 3 days | Errors and Reports pages: a note that the data is kept in memory only. |
| ORM statistics | The ORM SQL is free and shows with other queries | The console ORM page | ORM page: a BoxLang+ note. Server: 403. |
| HTTP history | The last hour of this server | 24 hours, 7 and 15 days (needs the disk store) | HTTP page: the 24h, 7d and 15d buttons are disabled. Server: 403. |
| The list of outgoing HTTP calls | No | Allowed, at `collect.level` full | HTTP page: the Calls tab shows a BoxLang+ note. Server: 403. |
| AI observability (`aiObs`) | Three counters for the last hour: failed runs, rate limit hits and MCP errors | Allowed | Everything but the counters answers 403. The recorder middleware is not attached. |
| Email reports: a daily, weekly and monthly report of the cluster for admins (`notifications`) | No | Allowed | Part of the Notifications tab. Server: 403. |
| Notifications: email alerts for 15 conditions on every server, recipients, SMTP settings and a test mail (`notifications`) | No | Allowed | The Notifications tab shows a BoxLang+ note. Server: 403. |
| The Mail page: message viewer with preview, search, servers, queue and its actions, settings (`mail`) | Three counters for the last hour (sent, failed, spooled), the last ten messages (addresses and subject) | Allowed | Everything but the counters answers 403. |
| The server selector and the pages of other servers (HTTP, Reports, Errors, AI, and System, Executors, Tasks, Datasources, Caches, Requests, In flight from the health snapshot) | This server only | Allowed | No selector in the header. The server answers 403 for another server or all. |
| Requests kept in memory | 25 at most, even if `history.maxRequests` is higher | `history.maxRequests` as configured (default 50) | None. |
| The In flight page (`inFlight`) | No | Allowed | In flight page: a BoxLang+ note. Server: 403. |
| Threads and thread dumps (`threads`) | No | Allowed | Threads page: a BoxLang+ note. Server: 403. |
| Change or reset settings in the console (`liveSettings`) | Read every value | Allowed | Settings page: the buttons are disabled with a note. Server: 403. `boxlang.json` still works. |
| The viewer role (`viewerRole`) | The viewer password is refused with a BoxLang+ message; admin signs in | Allowed | Login page. A viewer session ends when the license ends. |
| Log search and live tail (`logTail`) | Browse and read up to 200 lines | Search, live tail, up to 2000 lines | Logs page: the search box and Live button are disabled. Server: 403 for a search. |
| All statements in Queries (`fullQueries`) | The 10 heaviest by total time, with the totals of all | Every statement kept | Queries page: a note with the count. |

The audit log keeps writing on Free. There is no page that reads it, so nothing about it is gated.

The console also has an **Upgrade** page (until the license is BoxLang+) that lists everything above, with a link to the plans. It describes the current split and may change.

The disk store (`store.enabled`, on by default) writes to `store.dir` (default `lens-data` in the BoxLang home), in a subfolder for this server. It keeps data for `store.retentionDays` (15, at most 30), limits the whole folder to `store.maxMB` (500) and hands changes to the store every `store.flushSeconds` (30). One owner writes everything on its own thread, and each file is replaced atomically. See [The store](reference/store.md) and [Errors and Reports](console/errors-and-reports.md#the-disk-store). Without the license the store settings have no effect. The bar layout file and the settings overrides file are small files for your own choices, and the settings file works on Free.

BoxLang AI (bx-ai) ships inside the module, in its `modules` folder, so there is nothing else to install. It is Apache 2.0 licensed. Using it from Lens still needs `ai.enabled` and, for the server calls, BoxLang+.

## The license

BxLens ships under a BoxLang+ proprietary license, in the `LICENSE` file of the module. It is freeware with limits: the free features can be used without a subscription, including in production, but not redistributed or modified. The BoxLang+ features and the removal of the free limits need a BoxLang+ subscription or an active trial. The same terms apply to every Ortus BoxLang+ module, such as bx-redis. The exact text is the `LICENSE` file, not this page.

## License states

Lens detects the state through the `bx-plus` module, the same way other BoxLang+ modules do. It asks the global `BoxlangLicenseService` whether the license is valid and whether it is a trial (`isValidLicense`, `isTrialMode`), and reads the expiry from `BoxlangLicenseInfo`.

| State | Label in the console | When |
|---|---|---|
| Plus active | `BoxLang+ active` | A valid license that is not a trial. |
| Trial | `Trial` with the days left | A valid trial license. The console shows a banner: you are on a trial, Plus features stop working when it ends and need a license, with a link to [boxlang.io/plans](https://boxlang.io/plans). |
| Expired | `License expired` | The license is present but not valid. The banner says Plus features may stop working. |
| Free | `Free` | `bx-plus` is not installed, or the check failed. |

![The trial banner in the console](assets/screenshots/license-trial.png)

The state shows in the console header.

## Safe by design

- The answer is cached for 5 minutes.
- A missing, invalid or failing license check never breaks Lens. It reports Free and carries on.
- Lens makes no network call for licensing. It only talks to the `bx-plus` module in the same runtime.

## Show a state for a demo

Set `dev.license` to `trial`, `plus`, `expired` or `none` to force a state. An empty value detects the real one. The harness reads the `LENS_LICENSE` environment variable for this:

```bash
LENS_LICENSE=trial harness/start.sh
```

## Third-party notices

The console and the bar use Alpine.js and Phosphor Icons. Phosphor Icons are MIT licensed, the notice is in `src/main/bx/assets/ICONS-LICENSE.txt`.
