Cassandra
Java Driver
QueryBuilder
TTL
Database Management

How to pass TTL in Cassandra Java Driver QueryBuilder?

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

Introduction

TTL is Cassandra's built-in expiration mechanism: you write a value, attach a number of seconds, and Cassandra automatically expires that data later. In Java, the exact QueryBuilder syntax depends on the driver generation you are using, so the safest answer is to show the current driver 4 style first and then note the older driver 3 form. The core idea is always the same: TTL is part of the write statement, not a separate option passed at execute time.

Using TTL with the current QueryBuilder API

In the DataStax and Apache Java driver 4 line, usingTtl(...) is available directly on insert and update builders. You can pass a literal number of seconds or a bind marker.

java
1import static com.datastax.oss.driver.api.querybuilder.QueryBuilder.bindMarker;
2import static com.datastax.oss.driver.api.querybuilder.QueryBuilder.insertInto;
3
4import com.datastax.oss.driver.api.core.CqlSession;
5import com.datastax.oss.driver.api.core.cql.PreparedStatement;
6import com.datastax.oss.driver.api.core.cql.SimpleStatement;
7
8public class InsertWithTtl {
9    public static void main(String[] args) {
10        try (CqlSession session = CqlSession.builder().build()) {
11            SimpleStatement template = insertInto("app", "sessions")
12                .value("user_id", bindMarker())
13                .value("token", bindMarker())
14                .usingTtl(bindMarker())
15                .build();
16
17            PreparedStatement ps = session.prepare(template);
18            session.execute(ps.bind("alice", "abc123", 3600));
19        }
20    }
21}

This writes the row with a one-hour TTL. Using a bind marker is helpful when different rows need different retention windows.

Updating data with a TTL

TTL is not limited to inserts. You can also apply it to updates. That is useful for expiring refresh tokens, cache rows, or rolling activity markers.

java
1import static com.datastax.oss.driver.api.querybuilder.QueryBuilder.bindMarker;
2import static com.datastax.oss.driver.api.querybuilder.QueryBuilder.update;
3
4import java.time.Instant;
5
6import com.datastax.oss.driver.api.core.CqlSession;
7import com.datastax.oss.driver.api.core.cql.PreparedStatement;
8import com.datastax.oss.driver.api.core.cql.SimpleStatement;
9
10public class UpdateWithTtl {
11    public static void main(String[] args) {
12        try (CqlSession session = CqlSession.builder().build()) {
13            SimpleStatement template = update("app", "sessions")
14                .usingTtl(600)
15                .setColumn("last_seen", bindMarker())
16                .whereColumn("user_id").isEqualTo(bindMarker())
17                .build();
18
19            PreparedStatement ps = session.prepare(template);
20            session.execute(ps.bind(Instant.now(), "alice"));
21        }
22    }
23}

In driver 4, a TTL of 0 has a special meaning: it removes the TTL for the written cells instead of making them expire immediately. That detail matters when you are intentionally overriding a table-level or previously written TTL.

Older driver syntax looks different

If you are maintaining code on the older com.datastax.driver.core package, the QueryBuilder API uses using(ttl(...)) instead of usingTtl(...).

java
1import static com.datastax.driver.core.querybuilder.QueryBuilder.bindMarker;
2import static com.datastax.driver.core.querybuilder.QueryBuilder.insertInto;
3import static com.datastax.driver.core.querybuilder.QueryBuilder.ttl;
4
5Statement stmt = insertInto("app", "sessions")
6    .value("user_id", bindMarker())
7    .value("token", bindMarker())
8    .using(ttl(bindMarker()));

That difference is why many answers online appear to disagree with each other. They are often correct for different driver generations. Check the imported package names before copying an example.

What TTL really applies to

TTL applies to the values you write in that statement. It is not a query timeout, and it is not a server-side scheduler. Cassandra stores expiration metadata with the cells and discards them when the TTL has elapsed. If you update only some columns in a row, the TTL affects the columns you touched, not every column in the row by default.

This is also why TTL belongs in the statement builder. The retention rule is part of the data mutation itself.

Common Pitfalls

The biggest pitfall is mixing driver 3 and driver 4 examples. If your imports start with com.datastax.oss.driver, use usingTtl(...). If they start with com.datastax.driver.core, the older using(ttl(...)) syntax is likely the one you need.

Another mistake is binding parameters in the wrong order. Prepared statement bind markers are positional, so the TTL marker must be bound where it appears in the query.

Developers also assume TTL behaves like a row-wide expiration switch. In Cassandra, TTL is attached to written cells, so partial updates can produce rows whose columns expire at different times.

Finally, remember that 0 is not "expire now" in the driver 4 QueryBuilder API. It removes the TTL on the written data.

Summary

  • In Java driver 4, pass TTL with usingTtl(...) on the QueryBuilder statement.
  • Use a bind marker when TTL varies per write, and a literal when it is fixed.
  • In older driver 3 code, the equivalent syntax is using(ttl(...)).
  • TTL is part of the mutation and applies to the cells written by that statement.
  • Be careful with bind order and the special meaning of a TTL value of 0.

Related reading
Course
Beginner
27 lessons
10 hours
System Design Fundamentals

Build a strong foundation in designing scalable, reliable distributed systems.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

All Rights Reserved.