All Products
Search
Document Center

Tablestore:Consume incremental data

Last Updated:Aug 05, 2026

The Stream API in the Tablestore SDK for Java consumes incremental changes to a table, including inserts, updates, and deletes.

Prerequisites

Description

Stream organizes incremental changes from a table into shards. To consume a stream, call four APIs in sequence: list streams, describe a stream, get a shard iterator, and fetch records.

  1. Call listStream(ListStreamRequest) to list the streamId values of all Stream-enabled tables in the instance.

  2. Call describeStream(DescribeStreamRequest) to retrieve stream metadata (creation time, expiration time, current status) and the list of Shard objects.

  3. Call getShardIterator(GetShardIteratorRequest) to get the read iterator (shardIterator) for a specific Shard. The iterator marks where to start fetching incremental records.

  4. Call getStreamRecord(GetStreamRecordRequest) with the shardIterator to fetch a batch of incremental records (a list of StreamRecord objects). Use the returned nextShardIterator to fetch subsequent records.

public ListStreamResponse listStream(ListStreamRequest request) throws TableStoreException, ClientException
public DescribeStreamResponse describeStream(DescribeStreamRequest request) throws TableStoreException, ClientException
public GetShardIteratorResponse getShardIterator(GetShardIteratorRequest request) throws TableStoreException, ClientException
public GetStreamRecordResponse getStreamRecord(GetStreamRecordRequest request) throws TableStoreException, ClientException

The following example consumes the stream_test_demo stream end-to-end and prints the type and primary key of each record.

String demoTable = "stream_test_demo";

// 1. List all tables in the instance with Stream enabled and find the streamId of the target table.
ListStreamRequest listRequest = new ListStreamRequest(demoTable);
ListStreamResponse listResponse = client.listStream(listRequest);

String targetStreamId = null;
for (Stream stream : listResponse.getStreams()) {
    if (demoTable.equals(stream.getTableName())) {
        targetStreamId = stream.getStreamId();
        break;
    }
}
System.out.println("Stream ID: " + targetStreamId);

// 2. Query all shards of the Stream.
DescribeStreamRequest describeRequest = new DescribeStreamRequest(targetStreamId);
DescribeStreamResponse describeResponse = client.describeStream(describeRequest);
List<StreamShard> shards = describeResponse.getShards();
System.out.println("Shard count: " + shards.size());

if (!shards.isEmpty()) {
    String shardId = shards.get(0).getShardId();

    // 3. Get the initial read iterator of the shard.
    GetShardIteratorRequest iterRequest =
            new GetShardIteratorRequest(targetStreamId, shardId);
    GetShardIteratorResponse iterResponse = client.getShardIterator(iterRequest);
    String shardIterator = iterResponse.getShardIterator();

    // 4. Use the iterator to pull incremental records from the shard.
    GetStreamRecordRequest recordRequest = new GetStreamRecordRequest(shardIterator);
    recordRequest.setLimit(100);
    GetStreamRecordResponse recordResponse = client.getStreamRecord(recordRequest);

    List<StreamRecord> records = recordResponse.getRecords();
    System.out.println("Records fetched: " + records.size());
    for (StreamRecord record : records) {
        System.out.println("RecordType: " + record.getRecordType()
                + ", PK: " + record.getPrimaryKey());
    }

    // nextShardIterator is used to continue pulling subsequent incremental records.
    System.out.println("Next iterator: "
            + (recordResponse.getNextShardIterator() != null ? "yes" : "no"));
}

Parameters

List streams request

ListStreamRequest contains the following parameter.

Name

Type

Description

tableName (optional)

String

The name of the table. If omitted, the request returns stream information for every Stream-enabled table in the instance; otherwise, it returns information only for the specified table.

Describe stream request

DescribeStreamRequest contains the following parameters.

Name

Type

Description

streamId (required)

String

The unique identifier of the stream. Returned by listStream.

inclusiveStartShardId (optional)

