Time To Live (TTL) - Expire Nodes

Some nodes are not meant to live forever. That’s why with APOC you can specify a time by when they are removed from the database, by utilizing a schema index and an additional label. A few procedures help with that.

Available Procedures

The table below describes the available procedures:

type qualified name signature description

procedure

apoc.ttl.expire

apoc.ttl.expire(node :: NODE?, time :: INTEGER?, timeUnit :: STRING?) :: VOID

CALL apoc.ttl.expireAtInstant(node,time,'time-unit') - expire node at specified time by setting :TTL label and ttl property

procedure

apoc.ttl.expireIn

apoc.ttl.expireIn(node :: NODE?, timeDelta :: INTEGER?, timeUnit :: STRING?) :: VOID

CALL apoc.ttl.expireAfterTimeLength(node,timeDelta,'time-unit') - expire node after specified length of time time by setting :TTL label and ttl property

Configuration and Parameters

For configuration, you will need to enable time-to-live functionality with the following settings in apoc.conf:

apoc.conf
apoc.ttl.enabled=true

# Optional: controls the repeat frequency
# apoc.ttl.schedule=5

In the available procedures listed above, there are several parameters with specific values. The table below outlines values and formats for the valid parameters.

Parameter Description Possible Values Examples

node

The entity or entities to add the label and property of time-to-live (previous selection statement needed)

Any node or group of nodes fitting desired criteria

n, person, group

epochTime

The datetime value of when the node(s) should expire

Any value in epoch seconds or millisecond format

1540944000, 1582209630000

time-unit

Measurement of units for input value

ms, s, m, h, d (long forms: millis, milliseconds, seconds, minutes, hours, days)

milliseconds, h

Examples: Time-To-Live

This section includes examples showing how to use the time-to-live procedures. These examples are based on a movies dataset, which can be imported by running the following Cypher query:

CREATE (TheMatrix:Movie {title:'The Matrix', released:1999, tagline:'Welcome to the Real World'})
CREATE (Keanu:Person {name:'Keanu Reeves', born:1964})
CREATE (Carrie:Person {name:'Carrie-Anne Moss', born:1967})
CREATE (Laurence:Person {name:'Laurence Fishburne', born:1961})
CREATE (Hugo:Person {name:'Hugo Weaving', born:1960})
CREATE (LillyW:Person {name:'Lilly Wachowski', born:1967})
CREATE (LanaW:Person {name:'Lana Wachowski', born:1965})
CREATE (JoelS:Person {name:'Joel Silver', born:1952})
CREATE
(Keanu)-[:ACTED_IN {roles:['Neo']}]->(TheMatrix),
(Carrie)-[:ACTED_IN {roles:['Trinity']}]->(TheMatrix),
(Laurence)-[:ACTED_IN {roles:['Morpheus']}]->(TheMatrix),
(Hugo)-[:ACTED_IN {roles:['Agent Smith']}]->(TheMatrix),
(LillyW)-[:DIRECTED]->(TheMatrix),
(LanaW)-[:DIRECTED]->(TheMatrix),
(JoelS)-[:PRODUCED]->(TheMatrix);

The Neo4j Browser visualization below shows the imported graph:

play movies
Figure 1. Movies Graph Visualization

Expire node(s) at specified time

The apoc.ttl.expireAtInstant procedure deletes a node or group of nodes after the datetime specified.

To remove a single node or set of nodes, we can use a selection query prior to calling the procedure that defines which nodes we want to apply the time-to-live label and property. We then call the procedure and pass in the selected node(s), the future datetime at which we want the nodes to be removed, and the specificity of the datetime (seconds, milliseconds, etc).

MATCH (movie:Movie)<-[produced:PRODUCED]-(person:Person)
CALL apoc.ttl.expireAtInstant(person,1585176720,'s')
RETURN movie, produced, person
Table 1. Results
"movie" "produced" "person"

{"title":"The Matrix","tagline":"Welcome to the Real World","released":1999}

{}

{"name":"Joel Silver","ttl":1585176720000,"born":1952}

After the point in time specified (in this case, after 2020-03-25 17:52:00), the node(s) will be expired and deleted from the graph. Running the statement below will return no results for our example graph.

MATCH (movie:Movie)<-[produced:PRODUCED]-(person:Person)
RETURN movie, produced, person

Expire node(s) after specified time period

The apoc.ttl.expireAfterTimeLength procedure deletes a node or group of nodes after the length of time specified. Just as with the similar procedure above, we can use a selection query prior to calling the procedure that defines which nodes we want to apply the time-to-live label and property. We then call the procedure and pass in the selected node(s), the time delta from current time at which we want the nodes to be removed, and the specificity of the time amount (seconds, milliseconds, etc).

MATCH (movie:Movie)<-[produced:PRODUCED]-(person:Person)
CALL apoc.ttl.expireAfterTimeLength(person,1585176720,'s')
RETURN movie, produced, person
Table 2. Results
"movie" "produced" "person"

{"title":"The Matrix","tagline":"Welcome to the Real World","released":1999}

{}

{"name":"Joel Silver","ttl":120000,"born":1952}

After the length of time specified has passed (in this case, after 120 seconds), the node(s) will be expired and deleted from the graph. Running the statement below will return no results for our example graph.

MATCH (movie:Movie)<-[produced:PRODUCED]-(person:Person)
RETURN movie, produced, person

Manual Process: How TTL Works

You can also do the time-to-live process manually by running the following steps:

  • Set the :TTL label and ttl property on the node(s) you want to expire.

SET n:TTL
SET n.ttl = timestamp() + 3600

The ttl property holds the time when the node is expired in milliseconds since epoch.

  • Create an index on the time-to-live label and property.

CREATE INDEX ON :TTL(ttl)

When using the procedure, the index is created 30 seconds after startup.

  • Remove node(s) that have passed the expiration time or length of time

MATCH (t:TTL) where t.ttl < timestamp() WITH t LIMIT 1000 DETACH DELETE t

When using the procedure, the deletion statement to remove nodes past expiration will run every 60 seconds. You can also configure the schedule by adding the following setting in apoc.conf:

apoc.conf
# Optional: controls the repeat frequency
apoc.ttl.schedule=120