---
title: Tail Handler
description: Process real-time logs from producer Workers using the tail() handler in Tail Workers.
image: https://developers.cloudflare.com/dev-products-preview.png
---

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/workers/llms.txt  
> Use this file to discover all available pages before exploring further.

[Skip to content](#%5Ftop) 

# Tail Handler

## Background

The `tail()` handler is the handler you implement when writing a [Tail Worker](https://developers.cloudflare.com/workers/observability/logs/tail-workers/). Tail Workers can be used to process logs in real-time and send them to a logging or analytics service.

The `tail()` handler is called once each time the connected producer Worker is invoked.

To configure a Tail Worker, refer to [Tail Workers documentation](https://developers.cloudflare.com/workers/observability/logs/tail-workers/).

## Syntax

JavaScript

```

export default {

  async tail(events, env, ctx) {

    fetch("<YOUR_ENDPOINT>", {

      method: "POST",

      body: JSON.stringify(events),

    })

  }

}


```

### Parameters

* `events` array  
   * An array of [TailItems](https://developers.cloudflare.com/workers/runtime-apis/handlers/tail/#tailitems). One `TailItem` is collected for each event that triggers a Worker. For Workers for Platforms customers with a Tail Worker installed on the dynamic dispatch Worker, `events` will contain two elements: one for the dynamic dispatch Worker and one for the User Worker.
* `env` object  
   * An object containing the bindings associated with your Worker using [ES modules format](https://developers.cloudflare.com/workers/reference/migrate-to-module-workers/), such as KV namespaces and Durable Objects.
* `ctx` object  
   * An object containing the context associated with your Worker using [ES modules format](https://developers.cloudflare.com/workers/reference/migrate-to-module-workers/). Currently, this object just contains the `waitUntil` function.

### Properties

* `event.type` string  
   * The type of event. This will always return `"tail"`.
* `event.traces` array  
   * An array of [TailItems](https://developers.cloudflare.com/workers/runtime-apis/handlers/tail/#tailitems). One `TailItem` is collected for each event that triggers a Worker. For Workers for Platforms customers with a Tail Worker installed on the dynamic dispatch Worker, `events` will contain two elements: one for the dynamic dispatch Worker and one for the user Worker.
* `event.waitUntil(promisePromise)` : void  
   * Refer to [waitUntil](https://developers.cloudflare.com/workers/runtime-apis/context/#waituntil). Note that unlike fetch event handlers, tail handlers do not return a value, so this is the only way for trace Workers to do asynchronous work.

### `TailItems`

#### Properties

* `scriptName` string  
   * The name of the producer script.
* `event` object  
   * Contains information about the Worker’s triggering event.  
         * For fetch events: a [FetchEventInfo object](https://developers.cloudflare.com/workers/runtime-apis/handlers/tail/#fetcheventinfo)  
         * For other event types: `null`, currently.
* `eventTimestamp` number  
   * Measured in epoch time.
* `logs` array  
   * An array of [TailLogs](https://developers.cloudflare.com/workers/runtime-apis/handlers/tail/#taillog).
* `exceptions` array  
   * An array of [TailExceptions](https://developers.cloudflare.com/workers/runtime-apis/handlers/tail/#tailexception). A single Worker invocation might result in multiple unhandled exceptions, since a Worker can register multiple asynchronous tasks.
* `outcome` string  
   * The outcome of the Worker invocation, one of:  
         * `unknown`: outcome status was not set.  
         * `ok`: The worker invocation succeeded.  
         * `exception`: An unhandled exception was thrown. This can happen for many reasons, including:  
                  * An uncaught JavaScript exception.  
                  * A fetch handler that does not result in a Response.  
                  * An internal error.  
         * `exceededCpu`: The Worker invocation exceeded either its CPU limits.  
         * `exceededMemory`: The Worker invocation exceeded memory limits.  
         * `scriptNotFound`: An internal error from difficulty retrieving the Worker script.  
         * `canceled`: The worker invocation was canceled before it completed. Commonly because the client disconnected before a response could be sent.  
         * `responseStreamDisconnected`: The response stream was disconnected during deferred proxying. Happens when either the client or server hangs up early.

Outcome is not the same as HTTP status.

Outcome is equivalent to the exit status of a script and an indicator of whether it has fully run to completion. A Worker outcome may differ from a response code if, for example:

* a script successfully processes a request but is logically designed to return a `4xx`/`5xx` response.
* a script sends a successful `200` response but an asynchronous task registered via `waitUntil()` later exceeds CPU or memory limits.

### `FetchEventInfo`

#### Properties

* `request` object  
   * A [TailRequest object](https://developers.cloudflare.com/workers/runtime-apis/handlers/tail/#tailrequest).
* `response` object  
   * A [TailResponse object](https://developers.cloudflare.com/workers/runtime-apis/handlers/tail/#tailresponse).

### `TailRequest`

#### Properties

* `cf` object  
   * Contains the data from [IncomingRequestCfProperties](https://developers.cloudflare.com/workers/runtime-apis/request/#incomingrequestcfproperties).
* `headers` object  
   * Header name/value entries (redacted by default). Header names are lowercased, and the values associated with duplicate header names are concatenated, with the string `", "` (comma space) interleaved, similar to [the Fetch standard ↗](https://fetch.spec.whatwg.org/#concept-header-list-get).
* `method` string  
   * The HTTP request method.
* `url` string  
   * The HTTP request URL (redacted by default).

#### Methods

* `getUnredacted()` object  
   * Returns a TailRequest object with unredacted properties

Some of the properties of `TailRequest` are redacted by default to make it harder to accidentally record sensitive information, like user credentials or API tokens. The redactions use heuristic rules, so they are subject to false positives and negatives. Clients can call `getUnredacted()` to bypass redaction, but they should always be careful about what information is retained, whether using the redaction or not.

* Header redaction: The header value will be the string `“REDACTED”` when the (case-insensitive) header name is `cookie`/`set-cookie` or contains a substring `"auth”`, `“key”`, `“secret”`, `“token”`, or `"jwt"`.
* URL redaction: For each greedily matched substring of ID characters (a-z, A-Z, 0-9, '+', '-', '\_') in the URL, if it meets the following criteria for a hex or base-64 ID, the substring will be replaced with the string `“REDACTED”`.
* Hex ID: Contains 32 or more hex digits, and contains only hex digits and separators ('+', '-', '\_')
* Base-64 ID: Contains 21 or more characters, and contains at least two uppercase, two lowercase, and two digits.

### `TailResponse`

#### Properties

* `status` number  
   * The HTTP status code.

### `TailLog`

Records information sent to console functions.

#### Properties

* `timestamp` number  
   * Measured in epoch time.
* `level` string  
   * A string indicating the console function that was called. One of: `debug`, `info`, `log`, `warn`, `error`.
* `message` object  
   * The array of parameters passed to the console function.

### `TailException`

Records an unhandled exception that occurred during the Worker invocation.

#### Properties

* `timestamp` number  
   * Measured in epoch time.
* `name` string  
   * The error type (For example,`Error`, `TypeError`, etc.).
* `message` object  
   * The error description (For example, `"x" is not a function`).

## Related resources

* [Tail Workers](https://developers.cloudflare.com/workers/observability/logs/tail-workers/) \- Configure a Tail Worker to receive information about the execution of other Workers.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/workers/","name":"Workers"}},{"@type":"ListItem","position":3,"item":{"@id":"/workers/runtime-apis/","name":"Runtime APIs"}},{"@type":"ListItem","position":4,"item":{"@id":"/workers/runtime-apis/handlers/","name":"Handlers"}},{"@type":"ListItem","position":5,"item":{"@id":"/workers/runtime-apis/handlers/tail/","name":"Tail Handler"}}]}
```
