Fact-checked by Grok 2 weeks ago

Apache ORC

Apache ORC (Optimized Row Columnar) is a free and open-source, self-describing, type-aware columnar file format designed for efficient storage and high-performance querying of large datasets in Hadoop workloads. It organizes data into columns rather than rows to enable selective reading, compression, and fast streaming access, while supporting complex data types such as structs, lists, maps, and unions. Developed in January 2013 as part of the project to accelerate query performance and enhance storage efficiency over predecessors like RCFile, ORC was introduced to address limitations in processing petabyte-scale s. Early adoption by organizations like , which scaled its to over 300 petabytes using ORC, demonstrated significant savings in storage and query times compared to alternative formats. In April 2015, ORC graduated to become a top-level Apache project, separating from to support independent development and non-Java implementations, including C++ libraries for broader interoperability. ORC files are structured into header, stripes (default 64 MB for ), row groups, and footer sections, with built-in indexes and bloom filters enabling predicate pushdown to skip irrelevant during reads. It supports advanced features like native (e.g., Zstandard), encryption, and transaction compatibility in systems like and , making it suitable for modern data lakes and analytics pipelines. Widely integrated with tools such as , Trino, , and , ORC remains a cornerstone for columnar storage in ecosystems due to its balance of performance, compactness, and ecosystem compatibility.

Overview

Definition and Purpose

Apache ORC (Optimized Row Columnar) is a , open-source, self-describing, type-aware columnar designed for efficient storage and retrieval in Hadoop workloads. It organizes data column by column rather than row by row, enabling selective access to specific columns during queries, which is particularly suited for analytical processing in distributed environments. Developed in January 2013 as part of initiatives to enhance performance, ORC originated to address limitations in earlier storage formats by improving query speed and data compression in data warehouses. Its primary purpose is to optimize Hive queries through mechanisms such as reduced (I/O) operations, where only necessary columns and row groups are read from disk, thereby minimizing data transfer and processing overhead. Additionally, ORC supports predicate pushdown, allowing filters to be applied early using built-in indexes at file, stripe, and row levels to skip irrelevant data sections efficiently. ORC is engineered for large streaming reads, facilitating high-throughput sequential access common in while preserving full type information from table schemas, including complex types like structs, lists, maps, and unions. This type retention ensures compatibility with Hive's schema evolution and enables precise data handling without loss of semantic meaning during storage and retrieval. By combining these features, ORC significantly boosts overall system efficiency in Hadoop ecosystems, making it a foundational component for scalable data processing.

Key Characteristics

Apache ORC employs a columnar organization, where is stored by columns rather than rows, enabling efficient selective reading of only the required columns during queries to minimize operations. This design significantly reduces the amount of that needs to be read from , making it particularly suitable for analytical workloads that access specific subsets of . As a self-describing format, ORC files embed the schema and metadata directly within the file, eliminating the need for external schema definitions and allowing readers to understand the structure without additional configuration. This type-aware approach ensures that the format is optimized for Hadoop ecosystems, where seamless integration with tools like is essential. ORC provides full support for Hive's primitive and complex data types, including structs, lists, maps, unions, decimals, timestamps, and , enabling rich without loss of fidelity. This comprehensive facilitates advanced data processing tasks in environments. The format is optimized for high-throughput streaming reads in scenarios, while incorporating mechanisms for quick access to specific rows through internal indexing. This balance supports efficient performance in large-scale data lakes, where rapid sequential access is common.

History

Origins and Development

Apache ORC originated in early as a collaborative effort between Hortonworks and to overcome the storage inefficiencies of existing file formats, such as RCFile, which struggled with compression and query performance on massive datasets. Hortonworks engineers, led by figures like Owen O'Malley, designed ORC to enable high-speed processing and reduced file sizes within the Hadoop ecosystem, particularly for workloads. The project was publicly announced in February 2013, highlighting its potential to handle petabyte-scale data more effectively, drawing from Facebook's experiences managing over 300 petabytes of data with daily influxes exceeding 600 terabytes. This collaboration addressed critical scaling needs, where traditional formats yielded only about 5x , while aimed for significant improvements through columnar storage and advanced encodings. Facebook's data infrastructure team, including Pamela Vagata and Kevin Wilfong, contributed insights from their warehouse operations to refine the format for real-world efficiency. In March 2013, ORC was accepted into the Apache Incubator as an independent project, marking its transition toward broader while retaining close ties to . Initial integration occurred with 0.11.0, released in May 2013, allowing users to leverage ORC for optimized reads and writes in production environments. This early adoption by major Hadoop users like and underscored ORC's role in enabling faster queries on vast datasets without extensive infrastructure changes.

Major Releases

