For AI agents: the complete documentation index is at llms.txt. Every page is also available as markdown by appending .md to its URL, or by sending an Accept: text/markdown request header.

ALTER TABLE FORCE REINDEX PARQUET

Rebuilds the indexes of Parquet partitions while the table stays online. Queries keep running against the current partition data until the rebuild commits, so you can repair indexes without the downtime that REINDEX ... LOCK EXCLUSIVE requires.

The main use is repairing tables written by QuestDB 9.3.4 through 10.0.1. Those versions could leave stale column-top metadata on a Parquet partition after merging out-of-order rows into it, leaving the partition's indexes out of step with its data. FORCE REINDEX PARQUET corrects that metadata and rebuilds the indexes from the Parquet file. It also rebuilds an index that is damaged for any other reason, such as a missing index file.

FORCE REINDEX PARQUET is available from QuestDB 10.2.0 and QuestDB Enterprise 4.2.0.

Syntax​

ALTER TABLE tableName FORCE REINDEX PARQUET
[COLUMN columnName]
[PARTITION LIST partitionName [, partitionName ...]];
  • COLUMN columnName rebuilds only the index of columnName, which must be an indexed column. Without it, every index of the table is rebuilt.
  • PARTITION LIST rebuilds only the listed partitions. The partition name must match the name of the partition's directory, as described in Partitions. Without it, every Parquet partition of the table is rebuilt.

Both bitmap and posting indexes are rebuilt, including the covering columns of a posting index.

Examples​

Rebuild every index on every Parquet partition
ALTER TABLE trades FORCE REINDEX PARQUET;
Rebuild the index of one column
ALTER TABLE trades FORCE REINDEX PARQUET COLUMN symbol;
Rebuild one column's index on selected partitions
ALTER TABLE trades FORCE REINDEX PARQUET COLUMN symbol
PARTITION LIST '2026-03-01', '2026-03-02';

To find the partitions that are in Parquet format, filter table_partitions() on its isParquet column:

List Parquet partitions
SELECT name FROM table_partitions('trades') WHERE isParquet;

How it works​

Each partition is rebuilt into a new partition directory version. The new version shares the Parquet file with the old one through hard links and gets freshly built index files of its own. Queries that started before the rebuild keep reading the old version until they finish, and QuestDB removes the old version once nothing references it. Retired index files are also reclaimed by VACUUM TABLE.

The statement commits each partition separately. If it stops partway, the partitions it already rebuilt stay rebuilt, and running the statement again finishes the rest.

The statement has no timeout. A CANCEL QUERY or a dropped client connection stops it once the partition in progress is committed.

The statement runs outside the write-ahead log and changes only the node it runs on. It is not replicated.

Partitions that are skipped​

  • Native partitions are never rebuilt. On a non-WAL table the active partition stays in native format, so it is left out. Use REINDEX TABLE ... LOCK EXCLUSIVE for native partitions.
  • Cold partitions that live only in object storage have no local files to rebuild. They are skipped, and the statement fails if every selected partition is cold.
  • Partitions attached from a soft link are skipped, because a new directory version would move them off their attached volume.

Automatic repair​

You do not need FORCE REINDEX PARQUET for affected partitions that are rewritten for another reason. QuestDB repairs stale column metadata on its own when:

  • ALTER TABLE ALTER COLUMN ADD INDEX runs. It repairs every affected local Parquet partition in the same transaction, so the new index is built over correct metadata.
  • An out-of-order write lands in an affected Parquet partition. The partition is rewritten with correct metadata.

Deduplication on Parquet partitions reads key values from the Parquet data rather than from the stale metadata, so it removes duplicates correctly whether or not the partition has been repaired.

Permissions​

In QuestDB Enterprise, the statement requires the REINDEX permission on the table, or on the column when COLUMN is given. See permissions.

Replication​

In QuestDB Enterprise, the statement also runs on read-only replicas. Its changes stay on the local node and do not advance the replica's replicated transaction sequence. Because nothing is replicated, run it on the primary and on every replica that holds affected partitions.

Errors​

ErrorCause
'parquet' expectedThe PARQUET keyword is missing after FORCE REINDEX.
Invalid column: columnNameThe column does not exist.
column is not indexedThe COLUMN clause names a column without an index.
partition does not existA partition in PARTITION LIST does not exist.
partition is not parquet, use REINDEX TABLE ... LOCK EXCLUSIVE for native partitionsA partition in PARTITION LIST is in native format. No partition is rebuilt.
cannot reindex cold partitions, they have no local dataEvery selected partition is cold.
table is not partitioned, use REINDEX TABLE ... LOCK EXCLUSIVEThe table has no partitions, so it has no Parquet partitions.

The statement also fails, rather than waiting, when another operation holds the table writer, for example while WAL transactions are being applied. Retry it once the writer is free.

See also​