String

The starting shardId of the returned shard list. Specify to paginate through large shard sets.

shardLimit (optional)

int

The maximum number of shards to return in the response.

Get shard iterator request

GetShardIteratorRequest contains the following parameters.

Name

Type

Description

streamId (required)

String

The unique identifier of the stream. Returned by describeStream.

shardId (required)

String

The unique identifier of the shard. Returned in the StreamShard object by describeStream.

timestamp (optional)

long

The starting timestamp of the iterator, in microseconds. If omitted, reading starts from the beginning of the shard.

Read incremental data request

GetStreamRecordRequest contains the following parameters.

Name

Type

Description

shardIterator (required)

String

The read iterator. Returned by getShardIterator or by the nextShardIterator field of the previous getStreamRecord response.

limit (optional)

int

The maximum number of StreamRecord objects to return in the response.

tableName (optional)

String

The name of the table that contains the target shard.

Response

Stream list

ListStreamResponse contains the following operation-specific field.

Name

Type

Description

streams

List<Stream>

The Stream information list. Each element includes information such as the table name, Stream ID, and expiration time. Call getStreams() to obtain the list.

Stream information

DescribeStreamResponse contains the following operation-specific fields.

Name

Type

Description

streamId

String

The Stream ID.

tableName

String

The name of the data table.

creationTime

long

The time when the Stream was created.

expirationTime

int

The expiration time of the Stream.

status

StreamStatus

The Stream status.

shards

List<StreamShard>

The shards returned on the current page.

nextShardId

String

The start shard ID of the next page. A null value indicates that all shards have been returned.

timeseriesDataTable

boolean

Indicates whether the table is a time series data table. Call isTimeseriesDataTable() to obtain the value.

Shard iterator

GetShardIteratorResponse contains the following operation-specific field.

Name

Type

Description

shardIterator

String

The iterator for the specified shard. Use this value in the first getStreamRecord() request.

Incremental data

GetStreamRecordResponse contains the following operation-specific fields.

Name

Type

Description

records

List<StreamRecord>

The incremental records returned in the response.

nextShardIterator

String

The iterator for the next read. A null value indicates that the current shard has been fully read.

mayMoreRecord

Boolean

Indicates whether the current shard may contain more records.

Examples

Paginate through the shard list

For streams with many shards, paginate with inclusiveStartShardId and shardLimit. A null nextShardId indicates that all shards have been returned.

String currentStreamId = "<your-stream-id>";
String startShardId = null;
int totalShards = 0;

while (true) {
    DescribeStreamRequest request = new DescribeStreamRequest(currentStreamId);
    if (startShardId != null) {
        request.setInclusiveStartShardId(startShardId);
    }
    request.setShardLimit(50);

    DescribeStreamResponse response = client.describeStream(request);
    totalShards += response.getShards().size();

    // A null nextShardId indicates that all shards have been traversed.
    if (response.getNextShardId() == null) {
        break;
    }
    startShardId = response.getNextShardId();
}
System.out.println("Total shards: " + totalShards);

Continuously poll incremental data

Repeatedly call getStreamRecord with nextShardIterator to fetch incremental records from a single shard. A null nextShardIterator indicates that the current shard has been fully consumed.

String currentStreamId = "<your-stream-id>";
String shardId = "<your-shard-id>";

GetShardIteratorRequest iterRequest =
        new GetShardIteratorRequest(currentStreamId, shardId);
String shardIterator = client.getShardIterator(iterRequest).getShardIterator();

int totalRecords = 0;
while (shardIterator != null) {
    GetStreamRecordRequest recordRequest = new GetStreamRecordRequest(shardIterator);
    recordRequest.setLimit(100);
    GetStreamRecordResponse response = client.getStreamRecord(recordRequest);

    totalRecords += response.getRecords().size();
    shardIterator = response.getNextShardIterator();
}
System.out.println("Polling total records: " + totalRecords);