# Tenzir Node v5.17.0

This release introduces user-defined operators in packages, allowing you to extend Tenzir with custom operators defined in TQL files. It also adds list manipulation functions, a recursive search function, and improved memory management.

## 🚀 Features

### User-defined operators in packages

Oct 9, 2025 · [@tobim](https://github.com/tobim) · [#5496](https://github.com/tenzir/tenzir/pull/5496)

This extends the package format with user-defined operators. A packaged operator can be used from a pipeline after the package is installed on a node. Package operators are defined in `.tql` files the `operators` subdirectory of a package. Once installed, the operators can be called by its ID, which is constructed from the filesystem path.

Here is an example from a hypothetical MISP package. This is the directory structure with an operator:

```plaintext
└── misp
    └── operators
        └── event
            └── to_ocsf.tql
```

And you can use the operator in TQL:

```dart
misp::event::to_ocsf
```

### Improved list manipulation

Oct 6, 2025 · [@mavam](https://github.com/mavam), [@IyeOnline](https://github.com/IyeOnline) · [#5471](https://github.com/tenzir/tenzir/pull/5471)

We have added two new functions that make managing set-like lists easier.

The `add` function ensures uniqueness when building lists. Perfect for maintaining deduplicated threat intel feeds or collecting unique user sessions:

```tql
from {xs: [1]},
     {xs: [2]},
     {xs: []}
select result = xs.add(2)
```

```tql
{result: [1,2]}
{result: [2]}
{result: [2]}
```

The `remove` function cleans up your lists by eliminating all occurrences of unwanted elements. Ideal for filtering out known-good domains from suspicious activity logs or removing false positives from alert lists:

```tql
from {xs: [1, 2, 1, 3], y: 1},
     {xs: [4, 5], y: 1},
select result = xs.remove(y)
```

```tql
{result: [2, 3]}
{result: [4, 5]}
```

### Checking if a value exists in another value

Oct 2, 2025 · [@raxyte](https://github.com/raxyte) · [#5493](https://github.com/tenzir/tenzir/pull/5493)

The new `contains()` function recursively searches for a value within data structures and returns `true` if found, `false` otherwise.

## 🔧 Changes

### Memory usage when importing many different schemas at once

Oct 10, 2025 · [@tobim](https://github.com/tobim), [@jachris](https://github.com/jachris) · [#5508](https://github.com/tenzir/tenzir/pull/5508)

Previously, importing a high volume of highly heterogeneous events could lead to memory usage issues because of internal buffering that was only limited on a per-schema basis. With the introduction of a global limit across all schemas, this issue has now been fixed. The configuration option `tenzir.max-buffered-events` can be used to tune the new buffering limits.

## 🐞 Bug Fixes

### Fixed spawning of demo nodes

Oct 13, 2025 · [@lava](https://github.com/lava) · [#5504](https://github.com/tenzir/tenzir/pull/5504)

Fixed an issue that would cause demo nodes on <https://app.tenzir.com> to fail when spawning.

### Handle spaces in filesystem paths

Oct 1, 2025 · [@raxyte](https://github.com/raxyte) · [#5499](https://github.com/tenzir/tenzir/pull/5499)

File paths containing spaces are now properly handled by operators.

[ Download on GitHub ](https://github.com/tenzir/tenzir/releases/tag/v5.17.0)

[Get the release artifacts and source code.](https://github.com/tenzir/tenzir/releases/tag/v5.17.0)