ORC was first released as part of version 0.11.0 on May 15, 2013, providing basic columnar storage capabilities optimized for Hadoop workloads, including lightweight indexes and for efficient querying. Subsequent milestones advanced the format's maturity and functionality. 1.0, released on January 25, 2016, marked the first independent Apache ORC project release, introducing a native C++ reader for cross-platform compatibility and tools for file inspection, while standardizing the ORC v1 file format originally developed in Hive 0.12. 1.4, released on May 8, 2017, added practical utilities such as code for comparing file formats, a tool for converting to ORC, and "nohive" JARs to decouple ORC from Hive dependencies, enhancing portability. 1.6, released on September 3, 2019, introduced column-level for in sensitive data environments and support for to improve ratio and speed over previous options like ZLIB. 2.0, released on March 8, 2024, shifted the default version to 17, dropped support for Java 8 and 11, and set as the default algorithm, alongside optimizations for memory management and false positive rates. The latest release, version 2.2.1, was issued on October 1, 2025, incorporating upgrades to Hadoop 3.4.2 for better ecosystem alignment, continuous integration fixes such as UBSAN test compatibility and expanded GitHub Actions support for Debian 13 and macOS 26, and Maven dependency updates including the enforcer plugin to 3.6.1 and JUnit to 5.13.4. Under Apache Software Foundation governance since 2015, ORC maintains a steady release cadence with minor versions addressing bugs and dependencies, emphasizing backward compatibility to ensure seamless upgrades across Hadoop-based systems and ongoing performance enhancements for large-scale data processing.

File Format

Overall Structure

An ORC file is organized into three primary sections: a header, a body, and a tail, which together provide a self-describing columnar layout optimized for efficient in distributed systems. The header consists of fixed magic bytes reading "" (three bytes in ASCII), serving as an identifier to confirm the upon reading. The body comprises one or more stripes, each representing an independent unit of data typically sized at around 200 MB of to facilitate large, efficient streaming reads from storage systems like HDFS. The default configuration is 64 MB, which can be adjusted as needed. Stripes enable by encapsulating complete subsets of the , with each stripe containing index streams for fast seeking to specific row groups, data streams holding columnar chunks of the actual records, and a stripe footer that includes statistics such as minimum and maximum values per column along with row counts to aid query optimization. Within each stripe, the data is further divided into row groups, with a default size of rows per group to support lightweight indexing and skipping during scans. These row groups allow readers to locate and access subsets of rows without loading the entire stripe, enhancing performance for selective queries. The tail section follows the body and includes the file , footer, , and a single-byte length indicator for the postscript. The , which is uncompressed and limited to a maximum of 256 bytes, records essential details such as the compression algorithm used (with options including ZLIB, Snappy, and others), the compression block size, the file version (typically [0,12] corresponding to the Hive 0.12 release), lengths of the footer and metadata, and the "ORC" magic string for validation. The footer, encoded using for compactness, contains the file schema, information on stripe locations and counts, the total row count, and aggregate column statistics across the entire file. Finally, the provides additional stripe-level statistics to support advanced optimizations like predicate pushdown. The described structure follows the ORC v1 specification, which remains the current as of ORC project release 2.2.1 (October 2025).

Schema and Data Types

The schema in an Apache ORC file is stored in the footer and encoded using to represent a of types, which is then flattened into a linear list via pre-order traversal to assign column indexes starting from 0 for the root type. This self-describing approach ensures that the is independent of external systems, allowing readers to fully interpret the file's structure and data types without additional context. ORC supports a range of types to handle basic data elements efficiently in a columnar format. These include for true/false values, BYTE (8-bit signed ), SHORT (16-bit signed ), (32-bit signed ), LONG (64-bit signed ), FLOAT (32-bit IEEE floating point), DOUBLE (64-bit IEEE floating point), STRING for variable-length strings, BINARY for variable-length byte arrays, TIMESTAMP for date-time without timezone (milliseconds since Unix epoch), for arbitrary-precision numbers with scale, for days since Unix epoch, for length-limited strings, and CHAR for fixed-length strings. For nested and structured data, ORC provides complex types that build upon primitives to form hierarchical schemas. A LIST type contains a single type for its elements, enabling arrays of homogeneous values; a type has two types, one for keys (often primitive) and one for values; a STRUCT type defines named fields, each as a column with its own type; a supports variants by specifying multiple possible types, selected by a value; and TIMESTAMP_INSTANT extends by incorporating timezone information for locale-aware datetime handling. All types, primitive and complex, natively support null values to accommodate missing data. ORC facilitates type evolution to manage schema changes over time, such as adding or reordering columns, through mechanisms like union types for variant handling and the SchemaEvolution class, which infers compatible mappings between file and reader schemas, supporting implicit conversions and positional or name-based matching as configured.

Compression and Encoding

Compression Algorithms

