> ## Documentation Index
> Fetch the complete documentation index at: https://wiki.krkn.tech/llms.txt
> Use this file to discover all available pages before exploring further.

# krkns

> The Krkn Server (krkns) is the primary controller for the Krkn Application

The Krkn Server is the primary controller and ochestrator of the distributed hash cracking network.

<img src="https://mintcdn.com/krakentechllc/AEChm_hbncj06v_j/images/Krkn-_28.png?fit=max&auto=format&n=AEChm_hbncj06v_j&q=85&s=7ee4b98d111128347492045b5082d185" alt="Krkn 28" width="1306" height="528" data-path="images/Krkn-_28.png" />

## Licensing

The Krkn Server requires a `license.json` file in order to function. This file must be placed in the `~/.config/krkn` folder. This file is signed and if manipulated the Krkn server will not operate.

<img src="https://mintcdn.com/krakentechllc/Nq7ZZAHVB4nUtjR9/images/image-5.png?fit=max&auto=format&n=Nq7ZZAHVB4nUtjR9&q=85&s=85f3bbb833f5696848a9ad66be44361d" alt="Image" width="1168" height="160" data-path="images/image-5.png" />

## Environment Variables

The Krkn Server supports an optional environment variable for the `data` folder. The `data` folder contains the hash database and, depending on use, this can become large. It is possible to select a location for this by setting the `KRKN_DATA` environment variable to your preferred location.  This must remain set so it is recommended to add it to your profile.

## Config

The `config` subcommand can be used to persist settings across executions.

* **Interface**: The active interface to listen on (Tailscale defaults to port only) (string)
* **Port**: The port to serve on (int)
* **Max Runtime**: The maximum duration a job is allowed to run for in hours (int)
* **Optimized Kernels**: Utilize optimized kernels across attacks (bool)
* **Workload Profile**: The amount of resources allocated to a job \[1-4 inclusive] (int)
* **Tailscale**: Use the Tailscale Tailnet (bool)
* **QUIC**: Use HTTP/3 (QUIC) for communications (bool)
* **Insecure**: Do not require transport credentials (bool)
* **Debug**: Verbose output (bool)
* **Hostname**: The Tailscale Hostname to use (defaults to system Hostname if not set)

<img src="https://mintcdn.com/krakentechllc/AEChm_hbncj06v_j/images/Krkn-_26.png?fit=max&auto=format&n=AEChm_hbncj06v_j&q=85&s=609608c35c2816efbfc44830f07ea863" alt="Krkn 26" width="1202" height="616" data-path="images/Krkn-_26.png" />

## Get

The `get` subcommand can be used to query the current configurations.

<img src="https://mintcdn.com/krakentechllc/3Pp70L3IOotR2kRa/images/Krkn-_68.png?fit=max&auto=format&n=3Pp70L3IOotR2kRa&q=85&s=7428f625389850719af6b4ab5c3119b9" alt="Krkn 68" width="606" height="428" data-path="images/Krkn-_68.png" />

## Set

The `set` subcommand can be used to alter a configuration value.

<img src="https://mintcdn.com/krakentechllc/AEChm_hbncj06v_j/images/Krkn-_25.png?fit=max&auto=format&n=AEChm_hbncj06v_j&q=85&s=d8eacc018c6e55d92c962e61b6c5fc33" alt="Krkn 25" width="818" height="72" data-path="images/Krkn-_25.png" />

## Unset

The `unset` subcommand can be used to clear a single configuration value.

<img src="https://mintcdn.com/krakentechllc/AEChm_hbncj06v_j/images/Krkn-_24.png?fit=max&auto=format&n=AEChm_hbncj06v_j&q=85&s=8e487505fa3f8a80e5c1e73aad733aa6" alt="Krkn 24" width="782" height="78" data-path="images/Krkn-_24.png" />

## Clear

The `clear` subcommand can be used to clear all settings.

## Serve

The `serve` subcommand can be used to start the Krkn Server. If no flags are set, the cache will be used to retrieve settings.

<img src="https://mintcdn.com/krakentechllc/AEChm_hbncj06v_j/images/Krkn-_23.png?fit=max&auto=format&n=AEChm_hbncj06v_j&q=85&s=a729f4edbac7f792fa83f473575eb69d" alt="Krkn 23" width="1240" height="600" data-path="images/Krkn-_23.png" />

<img src="https://mintcdn.com/krakentechllc/AEChm_hbncj06v_j/images/Krkn-_22.png?fit=max&auto=format&n=AEChm_hbncj06v_j&q=85&s=ee6867cd5c83a31f0cd9879c16c931a7" alt="Krkn 22" width="1300" height="572" data-path="images/Krkn-_22.png" />

# Tailscale

## TS Net

Because this is using the TSNet it will need to be configured with its own address on tailscale. When you start the server you will be prompted to either supply an environment variable or click a link to approve the new node. An admin must approve this link before it can serve on Tailscale.

