---
title: "Group Sequencer"
description: "group and sequence TenXObjects"
source: "https://github.com/log-10x/modules/tree/main/pipelines/run/units/transform/group/unit.yaml"
icon: "material/select-group"

---
Groups [TenXObjects](https://doc.log10x.com/api/js/#TenXObject "Provide structured, reflective access to log/trace events read from input(s).") for filtering, aggregation, and output as single units.

Log events read from an input stream can serve as a part of a larger logical group. A typical
example of events spanning multiple sub-events are [stack traces](https://stackoverflow.com/questions/3988788/what-is-a-stack-trace-and-how-can-i-use-it-to-debug-my-application-errors){target="\_blank"} where each
line within the stack trace may be logged as a separate line.

Grouping enables:

- **Identify** groups consuming the most storage and analytics resources
  using [aggregators](https://doc.log10x.com/run/aggregate/ "Aggregate and summarize TenXObjects to publish as metrics").
  This is especially valuable when storing stack traces than span 100s of lines and consume a significant amount of resources.
- **Filter** unnecessary groups such as 'noisy' stack traces via [group filters](#groupfilters "JavaScript expressions TenXObject instance/group must evaluate as truthy against") and output [receivers](https://doc.log10x.com/run/output/receive "Filter and sample TenXObjects based on per-node budget sampling or a declarative field-set mute file").
- **Optimize** storage of multi-line events by [losslessly compacting](https://doc.log10x.com/run/transform/#compact) them as a composite instances to reduce storage footprint by \>  **75%** when compared to storing individual events.

## :material-group: Group Heads

tenXObjects which evaluate as truthy against [groupExpressions](https://doc.log10x.com/run/transform/group/#groupexpressions "JavaScript expressions TenXObject instance/group must evaluate as truthy against to be set as group head") are marked as starting of a new group (i.e. a _group head_).

All subsequent TenXObjects read from the same input will join the current group until either:

- Another group is started marked by a subsequent instance which evaluates as truthy against `groupExpressions`.
- The number of TenXObjects in the current group exceeds [groupMaxSize](#groupmaxsize "max number of objects to place in a group").
- The [groupFlushTimeout](#groupflushtimeout "interval to flush a pending TenXObjects group") elapses.

At that point the group is sealed as new composite TenXObject and flushed forward for aggregation and output.
Each composite TenXObject returns the number of instances grouped within it via the [groupSize](https://doc.log10x.com/api/js/#TenXObject+groupSize "If the current instance is a logical group formed via groupExpressions returns the number of tenxObject within the group.") member.

**` Example #1 - timestamps + negators (default)`**

The TenXObject [constructor](https://doc.log10x.com/run/transform/script/object/ "Initialize TenXObject instances at runtime using JavaScript.") below marks an instance as the head of a group if:

- its [text](https://doc.log10x.com/api/js/#text-string) field [starts with](https://doc.log10x.com/api/js/#TenXString.startsWith) an [indicator](#groupindicators) value.
- its [timestamped](https://doc.log10x.com/api/js/#timestamped-boolean) field is true.

```js
export class GroupTemplate extends TenXTemplate {

    static get isGroup() {

        // https://doc.log10x.com/run/initialize/group/#groupindicators
        if (this.startsWith(TenXEnv.get("groupIndicators"))) {
            return true;
        }

        return this.timestamped;
    }

    // This constructor is invoked by the engine once for each unique TenXTemplate discovered
    // at runtime based on log event structures
    constructor() {
        GroupTemplate.isGroup = this.isGroup();
     }
}
```

**` Example #2 - Group ISO_8601 events`**

The TenXObject below marks an instance as the head of a group if it
has an [ISO\_8601](https://stackoverflow.com/questions/3914404/how-to-get-current-moment-in-iso-8601-format-with-date-hour-and-minute){target="\_blank"} timestamp:

```js
export class IsoTemplate extends TenXTemplate {

  constructor() {
    IsoTemplate.isGroup = this.timestampFormat() == "yyyy-MM-dd'T'HH:mm'Z'";
  }
}
```

**` Example #3 - Group Linux Call Traces`**

The constructor below groups Linux Call Traces (see [example](https://syzkaller.appspot.com/text?tag=CrashLog&x=17f5743fe00000){target="\_blank"})
by folding lines that are part of a trace (e.g., an <IRQ> interrupt marker, or end with
a memory address) into a logical group.

```js
class NixTemplate extends TenXTemplate {

  constructor() {  

   // is event is call trace interrupt marker
    if (this.contains("<IRQ>")) {
        NixTemplate.isGroup = false;
    } else 
 
    // does event end in a '/'' + hex memory address (e.g., 0x16d0) ?
    // use the token() function to access the last + penultimate instance values
    if (this.token(-2) == "/") && (startsWith(this.token(-1), "0x")) {
        NixTemplate.isGroup = false;
    }
  }
}
```

## :material-filter-multiple-outline: Group Filters

The [groupFilters](#groupfilters "JavaScript expressions TenXObject instance/group must evaluate as truthy against") option provides a mechanism for filtering TenXObject groups
based on conditions that relate to the entire group (e.g., filter entire stack traces vs. individual lines).

The [YAML](https://doc.log10x.com/config/yaml/) config below places a limit of a maximum of 'SocketException' 1000 groups per minute
using a [cyclical counter](https://doc.log10x.com/api/js/#TenXCounter.inc):

```yaml
group:
  filters: 'this.includes("SocketException") && (this.groupSize > 1) ? (TenXCounter.incAndGet("socketException", 1, "1m") > 1000) : true'
```

A filter may also be set to a function loaded from a [JavaScript config](https://doc.log10x.com/config/javascript/) file. For example:

```yaml
group:
  filters: socketExceptionFilter()
```

Where the JavaScript file would contain:

```js

// @loader: tenx

public class MyFilter extends TenXObject {

  function socketExceptionFilter() {

    return this.includes("SocketException") && (this.groupSize > 1) ?
      (TenXCounter.incAndGet("socketException", 1, "1m") > 1000) : 
      true
  }

}

```

## :material-regex: Event Source

Input streams that read data from multiple locations (e.g., log files, pods, hosts)
can utilize source [patterns](https://doc.log10x.com/run/input/stream/#inputsourcepattern "a regex pattern used to extract the 'source' value") and
[fields](https://doc.log10x.com/run/input/stream/#inputsourcefields "JSON fields from which to extract the 'source' value") to assign each event
a logical origin (e.g., log file, host address).

This value ensure each TenXObject is grouped alongside instances
from the same source and is accessible via the [source](https://doc.log10x.com/api/js/#TenXObject+source "Returns the source value assigned to this instance by its input source pattern") member.

## :material-wrench-outline: Config Files

To configure the Group sequencer unit, [:material-cog: Edit](https://doc.log10x.com/config/app/#module-config "Learn how to edit app and module configurations") these files.  

Below is the default configuration from: [group/config.yaml](https://github.dev/log-10x/config/blob/main/pipelines/run/transform/group/config.yaml "group/config.yaml"){target="\_blank"}.  
  
<div class="edit-options">
    <a class="md-button tenx-edit-online-button" data-tooltip="Edit online on github.dev" href="https://github.dev/log-10x/config/blob/main/pipelines/run/transform/group/config.yaml" target="_blank" rel="noopener noreferrer">
        <span class="twemoji" style="margin-right: 0.3rem;">
            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
                <path d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"></path>
            </svg>
        </span> Edit Online
    </a>
    <button class="md-button tenx-config.yaml0-edit-button" data-tooltip="Edit configuration file" data-dialog-id="config-yaml0-dialog">
        <span style="margin-right: 0.3rem;">
            <span class="twemoji">
                <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
                    <path d="M20.71,7.04C21.1,6.65 21.1,6 20.71,5.63L18.37,3.29C18,2.9 17.35,2.9 16.96,3.29L15.12,5.12L18.87,8.87M3,17.25V21H6.75L17.81,9.93L14.06,6.18L3,17.25Z"></path>
                </svg>
            </span>
        </span>Edit Locally
    </button>
</div>

<dialog id="config-yaml0-dialog" class="md-dialog md-dialog--editor">
    <div class="editor-dialog-wrapper">
        <div class="editor-dialog-header">
            <span class="editor-dialog-title">Edit config.yaml Locally</span>
            <div class="editor-header-actions">
                <button class="editor-toolbar-btn yaml-editor-locations" data-tooltip="Save">
                    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="currentColor" d="M5 20h14v-2H5v2m14-9h-4V3H9v8H5l7 7 7-7Z"></path></svg>
                </button>
                <button class="editor-toolbar-btn yaml-editor-reset" data-tooltip="Reset to default">
                    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="currentColor" d="M12.5 8c-2.65 0-5.05 1-6.9 2.6L2 7v9h9l-3.62-3.62c1.39-1.16 3.16-1.88 5.12-1.88 3.54 0 6.55 2.31 7.6 5.5l2.37-.78C21.08 11.03 17.15 8 12.5 8z"></path></svg>
                </button>
                <button class="editor-toolbar-btn yaml-editor-copy" data-tooltip="Copy to clipboard">
                    <svg class="icon-copy" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="currentColor" d="M19 21H8V7h11m0-2H8a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h11a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2m-3-4H4a2 2 0 0 0-2 2v14h2V3h12V1Z"></path></svg>
                    <svg class="icon-check" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" style="display:none;"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg>
                </button>
                <span class="header-divider"></span>
                <button class="editor-toolbar-btn yaml-editor-fullscreen" data-tooltip="Fullscreen">
                    <svg class="icon-maximize" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="currentColor" d="M5,5H10V7H7V10H5V5M14,5H19V10H17V7H14V5M17,14H19V19H14V17H17V14M10,17V19H5V14H7V17H10Z"></path></svg>
                    <svg class="icon-minimize" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" style="display:none;"><path fill="currentColor" d="M5,16H8V19H10V14H5V16M14,14V19H16V16H19V14H14M16,5V8H19V10H14V5H16M10,5V10H5V8H8V5H10Z"></path></svg>
                </button>
                <span class="header-divider"></span>
                <button class="editor-toolbar-btn editor-dialog-close" onclick="closeDialog('config-yaml0-dialog')" data-tooltip="Close">
                    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="currentColor" d="M19,6.41L17.59,5L12,10.59L6.41,5L5,6.41L10.59,12L5,17.59L6.41,19L12,13.41L17.59,19L19,17.59L13.41,12L19,6.41Z"></path></svg>
                </button>
            </div>
        </div>
        <div class="editor-dialog-content">
            <div class="yaml-editor-container"></div>
        </div>
        <div class="yaml-editor-statusbar">
            <span class="yaml-editor-status"></span>
        </div>
    </div>
    <!-- Locations Popup -->
    <div class="locations-popup" style="display: none;">
        <div class="locations-popup-content">
            <div class="locations-popup-header">
                <span class="locations-header-label">Download and save to:</span>
                <button class="locations-popup-close" aria-label="Close">
                    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16">
                        <path fill="currentColor" d="M19,6.41L17.59,5L12,10.59L6.41,5L5,6.41L10.59,12L5,17.59L6.41,19L12,13.41L17.59,19L19,17.59L13.41,12L19,6.41Z"></path>
                    </svg>
                </button>
            </div>
            <ul class="locations-list">
                <li>
                    <span class="location-label">Linux / Docker / macOS
                        <span class="help-icon" data-tooltip="Default system location. The engine automatically reads configs from here at startup. Best for production deployments.">
                            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="12" height="12"><path fill="currentColor" d="M11 18h2v-2h-2v2m1-16A10 10 0 0 0 2 12a10 10 0 0 0 10 10 10 10 0 0 0 10-10A10 10 0 0 0 12 2m0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8m0-14a4 4 0 0 0-4 4h2a2 2 0 0 1 2-2 2 2 0 0 1 2 2c0 2-3 1.75-3 5h2c0-2.25 3-2.5 3-5a4 4 0 0 0-4-4Z"/></svg>
                        </span>
                    </span>
                    <div class="location-path-row">
                        <code class="default-path location-path" data-tooltip=""
                            data-copy-osx="/etc/log10x/config/run/transform/group/config.yaml"
                            data-copy-nix="/etc/log10x/config/run/transform/group/config.yaml"
                            data-copy-win="C:\log10x\configs/run/transform/group/config.yaml"></code>
                        <button class="copy-btn" data-tooltip="Copy path">
                            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="14" height="14">
                                <path fill="currentColor" d="M19 21H8V7h11m0-2H8a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h11a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2m-3-4H4a2 2 0 0 0-2 2v14h2V3h12V1Z"></path>
                            </svg>
                        </button>
                    </div>
                </li>
                <li>
                    <span class="location-label">Custom directory
                        <span class="help-icon" data-tooltip="Set TENX_CONFIG environment variable to point to a custom config directory. Useful when you want configs in a non-standard location.">
                            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="12" height="12"><path fill="currentColor" d="M11 18h2v-2h-2v2m1-16A10 10 0 0 0 2 12a10 10 0 0 0 10 10 10 10 0 0 0 10-10A10 10 0 0 0 12 2m0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8m0-14a4 4 0 0 0-4 4h2a2 2 0 0 1 2-2 2 2 0 0 1 2 2c0 2-3 1.75-3 5h2c0-2.25 3-2.5 3-5a4 4 0 0 0-4-4Z"/></svg>
                        </span>
                    </span>
                    <div class="location-path-row">
                        <code class="location-path" data-tooltip="$TENX_CONFIG/run/transform/group/config.yaml">$TENX_CONFIG/run/transform/group/config.yaml</code>
                        <button class="copy-btn" data-tooltip="Copy path">
                            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="14" height="14">
                                <path fill="currentColor" d="M19 21H8V7h11m0-2H8a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h11a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2m-3-4H4a2 2 0 0 0-2 2v14h2V3h12V1Z"></path>
                            </svg>
                        </button>
                    </div>
                </li>
                <li>
                    <span class="location-label">Within cloned repo
                        <span class="help-icon" data-tooltip="First run: git clone github.com/log-10x/config. Then save the file to this path within the cloned folder. Use for version control.">
                            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="12" height="12"><path fill="currentColor" d="M11 18h2v-2h-2v2m1-16A10 10 0 0 0 2 12a10 10 0 0 0 10 10 10 10 0 0 0 10-10A10 10 0 0 0 12 2m0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8m0-14a4 4 0 0 0-4 4h2a2 2 0 0 1 2-2 2 2 0 0 1 2 2c0 2-3 1.75-3 5h2c0-2.25 3-2.5 3-5a4 4 0 0 0-4-4Z"/></svg>
                        </span>
                    </span>
                    <div class="location-path-row">
                        <code class="location-path" data-tooltip="./pipelines/run/transform/group/config.yaml">./pipelines/run/transform/group/config.yaml</code>
                        <button class="copy-btn" data-tooltip="Copy path">
                            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="14" height="14">
                                <path fill="currentColor" d="M19 21H8V7h11m0-2H8a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h11a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2m-3-4H4a2 2 0 0 0-2 2v14h2V3h12V1Z"></path>
                            </svg>
                        </button>
                    </div>
                </li>
            </ul>
            <div class="locations-popup-footer">
                <button class="locations-download-btn" title="Download config file">
                    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="14" height="14">
                        <path fill="currentColor" d="M5 20h14v-2H5v2m14-9h-4V3H9v8H5l7 7 7-7Z"></path>
                    </svg>
                    <span>Download</span>
                </button>
            </div>
        </div>
    </div>
</dialog>

<template class="tenx-config-schema" data-encoding="base64">ewogICJ0eXBlIiA6ICJvYmplY3QiLAogICJwcm9wZXJ0aWVzIiA6IHsKICAgICJ0ZW54IiA6IHsKICAgICAgInR5cGUiIDogInN0cmluZyIKICAgIH0sCiAgICAiZ3JvdXAiIDogewogICAgICAidHlwZSIgOiAib2JqZWN0IiwKICAgICAgImFkZGl0aW9uYWxQcm9wZXJ0aWVzIiA6IGZhbHNlLAogICAgICAicHJvcGVydGllcyIgOiB7CiAgICAgICAgIm1heFNpemUiIDogewogICAgICAgICAgInR5cGUiIDogWwogICAgICAgICAgICAibnVtYmVyIiwKICAgICAgICAgICAgInN0cmluZyIsCiAgICAgICAgICAgICJudWxsIgogICAgICAgICAgXSwKICAgICAgICAgICJtYXJrZG93bkRlc2NyaXB0aW9uIiA6ICJNYXggbnVtYmVyIG9mIG9iamVjdHMgdG8gcGxhY2UgaW4gYSBncm91cFxuXG5TZXRzIHRoZSBtYXhpbXVtIG51bWJlciBvZiBvYmplY3RzIHRvIHBsYWNlIHVuZGVyIG9uZSBncm91cCBiZWZvcmUgc3RhcnRpbmcgYSBuZXcgZ3JvdXAuIFNldCAwIHRvIHVubGltaXRlZC4gKEFjY2VwdHMgbnVtYmVyIG9yIHN0cmluZyB3aXRoICQ9IHByZWZpeCBmb3IgcnVudGltZSBldmFsdWF0aW9uKSAoRGVmYXVsdDogMjAwMDApIiwKICAgICAgICAgICJkZWZhdWx0IiA6IDIwMDAwCiAgICAgICAgfSwKICAgICAgICAiZmx1c2hUaW1lb3V0IiA6IHsKICAgICAgICAgICJ0eXBlIiA6IFsKICAgICAgICAgICAgInN0cmluZyIsCiAgICAgICAgICAgICJudWxsIgogICAgICAgICAgXSwKICAgICAgICAgICJtYXJrZG93bkRlc2NyaXB0aW9uIiA6ICJJbnRlcnZhbCB0byBmbHVzaCBhIHBlbmRpbmcgVGVuWE9iamVjdHMgZ3JvdXBcblxuU2V0cyB0aGUgbWF4IGludGVydmFsIGFmdGVyIHdoaWNoIHRvIGZsdXNoIHBlbmRpbmcgVGVuWE9iamVjdHMgaW50byB0aGUgcGlwZWxpbmUuIFRoaXMgb3B0aW9uIHByb3ZpZGVzIGEgdGltZW91dCBwZXJpb2QgdG8gZmx1c2ggdGhlIGN1cnJlbnQgZ3JvdXAgaGVhZCBhbmQgY29tcG9zZWQgIFRlblhPYmplY3RzIGludG8gdGhlIHBpcGVsaW5lIGZvciBhZ2dyZWdhdGlvbiwgZmlsdGVyaW5nLCBhbmQgZW5jb2RpbmcgdG8gb3V0cHV0LiAoRGVmYXVsdDogNXNlYykiLAogICAgICAgICAgImRlZmF1bHQiIDogIjVzZWMiCiAgICAgICAgfSwKICAgICAgICAiZXhwcmVzc2lvbnMiIDogewogICAgICAgICAgInR5cGUiIDogWwogICAgICAgICAgICAic3RyaW5nIiwKICAgICAgICAgICAgIm51bGwiCiAgICAgICAgICBdLAogICAgICAgICAgIm1hcmtkb3duRGVzY3JpcHRpb24iIDogIkphdmFTY3JpcHQgZXhwcmVzc2lvbnMgVGVuWE9iamVjdCBpbnN0YW5jZS9ncm91cCBtdXN0IGV2YWx1YXRlIGFzIHRydXRoeSBhZ2FpbnN0IHRvIGJlIHNldCBhcyBncm91cCBoZWFkXG5cblNwZWNpZmllcyBhIGxpc3Qgb2YgSmF2YVNjcmlwdCBleHByZXNzaW9ucyB0aGF0IG11c3QgYWxsIGV2YWx1YXRlIGFzIHRydXRoeSBmb3IgdGhlIHRhcmdldCBUZW5YT2JqZWN0IHRvIGJlIGNsYXNzaWZpZWQgYXMgW2dyb3VwIGhlYWRdKGh0dHBzOi8vZG9jLmxvZzEweC5jb20vcnVuL3RyYW5zZm9ybS9ncm91cC8jZ3JvdXAtaGVhZHMpLiAgRm9yIGV4YW1wbGUsIHRoZSBbZ3JvdXAgaW5pdGlhbGl6ZXJdKGh0dHBzOi8vZG9jLmxvZzEweC5jb20vcnVuL2luaXRpYWxpemUvZ3JvdXAvKSBtb2R1bGUgY2FsY3VsYXRlcyBhIFtUZW54VGVtcGxhdGUgdmFyaWFibGVdKGh0dHBzOi8vZG9jLmxvZzEweC5jb20vYXBpL2pzLyNUZW5YVGVtcGxhdGUuc2V0KSB0byBkZXRlcm1pbmUgd2hldGhlciBpbnN0YW5jZXMgb2YgYSB0YXJnZXQgYFRlblhUZW1wbGF0ZWAgcmVwcmVzZW50IGdyb3VwIGhlYWRzIGJhc2VkIG9uIGEgbnVtYmVyIG9mIGhldXJpc3RpYyBpbmRpY2F0b3JzIGFuZCBzZXRzIHRoZSBjYWxjdWxhdGVkIGZpZWxkIG5hbWUgKGUuZy4sIGBHcm91cFRlbXBsYXRlLmlzR3JvdXBgKSBob2xkaW5nIHRoZSByZXN1bHRpbmcgdmFsdWUgaW50byB0aGlzIGFycmF5LiAgIFVzaW5nIFRlblhUZW1wbGF0ZSB2YXJpYWJsZXMgYWxsb3dzIGZvciBjb21wdXRpbmcgdGhpcyBzdGF0ZSBvbmNlIGZvciBhbGwgaW5zdGFuY2VzIG9mIGEgdGFyZ2V0IGV2ZW50LiIKICAgICAgICB9LAogICAgICAgICJmaWx0ZXJzIiA6IHsKICAgICAgICAgICJ0eXBlIiA6IFsKICAgICAgICAgICAgImFycmF5IiwKICAgICAgICAgICAgInN0cmluZyIsCiAgICAgICAgICAgICJudWxsIgogICAgICAgICAgXSwKICAgICAgICAgICJtYXJrZG93bkRlc2NyaXB0aW9uIiA6ICJKYXZhU2NyaXB0IGV4cHJlc3Npb25zIFRlblhPYmplY3QgaW5zdGFuY2UvZ3JvdXAgbXVzdCBldmFsdWF0ZSBhcyB0cnV0aHkgYWdhaW5zdFxuXG5TcGVjaWZpZXMgYSBsaXN0IG9mIEphdmFTY3JpcHQgZXhwcmVzc2lvbnMgdGhhdCBtdXN0IGFsbCBldmFsdWF0ZSBhcyB0cnV0aHkgZm9yIHRoZSB0YXJnZXQgb2JqZWN0L2dyb3VwIHRvIGJlIHBhcnQgb2YgYSBzZXF1ZW5jZSBhZ2dyZWdhdGVkL3dyaXR0ZW4gdG8gb3V0cHV0LiAgVG8gbGVhcm4gbW9yZSBzZWUgW2dyb3VwIGZpbHRlcnNdKGh0dHBzOi8vZG9jLmxvZzEweC5jb20vcnVuL3RyYW5zZm9ybS9ncm91cC8jZ3JvdXAtZmlsdGVycykuIiwKICAgICAgICAgICJpdGVtcyIgOiB7CiAgICAgICAgICAgICJ0eXBlIiA6ICJzdHJpbmciCiAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAiYXN5bmMiIDogewogICAgICAgICAgInR5cGUiIDogWwogICAgICAgICAgICAiYm9vbGVhbiIsCiAgICAgICAgICAgICJzdHJpbmciLAogICAgICAgICAgICAibnVsbCIKICAgICAgICAgIF0sCiAgICAgICAgICAibWFya2Rvd25EZXNjcmlwdGlvbiIgOiAiR3JvdXAgVGVuWE9iamVjdHMgaW4gYSBkZWRpY2F0ZWQgdGhyZWFkXG5cblNwZWNpZmllcyB3aGV0aGVyIHRvIHBlcmZvcm0gVGVuWE9iamVjdCBncm91cGluZyBsb2dpYyBpbiBhIGRlZGljYXRlZCB0aHJlYWQgKEFjY2VwdHMgYm9vbGVhbiBvciBzdHJpbmcgd2l0aCAkPSBwcmVmaXggZm9yIHJ1bnRpbWUgZXZhbHVhdGlvbikgKERlZmF1bHQ6IHRydWUpIiwKICAgICAgICAgICJkZWZhdWx0IiA6IHRydWUKICAgICAgICB9CiAgICAgIH0KICAgIH0KICB9LAogICJhZGRpdGlvbmFsUHJvcGVydGllcyIgOiBmYWxzZQp9</template>

```yaml
# 🔟❎ 'run' event grouping configuration

# Group  sequences of TenXObjects to filter, aggregate and output as a single logical unit.
# To learn more see https://doc.log10x.com/run/transform/group/

# Set the 10x pipeline to 'run'
tenx: run

# =============================== Group Options ===============================

group:

  # 'filters' specify JavaScript expressions an TenXObject instance/group must 
  #  evaluate as truthy against to be written to output
  filters: []

  # 'maxSize' defines the maximum number of TenXObjects to group
  #  before the group is sealed and forwarded into the pipeline. 
  #  Subsequent TenXObjects can form a new group.
  maxSize: 20000

  # 'flushTimeout' defines the max interval (e.g., 10s) to wait for 
  #  new events to be read from an input stream before it flushes any
  #  pending TenXObjects group into the pipeline.
  #  This mechanism is designed to avoid latencies in dispatching pending event
  #  groups to output destinations.
  flushTimeout: $=parseDuration("5s")

  # 'async' specifies whether to sequence and group TenXObjects in a dedicated thread
  async: true 
```

## :material-menu: Options

Specify the options below to [configure](/config "configure") the Group sequencer:

|Name|Description|
|---|---|
|[groupMaxSize](#groupmaxsize "max number of objects to place in a group")|Max number of objects to place in a group|
|[groupMaxSize](#groupmaxsize "max number of objects to place in a group")|Max number of objects to place in a group|
|[groupFlushTimeout](#groupflushtimeout "interval to flush a pending TenXObjects group")|Interval to flush a pending TenXObjects group|
|[groupExpressions](#groupexpressions "JavaScript expressions TenXObject instance/group must evaluate as truthy against to be set as group head")|JavaScript expressions TenXObject instance/group must evaluate as truthy against to be set as group head|
|[groupFilters](#groupfilters "JavaScript expressions TenXObject instance/group must evaluate as truthy against")|JavaScript expressions TenXObject instance/group must evaluate as truthy against|
|[groupAsync](#groupasync "group TenXObjects in a dedicated thread")|Group TenXObjects in a dedicated thread|

### :material-menu-right-outline:**`groupMaxSize`**

Max number of objects to place in a group.

|Type|Default|
|---|---|
|Number|20000|

Sets the maximum number of objects to place under one group before starting a new group.
Set 0 to unlimited.


### :material-menu-right-outline:**`groupMaxSize`**

Max number of objects to place in a group.

|Type|Default|
|---|---|
|Number|20000|

Sets the maximum number of objects to place under one group before starting a new group.
Set 0 to unlimited.


### :material-menu-right-outline:**`groupFlushTimeout`**

Interval to flush a pending TenXObjects group.

|Type|Default|
|---|---|
|String|5sec|

Sets the max interval after which to flush pending TenXObjects into the pipeline.
This option provides a timeout period to flush the current group head and composed
TenXObjects into the pipeline for aggregation, filtering, and encoding to output.


### :material-menu-right-outline:**`groupExpressions`**

JavaScript expressions TenXObject instance/group must evaluate as truthy against to be set as group head.

|Type|Default|
|---|---|
|String|""|

Specifies a list of JavaScript expressions that must all evaluate
as truthy for the target TenXObject to be classified as [group head](https://doc.log10x.com/run/transform/group/#group-heads).

For example, the [group initializer](https://doc.log10x.com/run/initialize/group/ "Combine multi-line events into TenXObject group instances") module calculates a [TenxTemplate variable](https://doc.log10x.com/api/js/#TenXTemplate.set) to determine whether instances of a target `TenXTemplate` represent group heads based on a number of heuristic indicators and sets the calculated field name (e.g., `GroupTemplate.isGroup`) holding the resulting value into this array.

Using TenXTemplate variables allows for computing this state once for all instances of a target event.


### :material-menu-right-outline:**`groupFilters`**

JavaScript expressions TenXObject instance/group must evaluate as truthy against.

|Type|Default|
|---|---|
|List|\[\]|

Specifies a list of JavaScript expressions that must all evaluate
as truthy for the target object/group to be part of a sequence aggregated/written to output.

To learn more see [group filters](https://doc.log10x.com/run/transform/group/#group-filters).


### :material-menu-right-outline:**`groupAsync`**

Group TenXObjects in a dedicated thread.

|Type|Default|
|---|---|
|Boolean|true|

Specifies whether to perform TenXObject grouping logic in a dedicated thread.


<br/>:material-github: This unit is defined in [group/unit.yaml](https://github.com/log-10x/modules/tree/main/pipelines/run/units/transform/group/unit.yaml "group/unit.yaml"){target="\_blank"}.

