# Internal InfluxDB

Heisenware incorporates a distinct InfluxDB time series database for each Workspace. This database is utilized to store time series data, enabling its future retrieval, processing, or visualization.

Given that each workspace has its own InfluxDB, various apps within the same Workspace can access data recorded by other apps. For this reason, the name of the InfluxDB contains the name of the Workspace, e.g., `acme-influx`.

{% hint style="info" %}
If you have already set up your own InfluxDB or another time series database, consider using the [time series database connector](/~/changes/Q625pQNc0nXqVGPtyjAY/building-apps/integration/data-connectors/time-series-database-wip.md). This will enable you to record and retrieve data to and from your database.
{% endhint %}

## Recording data

To record time series data, you’ll need the recorder function extension. This can be attached to any function output or modifier. Here are the steps to record data:

1. Click the `+` icon behind an output or modifier.
2. Select `Recorder.`
3. Add a name for the time series data measurement.

<div align="left"><figure><img src="/files/4gov2uj80zE3csqKwCDt" alt=""><figcaption><p>Function with recorder and a measurement called “example”.</p></figcaption></figure></div>

During runtime, either in test mode while in the App Builder, or after app deployment, the recording of the value begins. Each trigger of a function with recorder results in a data point. The configuration of the trigger determines the storage interval.

The data is stored as pairs of value and timestamp. The value can be anything, a single number (like a temperature value), an entire object, or even an array of arbitrary type. When data is queried, the associated timestamp appears in the [date time string format](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date#date_time_string_format), a simplified format based on [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601), which is always 24 characters long (`YYYY-MM-DDTHH:mm:ss.sssZ`). The timezone is always UTC, as denoted by the suffix `Z`.

### Retention policy

A retention policy specifies the duration after which data points are overwritten. This means that the oldest data point is always replaced with the most recent one. By default, the retention policy for a new measurement is set to `forever`, denoted by the letter `F` as part of the recorder.

You can select from various policies: hourly (`H`), daily (`D`), weekly (`W`), monthly (`M`), annually (`A`), and forever (`F`). With the `forever` policy, no data points are ever overwritten.

To modify the retention policy of a measurement, follow these steps:

1. Right-click on the recorder.
2. Select your preferred retention policy.

### Deleting recorder

To delete a recorder:

1. Right-click on the recorder.
2. Select `Delete`.

{% hint style="info" %}
If data has already been logged under a specific measurement, it will be preserved even if the recorder is deleted. If a new recorder is assigned the same measurement name, it will continue to write data to this existing series. This ensures that your data remains intact and accessible, regardless of changes to the recorder setup.
{% endhint %}

## Reading data

Before you can read data from the InfluxDB, ensure that data has been previously recorded. Useful visualization widgets for time series data that is read from the database are the [data grid](/~/changes/Q625pQNc0nXqVGPtyjAY/building-apps/ui-elements/display-widgets/data-grid-wip.md), [chart](/~/changes/Q625pQNc0nXqVGPtyjAY/building-apps/ui-elements/display-widgets/chart-wip.md), and  [sparkline](/~/changes/Q625pQNc0nXqVGPtyjAY/building-apps/ui-elements/display-widgets/sparkline-wip.md), which are all made for visualizing recorded, historic data.

### Read function

To retrieve data from the InfluxDB, you’ll need a `read`function. This can be found in the functions panel under the path: `Data Connectors` -> `Timeseries Database` -> `[workspace_name]-influx`.&#x20;

#### Input

The `read` function requires two inputs:

* **Bucket**: This is the abbreviated name of the bucket to use, as defined in the recorder. It can be `H`, `D`, `W`, `M`, `A`, or `F`.
* **Measurement**: This is the name of the measurement to read, as defined in the recorder.

#### Output

The `read` function outputs an array of objects, where `date` and `value` are keys within each object. This allows for easy access and manipulation of the retrieved data.

<div align="left"><figure><img src="/files/Gd2CzSVKmAdWJyjOKPvw" alt=""><figcaption><p>Read function returning an array of objects.</p></figcaption></figure></div>

#### Filters and aggregators

Optional filters and aggregators for the third input:

* **`tail`**: Number of latest values to read.
* **`start`**: Earliest time for results, inclusive. Expects a string. Can be specified using an **absolute** timestamp, such as `2021-01-01T00:00:00Z`, or using a **relative** timestamp, such as `-1h` or `-15m`.&#x20;
* **`stop`**: Latest time for results, exclusive. Expects a string. Defaults to `now` and can be specified as `start` using absolute or relative timestamps.
* **`every`**: Aggregation window duration. Expects a string.
* **`func`**: Aggregation function. Expects a string. Defaults to `mean`. Other options are `median`, `min`, `max`, or `sum.`

#### Recorder shortcut

A shortcut exists to add a pre-configured `read` function for a specific measurement. This shortcut can only be used if the original recorder is available in the same app. Click the database icon at the recorder’s right end to add a pre-configured `read` function with `tail: 100`, which is added directly below the data-recording function.

<div align="left"><figure><img src="/files/qcJXME7SORWCH5fdfNAt" alt=""><figcaption><p>Read function shortcut by clicking recorder database icon.</p></figcaption></figure></div>

### Query function

The `query` function provides raw access to InfluxDB, allowing queries using flux. This is an advanced feature; please consult the InfluxDB documentation for more information.

{% embed url="<https://docs.influxdata.com/influxdb/v2/query-data/get-started/query-influxdb/>" %}

{% hint style="info" %}
In the `from` statement (e.g., `from(bucket: "example-bucket")`), the bucket name corresponds to the retention policy, represented by either H, D, W, M, A, or F.
{% endhint %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.heisenware.com/~/changes/Q625pQNc0nXqVGPtyjAY/building-apps/data-and-file-storage/internal-influxdb.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