<img src="https://mintcdn.com/krakentechllc/GFpIKyEtK9L9kR5r/images/image-8.png?fit=max&auto=format&n=GFpIKyEtK9L9kR5r&q=85&s=645d4982077e8f72f5318374aca51363" alt="Image" width="2298" height="284" data-path="images/image-8.png" />

## Hostname

The hostname that will be registered on Tailscale will be either what is set for hostname in the configs + -krkn or the hosts default \<hostname>-krkn. This is to make it easily identifiable.

## Ready State

When the server is ready and listening on the TSNet you will not see it in ss or ps/netstat commands. You will see a notification indicating the **AuthLoop** state is: `Running; done`

# Dead Instrument Removal

<img src="https://mintcdn.com/krakentechllc/3Pp70L3IOotR2kRa/images/Krkn-_6.png?fit=max&auto=format&n=3Pp70L3IOotR2kRa&q=85&s=2e1d7db5abaf6719cbf351d30e3f1bb9" alt="Krkn 6" width="1634" height="690" data-path="images/Krkn-_6.png" />

# GPU-Aware Scheduling

When more than one Tentacle worker is polling for work at the same time, the krkns conductor does not simply hand out batches in FIFO order. It looks at each worker's published GPU capability score (see [Tentacle → GPU Capability Scoring](/tools/Krkn/tentacle)) and matches it against the **kind** of hash each queued batch is targeting:

* **Slow hashes** (bcrypt, scrypt, DCC2, Argon2, ...) → prefer the highest-scoring host
* **Fast hashes** (NTLM, MD5, SHA1, ...) → prefer the lowest-scoring host

The classification is made via `hashkat.Mode.IsFastHash()` against the batch's hash type, so the routing is fully data-driven from the existing Hashkat mode tables — no separate config file to maintain.

## Routing Rules

Selection happens every time a worker polls the conductor for new work. The rules are intentionally a **soft preference**, never a hard lock:

| Polling worker | Queue contents      | Strong peer state         | Result                                                                    |
| -------------- | ------------------- | ------------------------- | ------------------------------------------------------------------------- |
| weak           | slow only           | n/a                       | weak takes the slow batch (no other choice)                               |
| weak           | fast only           | n/a                       | weak takes the fast batch (no other choice)                               |
| weak           | slow + fast         | strong peer **idle**      | weak takes fast, slow waits for the strong peer's next poll               |
| weak           | slow + fast         | strong peer **busy**      | weak takes the slow batch — don't park work for someone who can't grab it |
| weak           | slow + fast         | no strong peer registered | weak takes the slow batch                                                 |
| strong         | anything            | n/a                       | strong takes a slow batch first if any exist, else a fast one             |
| any            | unclassifiable meta | n/a                       | falls back to FIFO                                                        |
| any            | empty               | n/a                       | nothing assigned this poll                                                |

<Note>
  "Strong peer exists" only counts peers that have **spare capacity right now** (`ActiveLeases < Capacity`). A strong-but-busy worker does NOT cause the conductor to hold slow work back, otherwise the slow batch would sit in the queue waiting for someone who physically can't take it on their next poll.
</Note>

<Tip>
  No worker is ever left idle. If the queue has any unleased candidate, the polling worker gets something — the score only affects *which* item it gets, never *whether* it gets one.
</Tip>

## Single-Worker Behavior

When only one Tentacle worker is registered the score system has nothing to compare against, so every batch goes to that worker in FIFO order. The scoring layer is invisible until you scale out to two or more workers with meaningfully different GPUs.

# Live Job Status

The krkns conductor maintains an in-memory cache of the most recent hashcat status snapshot for every running batch. Snapshots arrive over the Orchestra `ReportUpdate` RPC — every Tentacle worker samples its `kcat.Hashcat.GetStatus()` every 5 seconds and forwards the result.

Cached fields per batch:

* Session, time started, time estimated (absolute + relative)
* Progress (`X/Y (Z%)`) and recovered (`X/Y (Z%) Digests, X/Y (Z%) Salts`)
* Numeric recovered count
* Total hashes/sec
* Reporting instrument ID and snapshot timestamp

The cache is keyed on `batch_id` (the orchestra `work_id` minus the `batch-` prefix, which matches the `jobs.batch_id` column in the database) and is **purged** the moment a batch completes or fails — successful or otherwise — so it never grows beyond what is currently running.

Live fields are merged into the response of every `kcat.GetJob` and `kcat.ListJobs` call, which means clients see live progress without making extra round-trips. The krknc CLI surfaces these in `krknc job get` and `krknc job list`. See [krknc → Jobs](/tools/Krkn/krknc#jobs) for the table layout.

<Info>
  Live status is **not** persisted to the SQLite database. Status snapshots arrive every 5 seconds while a job is running and writing them to disk would dominate I/O for no benefit — the historical record on disk only captures what is needed to resume work after a server restart, while the in-memory cache covers the realtime UI.
</Info>
