# Point-in-time joins

Feature values in Feast are modeled as time-series records. Below is an example of a driver feature view with two feature columns (`trips_today`, and `earnings_today`):

![](https://485992010-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxiVe4aDsn9lis90octoq%2Fuploads%2Fgit-blob-adce5fd96790d72dc8cb02a14f5a07c96c16664d%2Fimage%20\(36\).png?alt=media)

The above table can be registered with Feast through the following feature view:

```python
from feast import Entity, FeatureView, Field, FileSource
from feast.types import Float32, Int64
from datetime import timedelta

driver = Entity(name="driver", join_keys=["driver_id"])

driver_stats_fv = FeatureView(
    name="driver_hourly_stats",
    entities=[driver],
    schema=[
        Field(name="trips_today", dtype=Int64),
        Field(name="earnings_today", dtype=Float32),
    ],
    ttl=timedelta(hours=2),
    source=FileSource(
        path="driver_hourly_stats.parquet"
    )
)
```

Feast is able to join features from one or more feature views onto an entity dataframe in a point-in-time correct way. This means Feast is able to reproduce the state of features at a specific point in the past.

Given the following entity dataframe, imagine a user would like to join the above `driver_hourly_stats` feature view onto it, while preserving the `trip_success` column:

![Entity dataframe containing timestamps, driver ids, and the target variable](https://485992010-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxiVe4aDsn9lis90octoq%2Fuploads%2Fgit-blob-f6a96bee665601e7d0edfe00b4c261e53decd011%2Fimage%20\(23\).png?alt=media)

The timestamps within the entity dataframe above are the events at which we want to reproduce the state of the world (i.e., what the feature values were at those specific points in time). In order to do a point-in-time join, a user would load the entity dataframe and run historical retrieval:

```python
# Read in entity dataframe
entity_df = pd.read_csv("entity_df.csv")

training_df = store.get_historical_features(
    entity_df=entity_df,
    features = [
        'driver_hourly_stats:trips_today',
        'driver_hourly_stats:earnings_today'
    ],
)
```

For each row within the entity dataframe, Feast will query and join the selected features from the appropriate feature view data source. Feast will scan backward in time from the entity dataframe timestamp up to a maximum of the TTL time specified.

![](https://485992010-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxiVe4aDsn9lis90octoq%2Fuploads%2Fgit-blob-94853e3109818777af0a990d5e8d67b2832adfe4%2Fimage%20\(31\).png?alt=media)

{% hint style="info" %}
Please note that the TTL time is relative to each timestamp within the entity dataframe. TTL is not relative to the current point in time (when you run the query).
{% endhint %}

Below is the resulting joined training dataframe. It contains both the original entity rows and joined feature values:

![](https://485992010-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxiVe4aDsn9lis90octoq%2Fuploads%2Fgit-blob-ae51a9c0725058507c262987e47fa32a1597fb2f%2Fimage%20\(29\).png?alt=media)

Three feature rows were successfully joined to the entity dataframe rows. The first row in the entity dataframe was older than the earliest feature rows in the feature view and could not be joined. The last row in the entity dataframe was outside of the TTL window (the event happened 11 hours after the feature row) and also couldn't be joined.


---

# 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.feast.dev/untitled/getting-started/concepts/point-in-time-joins.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.