Apache ORC utilizes block-level to efficiently reduce the footprint of large datasets while optimizing read . This is applied to the data streams within stripes, the core organizational units of ORC files, and operates on configurable chunks typically sized at 256 by default. Supported algorithms encompass NONE (for uncompressed ), ZLIB, SNAPPY, LZO, LZ4, , and (added in ORC 2.0.0). ZLIB serves as the default in implementations, while has been the default in ORC core since version 2.0.0 (2024); SNAPPY is commonly selected for its favorable trade-off between speed and ratio in high-throughput environments. The postscript section at the file's conclusion records the chosen compression kind and chunk size parameters, applying uniformly across the entire file to guide consistent processing by readers. Compression occurs independently per stripe, ensuring that failures or variations in one stripe do not affect others, and each compressed chunk prepends a minimal 3-byte header encoding the compressed length and a flag indicating if compression was skipped (e.g., when it would increase size). If compression yields no benefit, the original uncompressed data is retained to avoid unnecessary overhead. Leveraging its columnar format, ORC supports selective , where only the required columns or portions of row groups within stripes are processed during reads, minimizing I/O and CPU costs for targeted queries. This efficiency stems from the inherent data similarity within columns, which enhances , combined with chunk headers that add negligible size—often just a few percent even for highly fragmented data. File footers containing stripe-level statistics further support skip mechanisms, allowing readers to bypass irrelevant compressed blocks without . These general-purpose codecs build upon prior encodings for additional size reduction.

Encoding Techniques

Apache ORC utilizes a of lightweight, column-specific encoding techniques designed to exploit data patterns like , sequential ordering, and limited value ranges, thereby improving storage efficiency and read performance in its columnar structure. These encodings operate at the level of individual columns within row groups or stripes, transforming into more compact representations before any block-level is applied. By adapting to the statistical properties of each column—such as , bit width, and sortedness—ORC's writers select the most suitable encoding dynamically, recording the choice in the file's for accurate decoding during reads. Dictionary encoding is particularly effective for columns with repeated or low-cardinality values, such as strings or categorical data, where it replaces occurrences of each unique value with a compact integer identifier from a shared dictionary. The dictionary itself, containing the sorted unique values (e.g., UTF-8 encoded strings), is stored separately in a dedicated stream, while the main data stream holds the sequence of IDs, which are further encoded using run-length encoding to handle repetitions efficiently. For instance, a column listing U.S. states might build a dictionary like "CaliforniaFloridaNevada" for the values ["California", "Florida", "Nevada"], with the data stream representing [0, 1, 2] as encoded integers. ORC writers typically construct the dictionary progressively, often finalizing it after processing an initial row group of around 10,000 rows to balance build time and compression gains. This approach reduces redundancy in string-heavy datasets, common in Hive tables for dimensions like user IDs or categories. Bit packing provides dense storage for values by allocating a fixed number of bits per value—ranging from 1 to 24 bits—based on the maximum required width for the column's data. It is integrated into broader encodings, such as the mode of RLEv2, where values are grouped and packed into 64-bit words, minimizing unused bits for small s like counts or flags. This technique assumes uniform bit widths within a block and is ideal for numeric columns where values consistently fall below a certain , such as byte-sized enums or short IDs, thereby shrinking storage without loss of . Delta encoding targets sorted or near-sorted integer columns by storing a base value (the first in the sequence) followed by the differences (deltas) between consecutive values, which are then bit-packed for compactness. It excels in scenarios with monotonic trends, such as timestamps, row numbers, or incremental metrics, where deltas are often small and positive. For example, a sequence like [100, 102, 105] becomes a base of 100 and deltas of [0, 2, 5], encoded efficiently if the deltas fit narrow bit widths. This method leverages the predictability in ordered data, common in time-series or partitioned tables, to achieve higher than plain bit packing. Run-length encoding (RLE) in ORC comes in two variants tailored to different data types and patterns. RLEv1 is optimized for or streams, such as present/not-present indicators for nulls, encoding long runs of identical bits (e.g., 100 consecutive zeros as a single run header followed by the value) or short literal sequences using variable-length integers. RLEv2 extends this for general integers with multiple modes: direct for bit-packed values, for sequential differences, and patched base for handling outliers in mostly small-value sets by patching a base encoding with exceptions. For repeated integers, RLEv2 uses short repeat mode to denote runs of the same value, making it versatile for sparse or uniform numeric columns like sensor readings or flags. The selection of these encodings occurs per column during file writing, guided by heuristics that analyze data statistics within each row group or stripe, such as repetition frequency, variance, and bit distribution. For example, low-cardinality strings trigger encoding, while sorted integers favor or RLEv2 modes. This data-type-aware adaptation ensures that each column receives an encoding matched to its profile, with the chosen kind and parameters stored in the StripeFooter under ColumnEncoding for reader interpretation. Overall, these techniques enable to achieve substantial space savings—often outperforming row-based formats—while supporting fast, selective column scans in workflows.

