> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ocient.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Storage Optimization

> Reduce storage footprint in an Ocient System using table-level compression, system-level configuration, and data lifecycle management techniques.

export const TimeKey = "TimeKey®";

export const Ocient = "Ocient®";

The {Ocient} System provides several tools and techniques to reduce the storage footprint of your data while maintaining query performance and fault tolerance. This page organizes these techniques into three categories: optimizations you apply when designing tables, optimizations you configure at the system or storage-cluster level, and ongoing practices for managing data lifecycle and storage efficiency over time.

## Table-Level Storage Optimizations

Careful schema design at table creation time yields the largest storage savings. Use these techniques when defining tables:

* Apply column compression — Choose a compression scheme for each column based on its data type and cardinality to reduce on-disk size. The system supports ZSTD compression for strong general-purpose compression, Global Dictionary Compression (GDC) for low-cardinality variable-length columns, and dynamic compression (the default) for automatic lightweight encoding with no configuration required. You can stack GDC and ZSTD for additional savings. For details, see [Table Compression Options](/table-compression-options) and [Global Dictionary Compression](/global-dictionary-compression).
* Use appropriate data types — Select the narrowest data type that fits your data. For example, use `SMALLINT` or `INT` types instead of `BIGINT` when the value range allows. For columns with low cardinality, consider GDC to convert variable-length values to fixed-width integers.
* Leverage complex types to avoid extra tables — Use arrays, tuples, and arrays of tuples to denormalize one-to-many relationships into a single column instead of creating separate child tables. This denormalization eliminates the storage overhead of duplicated foreign keys and additional indexes. For details, see [Array, Tuple, and Matrix Overview](/array-tuple-and-matrix-overview).
* Index selectively — Secondary indexes improve query performance but consume additional storage. Create indexes only on columns that appear frequently in query predicates. Avoid redundant indexes on columns that are already covered by the clustering key or a clustering index. For details about the different index types available and when to use each one, see [Secondary Indexes](/secondary-indexes).
* Configure the redundancy mode — When creating a table, you can choose between `COPY` and `PARITY` redundancy for each segment part. `PARITY` redundancy uses erasure coding, which consumes less storage than full replication (`COPY`) but incurs additional CPU overhead during rebuilds or degraded-state queries. For details, see the `REDUNDANCY` parameter in [Tables](/tables).

## System-Level Storage Configuration

Configure the storage cluster and storage spaces to balance fault tolerance against storage overhead and minimize parity overhead. The system spreads data evenly across all nodes to maximize parallelism and use all available capacity. When a table uses `PARITY` redundancy, the system calculates the storage overhead of erasure coding as `PARITY_WIDTH / (WIDTH - PARITY_WIDTH)`. You can minimize this overhead by keeping `PARITY_WIDTH` as small as your fault-tolerance requirements allow and setting `WIDTH` as large as possible. For example, a 10-node segment group with `PARITY_WIDTH = 2` incurs 25% parity overhead, while `PARITY_WIDTH = 3` on the same width incurs approximately 43% overhead. Any nodes beyond the segment group width are overprovisioned, providing fault tolerance for load operations. You cannot change storage space configurations after creation, so evaluate your needs carefully before creating one. For configuration examples, see [Configure Storage Spaces](/configure-storage-spaces).

## Data Lifecycle and Ongoing Storage Management

Use these practices to control storage growth and reclaim space over time:

* Table retention policies — Automatically remove aged data by configuring the `RETENTION POLICY` on tables with a {TimeKey} column. The system periodically evaluates each row against the retention period and deletes rows that exceed it. This approach is ideal for time series and streaming workloads where historical data has diminishing value. For details, see [Table Retention Policies](/table-retention-policies).
* `TRUNCATE TABLE` SQL statement for space reclamation — When removing large volumes of data, use the `TRUNCATE TABLE` SQL statement instead of the `DELETE` statement. Both operations reclaim disk space, but the `DELETE` statement can reclaim storage only for segment groups in which all rows have been removed. The `TRUNCATE TABLE` statement removes all rows from the table and reclaims all associated storage. For details, see [Remove Records from an Ocient System](/remove-records-from-an-ocient-system).
* Removal of unused indexes — Periodically audit secondary indexes using the system catalog. Dropping an index prevents it from being created in future segments, reducing storage growth over time. Use the `DROP INDEX` SQL statement to remove unneeded indexes. For details, see [Secondary Indexes](/secondary-indexes).
* Monitoring of storage utilization — Use the `sys.storage_used` system catalog table to inspect per-node, per-table storage consumption. Identifying the largest tables and their compression ratios reveals opportunities for further optimization. For details, see [System Catalog](/system-catalog).

## Related Links

[Table Compression Options](/table-compression-options)

[Global Dictionary Compression](/global-dictionary-compression)

[Configure Storage Spaces](/configure-storage-spaces)

[Table Retention Policies](/table-retention-policies)

[Tables](/tables)
