Implementation status

This page summarizes the features supported by different Parquet implementations.

Note: If you find out of date information, please help us improve the accuracy of this page by opening an issue or submitting a pull request.

Legend

The value in each box means:

  • ✅: supported. Footnote added when support is partial. When data is available, links to release notes are provided on the implementing version.
  • ❌: not supported
  • (R): only read support
  • (W): only write support
  • (blank): no data

Implementations

Physical types

Physical types are defined by the enum Type in parquet.thrift

Data Typearrowparquet-javaarrow-goarrow-rsClickHousecudfhyparquetduckdbpolarsDataHaskell
BOOLEAN✅✅✅✅✅✅✅✅✅✅
INT32✅✅✅✅✅✅✅✅✅✅
INT64✅✅✅✅✅✅✅✅✅✅
INT961✅✅✅✅(R)(2)✅(R)(R)(R)(R)
FLOAT✅✅✅✅✅✅✅✅✅✅
DOUBLE✅✅✅✅✅✅✅✅✅✅
BYTE_ARRAY✅✅✅✅✅✅✅✅✅✅
FIXED_LEN_BYTE_ARRAY✅✅✅✅✅✅✅✅(R)(R)
Notes:
(1) This type is deprecated, but as of 2024 it’s common in currently produced parquet files
(2) Read as DateTime64(9); INT96 is never written.

Logical types

Logical types are defined by the union LogicalType in parquet.thrift and described in LogicalTypes.md

Data Typearrowparquet-javaarrow-goarrow-rsClickHousecudfhyparquetduckdbpolarsDataHaskell
STRING✅✅✅✅✅✅✅✅✅✅
ENUM❌✅✅✅(1)✅(2)(R)(3)✅✅(R)(R)(3)
UUID❌✅✅✅(1)✅(R)(1)✅✅(R)❌
8, 16, 32, 64 bit signed and unsigned INT✅✅✅✅✅✅✅✅✅(R)(4)
DECIMAL (INT32)✅✅✅✅(R)(5)✅✅✅(R)(R)(6)
DECIMAL (INT64)✅✅✅✅(R)(5)✅✅✅(R)(R)(6)
DECIMAL (BYTE_ARRAY)✅✅✅✅(R)(5)✅✅(R)(R)❌
DECIMAL (FIXED_LEN_BYTE_ARRAY)✅✅✅✅✅(7)✅✅✅✅❌
FLOAT16 (2023)✅✅(1)✅✅(R)(8)(R)(1)✅✅✅❌
DATE✅✅✅✅✅✅✅✅✅(R)(9)
TIME (INT32)✅✅✅✅(R)(10)✅✅✅(R)(R)(9)
TIME (INT64)✅✅✅✅(R)(10)✅✅✅✅(R)(9)
TIMESTAMP (INT64)✅✅✅✅✅(11)✅✅✅✅✅(12)
INTERVAL✅✅(1)✅✅❌(13)❌✅✅(R)❌
JSON✅✅(1)✅✅(1)✅(14)(R)(15)✅✅❌(R)(15)
BSON❌✅(1)✅✅(1)(R)(16)❌❌❌❌❌
VARIANT (2025)✅✅✅❌(R)(17)✅✅❌❌
GEOMETRY (2025)✅✅❌✅❌(18)❌✅✅(R)❌
GEOGRAPHY (2025)✅✅❌✅❌(18)❌✅✅(R)❌
FILE (2026)❌❌❌✅❌❌❌❌❌❌
LIST✅✅✅✅✅✅✅✅✅(R)
MAP✅✅✅✅✅✅✅✅(R)❌
UNKNOWN (always null)✅✅✅✅(R)✅✅✅✅❌
Notes:
(1) Only supported to use its annotated physical type
(2) Read as String; ClickHouse Enum8/Enum16 are written as ENUM.
(3) Read back as a plain string; the ENUM annotation is not surfaced.
(4) Signed integers only; unsigned annotations are read as signed values of the same width.
(5) Decimals are always written as FIXED_LEN_BYTE_ARRAY.
(6) Decimals are converted to Double on read, so precision above 15 digits is lost.
(7) Precision up to 76 digits.
(8) Read as Float32.
(9) Surfaced as the raw INT32/INT64 value; the DATE/TIME annotation is not applied.
(10) Read as DateTime64, or as Time64 when requested explicitly; ClickHouse Time/Time64 cannot be written.
(11) Milliseconds, microseconds and nanoseconds.
(12) Milliseconds, microseconds and nanoseconds are read; the writer always emits microseconds.
(13) Read as raw FixedString(12) bytes.
(14) Read as the JSON data type by default, or as String.
(15) Read back as a plain string; the JSON annotation is not surfaced.
(16) Read as raw bytes in a String column.
(17) Read as metadata/value byte lists with shredded typed children exposed; experimental extraction supports unshredded values only.
(18) GeoParquet (“geo” key-value metadata) is supported instead; WKB and WKT are read, WKB is written.