Indexing and Optimization

Internal Indexes

Apache ORC employs internal indexes to facilitate efficient data access and query optimization within its columnar . These indexes are organized on a per- and per-column basis, with a dedicated ROW_INDEX positioned at the beginning of each stripe for every primitive column. This structure allows readers to quickly locate and evaluate relevant portions of the data without scanning the entire file. The core of these indexes is the row index, which divides the data into row groups typically consisting of 10,000 rows, as configurable via the rowIndexStride parameter in the file footer. Each row index entry corresponds to one such row group and includes essential positioning information and statistical summaries for the column within that group. The positions specify the offsets to the start of streams in the row group, accounting for both uncompressed (byte offsets and value counts) and compressed (chunk starts, decompressed sizes, and value counts) data layouts. Additionally, these entries reference offsets to associated , enabling coordinated access during query processing. Row index entries store detailed column statistics to support advanced query optimizations. For each row group, the statistics encompass the count of values, presence of nulls, and type-specific aggregates; for numeric columns, this includes minimum and maximum values, as well as the sum, captured in structures like IntegerStatistics. These statistics are derived during file writing and serialized efficiently to minimize overhead. Binary columns store the sum of their total bytes, while string columns store the minimum and maximum values as well as the sum of their lengths; types store minimum and maximum values, while types store minimum, maximum, and sum values. This granular statistical information is crucial for evaluating query predicates against row groups. The primary function of these internal indexes is to enable pushdown and precise seeking during reads. By comparing query conditions—such as filters (e.g., "age > 100")—against the min/max statistics, the query engine can skip entire row groups that do not satisfy the , a known as data skipping. This mechanism, supported by Search Argument (SARG) evaluation, allows direct seeking to relevant stream positions, bypassing irrelevant data blocks. As a result, selective queries only the necessary row groups, significantly reducing the volume of data scanned and improving overall query performance. Storage of the internal indexes is designed for efficiency and low overhead. The row indexes are protobuf-encoded within the stripe index streams, ensuring compact representation while maintaining fast deserialization. Positioned at the front of each stripe, they are readily accessible without decompressing the full data payload. File- and stripe-level statistics complement the row indexes by providing coarser-grained summaries in the file footer, further aiding initial filtering decisions. This lightweight indexing approach integrates seamlessly with ORC's stripe-based architecture, where stripes represent horizontal partitions of the data.

Bloom Filters

Bloom filters in Apache ORC provide a probabilistic for efficient evaluation during query processing, enabling the reader to quickly determine if a specific value is absent from a row group without scanning its data. This mechanism supports fast negative responses for conditions like WHERE id = 123, allowing the query engine to skip entire row groups (typically 10,000 rows) and reduce I/O overhead. Introduced in Hive 1.2.0, bloom filters enhance pushdown by complementing min/max statistics, particularly for high-cardinality columns where exact matches are sparse. Configuration of bloom filters occurs at the column level via the orc.bloom.filter.columns table property, which specifies which columns receive filters during file writing; by default, none are created to balance storage overhead. One bloom filter is generated per enabled column per row group, with the false positive probability (FPP) tunable through the orc.bloom.filter.fpp setting, defaulting to 0.01 (1%). The FPP influences the number of hash functions (numHashFunctions, or k) and the bitset size (m), computed to approximate the desired error rate while minimizing space; for example, a lower FPP requires more bits and hash functions for better accuracy. Hashing for bloom filters uses type-specific functions: Murmur3 (64-bit, taking the most significant 8 bytes of the 128-bit output) for strings and , and Thomas Wang's 64-bit hash for numeric types like tinyint, smallint, int, bigint, float, and double. Multiple functions are derived from the base hash using the method from Kirsch et al., splitting the 64-bit value into two 32-bit parts (h1 and h2), then computing h1 + i * h2 ( m) for i from 0 to k-1 to set bit positions in the bitset. For dictionary-encoded columns (e.g., strings using or DICTIONARY_V2 encoding), filters hash the dictionary indices rather than raw values, ensuring compatibility with compression schemes. Bloom filters are stored as dedicated streams within each row group's index: BLOOM_FILTER (pre-ORC-101 format, using fixed64 for the bitset) or BLOOM_FILTER_UTF8 (post-ORC-101, using bytes for compact UTF-8-aligned storage). Each filter entry includes the numHashFunctions value followed by the bitset, with offsets recorded in the row index for quick access during reads. This integration allows seamless use in dictionary-encoded setups without additional decoding. As probabilistic structures, bloom filters guarantee no false negatives—a value present in the row group will always test positive—but may produce false positives, where an absent value incorrectly appears present, potentially leading to unnecessary scans. They are evaluated only after min/max index checks pass, limiting their scope to viable row groups, and do not support range predicates beyond equality.

