> For the complete documentation index, see [llms.txt](https://edseries-plugins.gitbook.io/p/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://edseries-plugins.gitbook.io/p/edlang/reference/performance.md).

# Performance

EdLang is built to cost nothing on packets that don't need it and very little on those that do.

* **No placeholder, no decoding.** The packet translator reads the raw bytes of each outgoing packet and looks for the markers eight bytes at a time. A packet without one is passed on untouched: no decoding, no Adventure components, no JSON.
* **No main thread work.** Packets are handled on the network threads. Lang files are read in parallel, starting while the worlds load; `/edlang reload` reads them in the background. Storage and chat translation have their own threads.
* **Caches without locks.** Each language keeps translated texts in memory, so a line seen once is a lookup the next time. Lang values are compiled once, on first use. Settings are an immutable snapshot swapped on reload.
* **Only real changes are sent.** A language change re-sends a player's texts once, half a second after their last change. Menus only redraw slots that changed.

## Numbers

One thread, JDK 21, nanoseconds per operation after warm-up (`bench/`, see below):

| Raw packet scan (no placeholder)                      |                |
| ----------------------------------------------------- | -------------- |
| 64 B packet                                           | 17 ns          |
| 300 B packet                                          | 57 ns          |
| 2 KB packet                                           | 351 ns         |
| 8 KB packet                                           | 1.4 µs         |
| 64 KB packet (chunk data)                             | 11.9 µs        |
| Worst case, `%` and `{` every few bytes: 2 KB / 64 KB | 488 ns / 17 µs |

| Translating a text line                                  |         |
| -------------------------------------------------------- | ------- |
| Component without a placeholder                          | 17 ns   |
| Component with a placeholder and arguments (seen before) | 93 ns   |
| Component with 2 placeholders in 4 parts                 | 210 ns  |
| A line never seen before (cold)                          | 1.9 µs  |
| String translate (seen before)                           | 10.6 ns |
| For comparison: one legacy text round trip               | 232 ns  |
| For comparison: one JSON text round trip                 | 827 ns  |

## Running the benchmark

`bench/es/edwardbelt/edlang/lang/Bench.java` checks the placeholder engine (27 checks) and, with the argument `bench`, prints the numbers above for your machine. It is not part of the plugin jar. Compile it against the built plugin classes and the Paper API:

```
mvn -q package dependency:build-classpath -Dmdep.outputFile=cp.txt
javac -cp "target/classes;$(cat cp.txt)" -d target/bench bench/es/edwardbelt/edlang/lang/Bench.java
java -cp "target/bench;target/classes;$(cat cp.txt)" es.edwardbelt.edlang.lang.Bench bench
```

(Use `:` instead of `;` on Linux and macOS.)
