# Tenzir Node Unreleased

## 💥 Breaking Changes

### TQL type syntax for package UDOs

May 31, 2026 · [@mavam](https://github.com/mavam), [@codex](https://github.com/codex) · [#6242](https://github.com/tenzir/tenzir/pull/6242)

Package UDO argument types now use TQL type names, such as `int`, `uint`, and `float`, instead of legacy names such as `int64`, `uint64`, and `double`. List types use TQL syntax, for example `type: "[int]"` in YAML.

For example, a package operator argument like this now materializes `$limit` as `int64`:

```yaml
args:
  named:
    - name: limit
      type: int
      default: 1000
```

## 🚀 Features

### Event-time windowing with the window operator

Jun 4, 2026 · [@jachris](https://github.com/jachris) · [#6253](https://github.com/tenzir/tenzir/pull/6253)

The new `window` operator groups streaming events into event-time windows and runs a subpipeline for each window:

```tql
window size=10min, every=1min, on=ts {
  summarize failures=count()
  start = $window.start
  end = $window.end
}
```

Unlike `every`, which reruns a subpipeline on a wall-clock schedule, `window` operates on **event time**: it assigns each event to windows by the timestamp that `on` evaluates to, and its internal clock is driven entirely by the timestamps of the incoming events. Windows are aligned to the Unix epoch and are either tumbling (omit `every`) or overlapping/hopping (`every < size`).

`tolerance` sets how much out-of-order lag the clock waits for before a window closes; events that arrive after their window closed are dropped with a warning.

`idle_timeout` makes `window` also well suited to low-volume streams: a window is emitted once it has been inactive for the given duration, so results arrive promptly even when the next event is far off, instead of waiting for it or for the end of the input.

Each window’s `$window.start` and `$window.end` are available inside the subpipeline, which may also end in a sink.

### Chunk stream operators

Jun 1, 2026 · [@aljazerzen](https://github.com/aljazerzen), [@codex](https://github.com/codex)

TQL now includes `read_chunks` and `write_chunks` for converting between byte streams and records with a `bytes` field.

For example, you can capture arbitrary output as records and turn it back into a byte stream later:

```tql
from {line: "hello"}, {line: "world"}
write_lines
read_chunks
write_chunks
read_lines
```

This makes it easier to inspect, buffer, transform, and roundtrip chunked byte streams inside a pipeline.

### Unix domain socket operators

May 30, 2026 · [@mavam](https://github.com/mavam), [@codex](https://github.com/codex)

Tenzir now supports Unix stream sockets in the new executor with three dedicated operators:

* `from_unix_socket` connects to a Unix domain socket and parses incoming bytes.
* `accept_unix_socket` listens on a socket path and parses each accepted client stream.
* `to_unix_socket` connects to a socket path and writes serialized bytes.

These operators replace the previous `uds=true` options on `from_file` and `to_file`. Use `from_unix_socket` or `to_unix_socket` for Unix domain socket clients, and keep `from_file` and `to_file` for regular filesystem and object-storage access.

```tql
accept_unix_socket "/run/collector.sock" {
  read_json
}
```

```tql
to_unix_socket "/run/collector.sock" {
  write_ndjson
}
```

### Recursive record sorting

May 28, 2026 · [@mavam](https://github.com/mavam), [@codex](https://github.com/codex)

The `sort` function now recursively sorts record fields wherever they occur in the sorted value, including records inside lists. Nested list element order is preserved unless the list itself is being sorted.

### Delimited byte output

May 28, 2026 · [@mavam](https://github.com/mavam), [@codex](https://github.com/codex)

The new `write_delimited` operator writes one `string` or `blob` value per event and appends a separator after each value:

```tql
from {data: "a"}, {data: "b"}
to_stdout {
  write_delimited data, "|"
}
```

This outputs:

```txt
a|b|
```

This lets you frame compact JSON, GELF over TCP with a null byte, or other preformatted messages without adding escaping or serialization in the byte writer.

### Microsoft SQL Server source operator

May 26, 2026 · [@tobim](https://github.com/tobim), [@codex](https://github.com/codex)

The new `from_microsoft_sql` operator reads rows from Microsoft SQL Server:

```tql
from_microsoft_sql table="dbo.users",
                   host="sql.example.net",
                   user="tenzir",
                   password=secret("mssql-password"),
                   database="telemetry"
```

It supports table reads, custom `sql` or `query` statements, schema inspection with `show="tables"` and `show="columns"`, SQL authentication, secret-backed passwords, TLS, and live polling via integer tracking columns. Result decoding covers SQL Server scalar values including integers, booleans, floats, decimals, money values, strings, binary data, `uniqueidentifier`, date/time values, XML, and JSON stored as text.

### Prometheus Remote Write sink

May 15, 2026 · [@mavam](https://github.com/mavam), [@codex](https://github.com/codex)

The new `to_prometheus` operator sends metric events to Prometheus Remote Write receivers.

For example:

```tql
from {
  metric: "http_requests_total",
  value: 42,
  timestamp: 2026-05-15T10:00:00Z,
  labels: {method: "GET", status: 200},
}
to_prometheus "https://prometheus.example/api/v1/write"
```

The operator supports Prometheus Remote Write v1 by default and can send Remote Write v2 payloads with `protobuf_message="io.prometheus.write.v2.Request"`.

### SQS receive controls

May 13, 2026 · [@mavam](https://github.com/mavam), [@codex](https://github.com/codex) · [#6167](https://github.com/tenzir/tenzir/pull/6167), [#6174](https://github.com/tenzir/tenzir/pull/6174)

The `from_amazon_sqs` operator now gives you explicit control over how messages are received from SQS. Use `keep_messages=true` to inspect or replay messages without removing them from the queue, `batch_size=<1..10>` to control how many messages each receive request may return, and `visibility_timeout=<duration>` to override the queue visibility timeout for received messages:

```tql
from_amazon_sqs "events", keep_messages=true, batch_size=10,
  visibility_timeout=30s
```

By default, `from_amazon_sqs` keeps deleting each received message after emitting it. With `keep_messages=true`, SQS makes the message visible again after the queue’s visibility timeout.

## 🔧 Changes

### Region derivation and endpoint logging for SQS

May 13, 2026 · [@lava](https://github.com/lava) · [#6168](https://github.com/tenzir/tenzir/pull/6168)

The `from_amazon_sqs` and `to_amazon_sqs` operators now derive the AWS region from a queue URL when `aws_region` is not set, so passing a full URL such as `https://sqs.us-west-2.amazonaws.com/123456789012/my-queue` works without having to specify the region again:

```tql
from_amazon_sqs "https://sqs.us-west-2.amazonaws.com/123456789012/my-queue"
```

Previously, this would fall back to the SDK default region and fail with a SigV4 signature mismatch. Explicit `aws_region`, resolved IAM credentials, and the SDK default still apply in that order when the URL has no region (for example VPC endpoints, LocalStack, or an `AWS_ENDPOINT_URL` override).

SQS API errors and HTTP failures now also include the endpoint URL in their log lines and diagnostic notes, which makes it easier to tell which queue produced an error when multiple SQS pipelines run side by side.

## 🐞 Bug Fixes

### Rebuild memory limits

Jun 2, 2026 · [@tobim](https://github.com/tobim), [@codex](https://github.com/codex) · [#6216](https://github.com/tenzir/tenzir/pull/6216)

Rebuilds now limit how much partition data they load into memory at once. This reduces the risk that automatic rebuilds or `tenzir-ctl rebuild start` cause the node to run out of memory when many partitions are selected.

When memory is scarce, rebuilds load fewer partitions in one batch and retry the remaining partitions later instead of materializing the full selected input set up front.

### Static pipeline startup validation

Jun 2, 2026 · [@tobim](https://github.com/tobim), [@codex](https://github.com/codex) · [#6248](https://github.com/tenzir/tenzir/pull/6248)

Tenzir now validates all configured and packaged pipelines before starting any of them during node startup. Previously, a deployment with multiple configured pipelines could start some valid pipelines and only then abort after discovering that a later pipeline was invalid.

### Diagnostics for lambda-valued let bindings

May 31, 2026 · [@mavam](https://github.com/mavam), [@codex](https://github.com/codex) · [#6241](https://github.com/tenzir/tenzir/pull/6241)

Invalid lambda-valued `let` bindings now produce a focused diagnostic instead of cascading into a generic evaluation warning and an internal error.

For example, `let $f = (x => x + 1)` now points at the lambda and suggests inlining it at the use site.

### Complete GeoIP record enrichment

May 29, 2026 · [@mavam](https://github.com/mavam), [@codex](https://github.com/codex) · [#6239](https://github.com/tenzir/tenzir/pull/6239)

GeoIP enrichment now includes all fields from MaxMind records. Previously, records containing `uint128` values could stop materializing subsequent fields, which could omit later enrichment data from affected databases.

### Arrow IPC file support in read\_feather

Apr 28, 2026 · [@tobim](https://github.com/tobim), [@codex](https://github.com/codex) · [#6087](https://github.com/tenzir/tenzir/pull/6087)

The `read_feather` operator can now read Arrow IPC file containers in addition to Arrow IPC streams:

```tql
from_file "partition.feather" {
  read_feather
}
```

This fixes reading Tenzir archive partition files directly. If an IPC file contains a Tenzir event envelope, `read_feather` unwraps the event payload and preserves the import time; IPC files without Tenzir schema metadata use the schema name `undefined`.