ACID and Security

Transactional Support

Apache ORC provides support for (Atomicity, , , ) transactions, enabling reliable insert, update, and delete operations on transactional tables. This is achieved through a combination of base files for immutable data and delta files for changes, utilizing dynamic stripes and row-level metadata to track operations. Each operation is recorded in ORC files as a struct containing fields such as operation (0 for insert, 1 for update, 2 for delete), originalTransaction, bucket, rowId, currentTransaction, and the affected row. This structure allows to maintain without requiring full rewrites of large datasets. Versioning in ORC ACID tables relies on write IDs assigned by Hive's transaction manager and unique row IDs, which consist of a triple: the original transaction ID, bucket number, and row number within the bucket. These identifiers ensure isolation by allowing readers to merge-sort files based on valid transaction lists retrieved from the Hive metastore, enabling snapshot isolation and capabilities. For instance, updates and deletes reference the original row ID to maintain traceability, preventing conflicts in concurrent environments. Optimizations in ORC enhance ACID performance, including compaction processes that merge small delta files to reduce file fragmentation. Minor compaction combines multiple delta files from recent transactions into a single delta file per bucket, while major compaction rewrites base and delta files into a new base file, discarding obsolete data. Full ACID support has been available since ORC version 1.0 (released in 2016), with later enhancements incorporating vectorized reading for improved query efficiency on transactional tables. Metadata properties, such as hive.acid.key.index, further optimize reads by enabling stripe skipping for irrelevant data. Despite these features, ORC's transactional support is primarily designed for integration with and is not intended for high-frequency OLTP workloads, handling millions of rows per transaction but not millions of transactions per hour. Tables must be created with the transactional=true property, be bucketed on the partition key, and use as the storage format; other formats and external tables are not supported for full operations.

Encryption and Masking

Apache ORC provides column-level encryption to protect sensitive , introduced in version 1.6, using the /CTR algorithm with 128-bit or 256-bit keys. Each encrypted column employs a randomly generated local key, which is itself encrypted using a master key from external systems such as Hadoop's Key Management Server (), Ranger , or AWS . This approach allows for fine-grained control, where only specified columns are encrypted, leaving others unencrypted to optimize storage and access. Key management in ORC involves storing the encrypted local keys within the file's StripeInformation structure, while the keys are referenced by name, version, and algorithm in the EncryptionKey metadata. The file footer includes an message that lists the encrypted columns and supports multiple encryption variants, enabling scenarios like encrypted unmasked data for authorized users and unencrypted masked versions for others. Key rotation is facilitated through versioned keys, allowing updates without re-encrypting the entire dataset. For readers lacking the appropriate decryption keys, ORC applies data masking to prevent unauthorized access to sensitive information, particularly personally identifiable information (PII) in columns. Masking options include nullify, which replaces all values with null (the default behavior); redact, which substitutes characters with fixed patterns such as 'X' for letters or '9' for digits; and SHA-256 hashing, which transforms string values into their cryptographic hashes while preserving the column type. Custom masking implementations can be provided via the DataMask API, ensuring compatibility with the column's data type and enabling tailored privacy protections. Encryption and masking in ORC incur minimal performance overhead due to their selective, column-specific application and transparent integration with Hadoop's key providers, allowing efficient reads for authorized users while skipping or masking data for others. This feature complements ORC's transactional support by focusing on data privacy at rest without impacting ACID compliance.

Usage and Integration

In Apache Hive

Apache Hive utilizes the Optimized Row Columnar (ORC) format as a primary storage option for tables, configurable as the default via the hive.default.fileformat property set to "ORC", with ORC support introduced in Hive version 0.11.0. Tables can be explicitly created in ORC format using the STORED AS ORC clause in the CREATE TABLE statement, which enables columnar storage, built-in compression, and indexing for enhanced query efficiency. Alternatively, TBLPROPERTIES can be used for ORC-specific configurations, such as TBLPROPERTIES ("orc.compress"="SNAPPY"), allowing fine-grained control over file formats during table creation or alteration. Data Definition Language (DDL) operations in Hive fully support ORC tables, including CREATE TABLE for initial setup and ALTER TABLE for ongoing management. The ALTER TABLE command facilitates compaction of ORC files—introduced in Hive 0.13.0—to consolidate small delta files from insert operations into larger, optimized files, thereby improving read performance and storage utilization in transactional environments. This compaction process, which can be major or minor, helps maintain optimal stripe sizes within ORC files without requiring manual file reorganization. Query optimization in benefits significantly from ORC's structure, as the engine automatically applies predicate pushdown during SELECT operations. This technique uses ORC's embedded row indexes to skip non-qualifying row groups and bloom filters to further data at the level, minimizing disk I/O and accelerating filter-based queries. For maintenance, Hive provides the ANALYZE TABLE command—available since version 0.10.0—to compute and update statistics on ORC tables, including row counts, column minima/maxima, and null counts, which inform the cost-based optimizer for better query planning. ORC also integrates natively with Hive's ACID (Atomicity, , , Durability) tables, where it is the sole supported format for full transactional capabilities, enabling features like updates and deletes on managed tables.

