---
title: OpenLM LicOps
description: OpenLM LicOps admits an HPC or Kubernetes job only when an OpenLM Platform license seat is free, and names the license server to check out from.
product: OpenLM Platform
---

When a cluster starts more licensed jobs than it has free seats, the jobs that lose the race fail after they reach a node, or hold the node while they wait for a license. OpenLM LicOps checks for a seat before the job starts. Your scheduler asks LicOps for a seat when the job is submitted, and LicOps answers yes or no. When the job starts, LicOps tells it which license server to check out from.

:::note[OpenLM LicOps is in early availability]

OpenLM LicOps is in early availability. It isn't listed in **Products**, then **Downloads** in OpenLM Platform. You deploy it from the container images described in [Deploy OpenLM LicOps](https://www.openlm.com/documentation/cloud/deployment-operations/deployment), and OpenLM supplies the scheduler adapters. Contact OpenLM before you plan a production rollout.

:::

## Choose between the Router and LicOps

OpenLM ships two products as one program, the OpenLM Router. The mode you give the Router at its first start decides which product it is:

| Aspect | OpenLM Router (failover) | OpenLM LicOps |
| --- | --- | --- |
| Built for | Engineers on workstations, whose FlexLM clients use one license server | HPC clusters and Kubernetes workloads that start many licensed jobs at once |
| What it does | Moves clients from a failed primary server to its backup | Admits a job only when a seat is free, and picks the license server for it from a pool, the servers that serve the same vendor and feature |
| License servers | A primary and an optional backup for each application | Any number of servers for each vendor and feature |
| What you configure in OpenLM Platform | Port mappings | Admission rules and reservations |
| Router mode | `basic` | `loadBalancer` |