Encodings

Encodings are defined by the enum Encoding in parquet.thrift and described in Encodings.md

Encodingarrowparquet-javaarrow-goarrow-rsClickHousecudfhyparquetduckdbpolarsDataHaskell
PLAIN✅✅✅✅✅✅✅✅✅✅
PLAIN_DICTIONARY✅✅✅✅(R)✅✅(R)(R)(R)
RLE_DICTIONARY✅✅✅✅✅✅✅✅✅(R)
RLE✅✅✅✅✅(1)✅✅✅(R)✅(2)
BIT_PACKED (deprecated)✅✅✅❌(3)❌(R)✅❌❌❌
DELTA_BINARY_PACKED✅✅✅✅(R)✅✅✅(R)❌
DELTA_LENGTH_BYTE_ARRAY✅✅✅✅(R)✅✅✅(R)❌
DELTA_BYTE_ARRAY✅✅✅✅(R)✅✅✅(R)❌
BYTE_STREAM_SPLIT (2020)✅✅✅✅(R)✅✅✅(R)❌
ALP (2026)❌❌❌✅❌❌❌❌❌❌
BYTE_STREAM_SPLIT (Additional Types) (2024)✅✅✅✅(R)✅✅❌❌❌
Notes:
(1) Written only for repetition and definition levels; RLE-encoded BOOLEAN values are read.
(2) Used for repetition and definition levels.
(3) Partial read support, but only in the case of level data with a bitwidth of 0

Compression Codecs

Compressions are defined by the enum CompressionCodec in parquet.thrift and described in Compression.md

Compressionarrowparquet-javaarrow-goarrow-rsClickHousecudfhyparquetduckdbpolarsDataHaskell
UNCOMPRESSED✅✅✅✅✅✅✅✅✅✅
BROTLI✅✅✅✅✅(R)(R)✅✅❌
GZIP✅✅✅✅✅✅(R)✅✅(R)
LZ4 (deprecated)✅❌❌✅(R)(1)❌(R)❌❌❌
LZ4_RAW✅✅✅✅✅✅(R)✅✅❌
LZO❌❌❌❌❌❌❌❌(R)❌
SNAPPY✅✅✅✅✅✅✅✅✅✅
ZSTD✅✅✅✅✅✅(R)✅✅(R)
Notes:
(1) Both Hadoop-framed and raw LZ4 blocks are read; LZ4_RAW is written instead.

Other format level features

Featurearrowparquet-javaarrow-goarrow-rsClickHousecudfhyparquetduckdbpolarsDataHaskell
xxHash-based bloom filters (2019)✅✅✅✅✅(R)✅✅❌❌
Bloom filter length1✅✅✅✅✅(R)✅✅❌❌
Statistics min_value, max_value✅✅✅✅✅✅✅✅✅❌
Page index (2018)✅✅✅✅✅✅✅(R)(R)❌
Page CRC32 checksum✅✅❌✅✅❌❌(R)(R)❌
Modular encryption (2019)✅✅✅✅R❌❌❌✅(2)❌❌
Size statistics (2023)3✅✅(R)✅✅✅(R)(R)(R)❌
Data Page V24✅✅✅✅(R)✅✅✅(R)(R)
Notes:
(1) In parquet.thrift: ColumnMetaData->bloom_filter_length
(2) Partial support
(3) In parquet.thrift: ColumnMetaData->size_statistics
(4) In parquet.thrift: DataPageHeaderV2