With Other Big Data Tools

Apache ORC integrates seamlessly with through native reader and writer support provided by the orc-core Java library, enabling efficient reading and writing of ORC files with features such as column projection and predicate pushdown. Since Spark 2.3, the default ORC implementation includes a vectorized reader that significantly enhances scan throughput by processing data in batches, achieving up to 2-5x performance improvements in benchmarks. This vectorized I/O capability leverages ORC's columnar structure for faster within Spark's DataFrame and SQL APIs. In Presto and its fork Trino, is supported via the connector, which facilitates federated queries across distributed data sources by treating ORC files as tables in a unified SQL . The connector exploits ORC's internal indexes, including bloom filters and column statistics, for pushdown, allowing filters to be applied at the layer to skip irrelevant data stripes and reduce I/O overhead. For instance, equality and small-range predicates can utilize bloom filters with a configurable false positive probability (default 0.05), optimizing query performance in large-scale environments. Beyond these, ORC interfaces with for efficient in-memory data processing and interchange, where Arrow's columnar format aligns naturally with ORC's structure to enable reads and writes. ORC files can be accessed generically through the Hadoop FileSystem API, supporting operations across various storage backends like HDFS without framework-specific dependencies. For non-Java environments, the native C++ library provides high-performance reading and writing capabilities, as utilized in systems like and Vertica. The core ORC ecosystem includes libraries for multiple languages: the library forms the foundation for Hadoop-based integrations, the C++ library handles low-level file operations, and support is available through pyarrow, which offers ORC read/write functions integrated with Arrow's in-memory columnar data. Additionally, orc-tools—a Java-based utility suite—enables file inspection (e.g., viewing , row counts, and column statistics) and conversion (e.g., from or to ORC), facilitating debugging and tasks in pipelines.

Performance and Adoption

Benchmarks and Benefits

Apache ORC achieves significant storage efficiency through its columnar structure and advanced techniques, such as dictionary encoding for strings and adaptive encoding for integers, resulting in files up to 75% smaller than uncompressed text or formats. For instance, in benchmarks with tables, ORC files compressed to 14.2% of the size of equivalent files using default settings. At , adoption of ORC led to an 8x over raw data—improved from 5x with RCFile—reclaiming tens of petabytes of storage space across their 300 PB as of 2014. In terms of query speed, ORC enables 2-10x faster scans in compared to RCFile, primarily through pushdown and lightweight indexes that skip irrelevant data. In , Yahoo's production benchmarks on datasets from 100 GB to 10 TB demonstrated average speedups of 6.2x to 11.8x over RCFile with Hive on Tez, with 85% of queries on 100 GB datasets completing in under a minute. pushdown further enhances this by evaluating filters against column statistics, allowing skips of over 90% of data in selective queries, reducing read volumes to as low as 3% in optimized cases. Benchmark results from TPC-DS-inspired queries in show outperforming by 7.8% to 14.8% on average, with greater advantages for complex data types due to 's native optimizations like type-aware encoding. Yahoo's tests also confirmed high streaming read speeds, with 's 256 MB stripes and supporting efficient distributed processing on petabyte-scale datasets. As of 2025, continues to evolve, with version 2.2.0 introducing further performance enhancements for and reading efficiency. Key benefits of ORC include reduced I/O costs from columnar storage and predicate pushdown, which minimize disk reads, and improved CPU utilization through vectorized execution that processes data in 1,024-row batches rather than row-by-row. This vectorization greatly lowers overhead for operations like scans and filters, enhancing overall efficiency. ORC's design scales seamlessly to petabyte datasets, as evidenced by its use in Facebook's warehouse and Yahoo's production environments.

Notable Implementations

was an early adopter of Apache ORC, deploying it for tables in their , where it enabled significant storage savings of tens of petabytes through advanced and indexing features. The format quickly scaled to support their massive 300+ petabyte as of 2014, facilitating efficient querying and analytics on production-scale workloads. Yahoo adopted ORC as the primary file format for storing production data in their data lakes, leveraging its columnar structure for integration with Hadoop ecosystems to support large-scale analytics. Other notable adopters include Cloudera, which incorporates ORC into its enterprise distributions for optimized Hive performance in big data environments. Alibaba developed the AliORC variant, combining ORC with MaxCompute for enhanced compatibility in cloud-based analytics platforms. In open-source ecosystems, ORC is integrated into projects like , where it supports high-performance data lake management alongside alternatives such as Delta Lake. ORC's adoption has enabled efficient processing in cloud environments, including Amazon EMR for scalable Hive and Spark workloads on S3, and Azure HDInsight, where it is recommended for high-performance Hive data storage.

