# Materialization - Docs

Materialization pre-computes your query results and stores them in S3. When someone calls your endpoint, PostHog returns the materialized results instead of running the query again - making responses much faster.

## When to use materialization

Materialization is ideal when:

-   **Your data doesn't need to be real-time** - Results are only as fresh as the last sync
-   **Your query is expensive** - Complex queries with large datasets benefit the most
-   **You have high traffic** - Avoid repeatedly running the same query

If you need real-time data or frequently update your query, stick with direct execution or use [caching](/docs/endpoints/caching.md) instead.

## How to enable materialization

1.  Go to your endpoint's **Configuration** tab
2.  Enable the **Materialization** toggle
3.  Choose a sync frequency:
    -   **Every hour** - Updates every hour
    -   **Every 6 hours** - Updates four times a day
    -   **Daily** - Updates once per day
    -   **Weekly** - Updates once per week

PostHog will run the first materialization immediately. After that, it syncs on your chosen schedule.

## Materialization status

On the endpoint page, you'll see one of these statuses:

-   **Completed** - Latest materialization succeeded, results are available
-   **Running** - Materialization is in progress
-   **Failed** - Materialization encountered an error

If materialization fails, the endpoint falls back to direct execution until the next successful sync.

## Limitations

Materialization is not available when:

-   **The endpoint has incompatible variables** - Only certain [variable](/docs/endpoints/variables.md) types are supported. See the compatibility table below.
-   **The endpoint is inactive** - Only active endpoints and their versions are materialized.

### Variable compatibility

Not all variables work with materialization. Compatibility depends on the operator and where the variable is used in the query.

| Variable type | Supported | Notes |
| --- | --- | --- |
| Equality (=) on columns | ✅ Yes | Standard column filters work out of the box |
| Range (>=, >, <, <=) on timestamp columns | ✅ Yes | Uses [timestamp bucketing](#timestamp-bucketing) to pre-aggregate data |
| Variables in HAVING clauses | ❌ No | Cannot be materialized |
| Variables in OR conditions | ❌ No | Cannot be materialized |

## Timestamp bucketing

When your query uses timestamp range variables (e.g., `timestamp >= {variables.start_date} AND timestamp < {variables.end_date}`), PostHog uses **bucketed materialization**.

Instead of materializing a single result set, PostHog pre-aggregates your data into time buckets. At read time, it re-aggregates only the buckets that fall within your actual variable values.

Supported bucket granularities:

-   `hour`
-   `day` (default)
-   `week`
-   `month`

By default, PostHog uses `toStartOfDay` to bucket your data. This means each row in the materialized result represents one day of pre-aggregated data.

### Configuring bucket size

You can customize the bucket granularity for each timestamp column directly in the **Configuration** tab. When materialization is enabled and your query has timestamp range variables, a dropdown appears for each timestamp column, letting you select a bucket size:

-   **Hour**
-   **Day**
-   **Week**
-   **Month**

Smaller buckets give more precise results, while larger buckets produce less granular results.

Bucketed materialization only works with aggregate functions that can be re-aggregated across buckets: `count`, `sum`, `min`, `max`, and their combinator variants like `countIf` and `sumIf`. Functions like `avg`, `uniq`, and `countDistinct` cannot be re-aggregated and are not supported.

## How materialization works with execution

When you execute an endpoint:

1.  If materialization is **enabled and complete**, PostHog returns the materialized results
2.  If materialization is **running or failed**, PostHog executes the query directly

See [Execution](/docs/endpoints/execution.md) for more details on how PostHog chooses between materialized and direct execution.

### Community questions

Ask a question

### Was this page useful?

HelpfulCould be better