High level data APIs for Parquet feature usage

Featurearrowparquet-javaarrow-goarrow-rsClickHousecudfhyparquetduckdbpolarsDataHaskell
Parquet summary file1✅✅❌❌❌(W)❌❌❌❌
Row group "Sorting column" metadata2✅❌✅✅❌(W)❌(R)(R)❌
Row group pruning using statistics❌✅✅(3)✅✅✅✅✅✅❌
Row group pruning using bloom filter❌✅✅(3)✅✅✅✅✅❌❌
Row group pruning using dictionary pages4✅✅(5)
Reading select columns only✅✅✅✅✅✅✅✅✅✅
Page pruning using statistics❌✅✅(3)✅✅✅(5)✅❌❌❌
Page pruning using row survival mask6✅✅✅(5)✅(7)
Selective page reads8✅✅✅(5)
Late Materialization9✅✅(5)✅✅(7)
Caller-driven parquet scan10✅✅(5)
Notes:
(1) Files named _metadata that consolidate footers from multiple parquet files.
(2) In parquet.thrift: RowGroup->sorting_columns
(3) Partial support
(4) Skip a row group when a column dictionary proves the predicate cannot match.
(5) Provided by the experimental cuDF Hybrid Scan APIs (multifile version).
(6) Decompress and decode only pages containing at least one surviving row. The row survival mask may originate from predicate evaluation or be caller-supplied, e.g. derived from Iceberg/Delta deletion vectors.
(7) Supported with parallel="prefiltered".
(8) Fetch, decompress and decode only the required pages determined by mechanisms in (6). Requires an OffsetIndex for selected column chunks.
(9) Evaluate predicate columns first, then use the resulting row mask to skip unneeded payload pages and materialize only surviving rows. See Arrow blog for details.
(10) Advanced APIs to let callers prune row groups and pages, and schedule I/O and compute work (single-pass or late materialization) using the fetched buffers. See cuDF Hybrid Scan APIs and Arrow push decoder for details.

Minimum Version for Read Support by Year

This table shows the minimum engine version required to read Parquet files using features introduced in each year. Only includes compression, encodings, physical types, and logical types. Features without a specified format version are assumed to have been added prior to 2023.

Note: This data was originally collected in December 2025, and not all data was backfilled. It is likely older releases of each engine support reading all features for 2023 and before. As volunteers have time they are invited to add more granular details on releases. Generally, versions are expected to be accurate for any year 2025 and after.

Note: The following features are excluded from this table: ENUM, UUID, INTERVAL, JSON, BSON, BIT_PACKED (deprecated), LZ4 (deprecated), LZO.

Engine≤2023 Features2024 Features2025 Features2026 Features
Apache Arrow C++18.0.0
(2024-10-28)
18.0.0
(2024-10-28)
❌❌
Parquet Java1.14.1
(2024-07-16)
1.14.1
(2024-07-16)
1.16.0
(2025-09-03)
❌
Apache Arrow Go18.4.0
(2025-07-21)
18.4.0
(2025-07-21)
❌❌
Apache Arrow Rust52.2.0
(2024-07-28)
53.0.0
(2024-08-31)
57.0.0
(2025-10-19)
60.0.0
(2026-09-15)
ClickHouse26.9
(2026-09-21)
26.9
(2026-09-21)
❌❌
cuDF25.12.00
(2025-12-10)
25.12.00
(2025-12-10)
❌❌
Hyparquet1.0.0
(2024-06-23)
1.0.0
(2024-06-23)
1.24.0
(2026-01-09)
❌
DuckDB1.4.0
(2025-09-16)
❌❌❌
Polars1.37.0
(2026-01-10)
❌❌❌
DataHaskell❌❌❌❌