References

  1. [1]
    Apache ORC • High-Performance Columnar Storage for Hadoop
    Help the smallest, fastest columnar storage for Hadoop workloads. ACID Support Includes support for ACID transactions and snapshot isolation.Doc DocumentationUsing Core Java
  2. [2]
    Background - Apache ORC
    Back in January 2013, we created ORC files as part of the initiative to massively speed up Apache Hive and improve the storage efficiency of data stored in ...ORC Adopters · Types · Indexes · ACID supportMissing: history | Show results with:history
  3. [3]
  4. [4]
    ORC becomes an Apache Top Level Project
    Apr 22, 2015 · Back in January 2013, we created ORC files as part of the initiative to massively speed up Apache Hive and improve the storage efficiency of ...Missing: history origin
  5. [5]
    ORC Adopters
    With more than 300 PB of data, Facebook was an early adopter of ORC and quickly put it into production. LinkedInPermalink. LinkedIn uses the ORC file format ...
  6. [6]
    ORC Specification v1 - Apache ORC
    ORC uses type specific readers and writers that provide light weight compression techniques such as dictionary encoding, bit packing, delta encoding, and run ...
  7. [7]
    Scaling the Facebook data warehouse to 300 PB
    Apr 10, 2014 · On our tests, this makes selective queries on Facebook ORCFile run 3x faster than open source ORCFile. Facebook ORCFile is also faster than ...
  8. [8]
    ORC Specification - Apache ORC
    ORC Specification. There have been two released ORC file versions: ORC v0 was released in Hive 0.11. ORC v1 was released in Hive 0.12 and ORC 1.x.Missing: history major
  9. [9]
    ORC 1.0.0 Released - Apache ORC
    Jan 25, 2016 · The ORC team is excited to announce the release of ORC v1.0.0. This release contains the native C++ ORC reader and some tools.
  10. [10]
  11. [11]
  12. [12]
    ORC 2.0.0 Released
    Mar 8, 2024 · ORC-1597: Set bloom filter fpp to 1%; ORC-1600: Reduce getStaticMemoryManager sync block in OrcFile; ORC-1601: Reduce get HadoopShims sync block ...
  13. [13]
  14. [14]
    Releases - Apache ORC
    All releases: ; 2.1.0, 2025-01-09, archived, ORC-2.1.0 ; 2.0.6, 2025-07-07, stable, ORC-2.0.6.Missing: history major
  15. [15]
    Types - Apache ORC
    ORC provides a rich set of scalar and compound types: Integer, Floating point, String types, Binary blobs, Decimal type, Date/time, Compound types.
  16. [16]
    SchemaEvolution (ORC Core 2.2.1 API)
    Package org.apache.orc.impl. Class SchemaEvolution. java.lang.Object. org.apache.orc.impl.SchemaEvolution. public class SchemaEvolution extends Object. Infer ...
  17. [17]
    [#ORC-789] Supporting schema evolution for union expansion - Issues
    Jul 13, 2022 · We are seeing the following schema evolution occurred from time to time while ORC library doesn't seem to support that: Error: org.apache.orc.
  18. [18]
    ORC Java configuration
    orc.tolerate.missing.schema, true, Writers earlier than HIVE-4243 may have inaccurate schema metadata. This setting will enable best effort schema evolution ...
  19. [19]
    Hive Configuration - Apache ORC
    Use zerocopy reads with ORC. (This requires Hadoop 2.3 or later.) hive.merge.orcfile.stripe.level, true, When hive.merge.mapfiles, ...Missing: optimization | Show results with:optimization
  20. [20]
    Indexes - Apache ORC
    ORC provides three level of indexes within each file. The file and stripe level column statistics are in the file footer so that they are easy to access.
  21. [21]
    ACID support - Apache ORC
    Although we support ACID transactions, they are not designed to support OLTP requirements. It can support millions of rows updated per a transaction, but it ...
  22. [22]
    Hive Transactions - Apache Hive - Apache Software Foundation
    ### Summary of Hive ACID Transactions with ORC
  23. [23]
    Releases - Apache ORC
    ORC-1.1.1. 1.1.0, 2016-06-10, archived, ORC-1.1.0. 1.0.0, 2016-01-25, archived, ORC-1.0.0. Overview. Background · ORC Adopters · Types · Indexes · ACID support ...Missing: history | Show results with:history
  24. [24]
    DataMask (ORC Core 2.2.1 API)
    The API for masking data during column encryption for ORC. They apply to an individual column (via ColumnVector) instead of a VectorRowBatch.Missing: documentation | Show results with:documentation
  25. [25]
    AdminManual Configuration - Apache Hive
    Dec 12, 2024 · hive.default.fileformat, Default file format for CREATE TABLE statement. Options are TextFile, SequenceFile, RCFile, and Orc. TextFile. hive ...Table Of Contents · Configuring Hive · Hive Configuration Variables
  26. [26]
    LanguageManual DDL - Apache Hive
    Dec 12, 2024 · A table that supports operations with ACID semantics. See this for more details about transactional tables. Example: CREATE TRANSACTIONAL TABLE ...
  27. [27]
    ORC file format | Cloudera on Cloud
    ORC is the default storage for Hive data. The ORC file format for Hive data storage is recommended for the following reasons:
  28. [28]
    Hive Transactions - Apache Hive
    Dec 12, 2024 · Only ORC file format is supported in this first release. The feature has been built such that transactions can be used by any storage format ...
  29. [29]
    ORC Files - Spark 4.0.1 Documentation
    Apache ORC is a columnar format which has more advanced features like native zstd compression, bloom filter and columnar encryption.<|control11|><|separator|>
  30. [30]
    Spark Release 2.3.0
    Vectorized ORC Reader: [SPARK-16060] Adds support for new ORC reader that substantially improves the ORC scan throughput through vectorization (2-5x). To ...
  31. [31]
    Hive connector — Trino 478 Documentation
    ### ORC Support in Trino/Hive Connector
  32. [32]
    ORC bloom filters in Trino - Home
    Mar 3, 2022 · Bloom filters are used in ORC files to help increase the effectiveness of predicate pushdown by allowing Trino to skip a stripe.Missing: Apache | Show results with:Apache
  33. [33]
    Reading and Writing the Apache ORC Format
    The Apache ORC project provides a standardized open-source columnar storage format for use in data analysis systems. It was created originally for use in Apache ...
  34. [34]
    Using Core Java - Apache ORC
    To read ORC files, use the OrcFile class to create a Reader that contains the metadata about the file. There are a few options to the ORC reader, but far fewer ...Missing: native | Show results with:native
  35. [35]
    Java Tools - Apache ORC
    The check command can check whether the specified value of the column specified by multiple ORC files can be filtered. Check statistics and bloom filter index ...
  36. [36]
    Hive table compression: bz2 vs Text vs Orc vs Parquet
    Jan 16, 2019 · CSV (Text), 657.5 Mb, -. ORC, 93.5 Mb, 14.2%. Parquet, 146.6 Mb, 22.3%. One should keep in mind that default settings and values were used to ...
  37. [37]
    Hive and Apache Tez: Benchmarked at Yahoo! Scale - Slideshare
    This document discusses benchmarking Hive at Yahoo scale. Some key points: - Hive is the fastest growing product on Yahoo's Hadoop clusters which process ...
  38. [38]
    Extended Predicate Pushdown in Spark with Apache ORC - Medium
    May 24, 2022 · Default ORC predicate push down will read the whole data from disk, The New EPPD approach will only read only 0-3% of the whole data. It saves ...
  39. [39]
    The impact of columnar file formats on SQL‐on‐hadoop engine ...
    Sep 9, 2019 · We show that ORC generally performs better on Hive, whereas Parquet achieves best performance with SparkSQL. Using ZLIB compression brings up to 60.2% ...
  40. [40]
    Using Vectorized Query Execution - Apache
    Oct 30, 2013 · Vectorized query execution is a Hive feature that greatly reduces the CPU usage for typical query operations like scans, filters, aggregates, and joins.
  41. [41]
    Optimize Apache Hive with Apache Ambari in Azure HDInsight
    Sep 6, 2024 · Vectorization directs Hive to process data in blocks of 1,024 rows rather than one row at a time. Vectorization is only applicable to the ORC ...
  42. [42]
    How Facebook Compresses Its 300 PB Data Warehouse - AIwire
    Apr 11, 2014 · As you can see, on this dataset, HortonWorks was getting about a 4.5X compression ratio on the ORCFile embedded in Hive 12 compared to plain ...Missing: ORC | Show results with:ORC<|control11|><|separator|>
  43. [43]
    AliORC: A Combination of MaxCompute and Apache ORC
    Sep 18, 2019 · After two versions of iteration, ORC was incubated into a top-level Apache project, and successfully separated from Hive to become a separate ...
  44. [44]
    Build a high-performance, ACID compliant, evolving data lake using ...
    Jun 27, 2022 · Build a high-performance, ACID compliant, evolving data lake using Apache Iceberg on Amazon EMR ... Use org.apache.iceberg.aws.s3.S3FileIO as the ...Modern Data Lake Challenges · Using Apache Iceberg With... · Configure A Spark Session<|control11|><|separator|>