Choose one for your OpenLM account: failover or LicOps, not both. **LicOps Configuration** in OpenLM Platform works with one Router at a time, the one that reported most recently. If you need failover for workstation users, see [OpenLM Router](https://www.openlm.com/documentation/cloud/deployment-operations/router/) instead.

## How a job goes through LicOps

LicOps answers three requests in the life of every job. The scheduler adapters make them for you. A custom integration makes them itself.

1. **Admit**: when the job is submitted. The adapter asks for one or more seats of one vendor and feature. LicOps answers **Admit** or **Deny**. A denied job never enters the queue.
2. **Dispatch**: when the job starts on a node. LicOps names the license server to check out from, in `port@host` form. If the server it planned on has failed since admission, LicOps moves the seat to a healthy server that serves the same feature.
3. **Release**: when the job ends, whether it succeeds, fails, or is canceled. The seat returns to the pool.

LicOps tracks each job as a *session*, named by a session ID that the caller generates and sends with all three requests.

```mermaid
sequenceDiagram
  participant A as Scheduler adapter
  participant L as LicOps
  participant P as OpenLM Platform
  P-->>L: Seat counts and server health, about every 10 seconds
  A->>L: Admit: 1 seat of MLM:MATLAB
  L-->>A: Admit
  A->>L: Dispatch: the job starts on a node
  L-->>A: 27000@lic01.example.com
  Note over A: The application checks out from lic01
  A->>L: Release: the job ends
```

A *pool* is every license server that serves one vendor daemon and feature, written `VENDOR:FEATURE`, for example `MLM:MATLAB`. Every request names a pool, never a server: LicOps chooses the server.

### Where the seat counts come from

LicOps takes the license servers, their seat totals, the seats in use, and the health of each server from OpenLM Platform, about every 10 seconds. The OpenLM Broker on each license server reports them to OpenLM Platform, so LicOps can only use servers whose Broker reports to OpenLM Platform. To that it adds what only LicOps knows: the seats it has admitted that are not checked out yet. LicOps calculates the free seats as follows:

```text
free = total − in use − admitted, not yet checked out
```

That last term is what stops the last seat being given out twice. The license manager cannot see a job that is still starting, so without LicOps two jobs could both be admitted for one free seat. LicOps evaluates the whole sum in one step for each request, and corrects its count against the figures from OpenLM Platform about every 10 seconds.

Nothing is held at the license server. LicOps does not check licenses out and does not reserve them in FlexLM. Your applications check out exactly as they do today, from the server that dispatch names or from the server they already use.

### How LicOps chooses a server

Without rules, LicOps places each admitted seat on the least-loaded healthy server in the pool. To change that, write admission rules in OpenLM Platform. With them you can keep a server for one team, fill cheaper servers first, spread jobs evenly, or slow a burst of checkouts. See [Control placement with admission rules](https://www.openlm.com/documentation/cloud/deployment-operations/admission-rules). To cap how many seats LicOps hands out on a server at certain times of day, see [Cap seats on a schedule](https://www.openlm.com/documentation/cloud/deployment-operations/reservations).

Whether the application then checks out from the server LicOps chose depends on how you connect your workloads. See [Decide whether LicOps also chooses the server](https://www.openlm.com/documentation/cloud/deployment-operations/integrations/index#decide-whether-licops-also-chooses-the-server).

## What you deploy

LicOps runs in your own network, next to your scheduler. It only calls out to OpenLM Platform. Nothing on the OpenLM Platform side opens a connection to it.

The following table lists the components you deploy:

| Component | Where it runs | What it does |
| --- | --- | --- |
| The Router, in LicOps mode | A Linux host with Docker, or your Kubernetes cluster, with MongoDB and Redis | Answers admit, dispatch, and release requests. Its browser page connects it to OpenLM Platform. |
| Slurm or LSF adapters | Your scheduler's controller and submit hosts | Make the three requests at the submission, start and end of every licensed job. OpenLM supplies them. |
| Kubernetes admission webhook | Your Kubernetes cluster | Makes the three requests for pods that you annotate. Optional. |
| OpenLM Broker | Each license server in a pool | Reports the server, its licenses, and its health to OpenLM Platform. You might already run it. |

You define admission rules and reservations in OpenLM Platform, under **LicOps Configuration**. The Router collects them about every 10 seconds, the same way a failover Router collects its port mappings.

## LicOps terms

The following table lists the names you meet when you work with LicOps:

| Name | What it is |
| --- | --- |
| OpenLM Router | The program LicOps runs on. In LicOps mode, its status reads `Load balancer mode active` and its mode is `loadBalancer`. |
| **LicOps Configuration** | The OpenLM Platform app, under **Licenses and Features**, where you see the LicOps settings and define admission rules and reservations. It also configures a failover OpenLM Router, where it shows **Port Mappings**. |
| Pool | Every license server that serves one vendor daemon and feature, such as `MLM:MATLAB`. |
| Session | One job's seats, from admit to release, named by a session ID the caller generates. |
| Listen port | Port `30001` on the LicOps host. It matters only if you route checkouts through LicOps. |
| Router UI | The browser page on the LicOps host where you connect LicOps to OpenLM Platform. |
| Client Type `Router` | The identity client type LicOps signs in with, the same as a failover Router. |
| OpenLM Broker | The OpenLM component on each license server that reports the server, its licenses, and its health to OpenLM Platform. |

## Current limitations

LicOps has these limitations:

- **Tested with FlexLM only**: Pools and checkouts are FlexLM vendor daemons and features.
- **Seats are counted, not held**: A user who checks out a license without going through LicOps, from a workstation for example, still takes a seat. LicOps sees that seat in the next in-use figure from OpenLM Platform, not before.
- **Reservations cap seats but do not hold them**: A reservation limits how many seats LicOps hands out on a server. It does not set seats aside on the license server. See [Cap seats on a schedule](https://www.openlm.com/documentation/cloud/deployment-operations/reservations).
- **LSF support is in early access**: validate the adapters on a non-production queue before you rely on them. Each LSF job can ask for one vendor and feature, while the Slurm adapter admits several licenses for one job.
- **The Kubernetes interception chain is pre-release**: The sidecar and init-container images are development builds. Calling the API directly from a Kubernetes job is not affected.
- **Ports 8100 and 8101 are administration interfaces**: Allow access to them only from your administration network and from the hosts that submit jobs, and do not publish them to the internet. Publish only the license ports your clients use. See [System requirements](https://www.openlm.com/documentation/cloud/deployment-operations/system-requirements).

## In this section

Work through the pages in order:

1. [System requirements](https://www.openlm.com/documentation/cloud/deployment-operations/system-requirements): the license, host, datastores, network, and OpenLM Platform access LicOps needs.
2. [Deploy OpenLM LicOps](https://www.openlm.com/documentation/cloud/deployment-operations/deployment): run the Router in LicOps mode with Docker Compose. To deploy on Kubernetes, see [Deploy on Kubernetes](https://www.openlm.com/documentation/cloud/deployment-operations/deploy-kubernetes).
3. [Configure OpenLM LicOps](https://www.openlm.com/documentation/cloud/deployment-operations/configuration): connect LicOps to OpenLM Platform and check that it sees your pools.
4. [Control placement with admission rules](https://www.openlm.com/documentation/cloud/deployment-operations/admission-rules): optional, decide which server each job lands on.
5. [Cap seats on a schedule](https://www.openlm.com/documentation/cloud/deployment-operations/reservations): optional, limit the seats LicOps hands out during set hours.
6. [Connect workloads](https://www.openlm.com/documentation/cloud/deployment-operations/integrations/index): wire Slurm, LSF, Kubernetes, or your own tools to LicOps.
7. [Operate OpenLM LicOps](https://www.openlm.com/documentation/cloud/deployment-operations/operations): see what LicOps is holding and find out why a job was denied.
8. [Troubleshooting](https://www.openlm.com/documentation/cloud/deployment-operations/troubleshooting): what the common symptoms mean.
9. [API reference](https://www.openlm.com/documentation/cloud/deployment-operations/reference): every request, response, and deny reason.
