Data lake storage: formats and layout
CSV, JSON, Avro, ORC and Parquet compared, compression, and how to lay out folders in a data lake.
On this page
You will learn
- How CSV, JSON, Avro, ORC and Parquet differ, and when each fits
- Why columnar formats are faster for analytics
- How compression codecs trade CPU for size
- How to lay out folders and zones in a data lake
What a data lake is
A data lake stores data as files in cheap object storage (Amazon S3, Azure Data Lake Storage, Google Cloud Storage) and lets many engines read it: Spark, Trino, Flink, DuckDB, warehouses. Storage is separated from compute, so you pay for compute only while queries run. The price is that the lake has no database to enforce anything: formats, layout and conventions do that job, and table formats like Delta and Iceberg add transactions on top.
The formats compared
| Format | Layout | Schema | Splittable | Best for |
|---|---|---|---|---|
| CSV | Row, text | None (all strings) | Yes, if uncompressed or with a splittable codec | Exchange with humans and legacy systems |
| JSON (Lines) | Row, text | Self-describing per record | Yes for JSON Lines | APIs, logs, nested data on landing |
| Avro | Row, binary | Embedded, with evolution rules | Yes | Kafka messages, write-heavy pipelines, schema evolution |
| ORC | Columnar, binary | Embedded | Yes | Analytics in Hive-era stacks |
| ParquetParquet: A columnar file format: values of each column are stored together, so queries read only the columns they need. Learn more → | Columnar, binary | Embedded | Yes | Analytics; the default under Delta, Iceberg and Hudi |
Why columnar wins for analytics
Input
| Row layout (CSV, Avro) |
|---|
| 1, Pune, 250 |
| 2, Delhi, 900 |
| 3, Pune, 120 |
Output
| Columnar layout (Parquet, ORC) |
|---|
| id: 1, 2, 3 |
| city: Pune, Delhi, Pune |
| amount: 250, 900, 120 |
The same three rows, two layouts
- Column pruningcolumn pruning: Reading only the columns a query uses, which columnar files like Parquet make possible. Learn more →:
SELECT sum(amount)reads one column out of fifty, not all of them. - Better compression: similar values sit together, so dictionary and run-length encoding shrink them a lot (a city column with 100 distinct values compresses to almost nothing).
- Skipping: each row grouprow group: A block of rows inside a Parquet file. Its min and max statistics let readers skip blocks that cannot match a filter. Learn more → stores min/max statistics per column, so
WHERE amount > 1000skips row groups whose max is lower. - The cost: writing is heavier, and reading one whole record touches every column chunk. That is why landing and streaming often use row formats.
Compression codecs
| Codec | Size | Speed | Typical use |
|---|---|---|---|
| Snappy | Good | Very fast | Spark's Parquet default |
| ZSTD | Better | Fast | Increasingly the default for Parquet and Iceberg; a good general choice |
| GZIP | Better | Slow | Archives; avoid on CSV, because a .gz file cannot be split, so one tasktask: The work for one partition in one stage, run on one CPU core. Learn more → reads it all |
| LZ4 | Good | Fastest | Hot data, shuffleshuffle: Moving rows between machines so that all rows with the same key end up together. Needed by joins, groupBy and sorting, and usually the most expensive step of a job. Learn more → files |
Inside Parquet, compression applies per column chunk, so every codec is splittable there. Outside Parquet, a single 10 GB .csv.gz file is read by one task, which is a common reason a job has one task running for an hour.
Zones: raw to curated
-
Raw / landing
Exactly as received: CSV, JSON, Avro. Append-only, never edited, kept for replay and audit.
-
Cleaned / bronze-silver
Parsed, typed, de-duplicated, in Parquet or a table format.
-
Curated / gold
Modelled for consumers: facts, dimensions, aggregates.
This is the same idea as the medallion architecture. Keeping the raw zone means any bug downstream can be fixed by reprocessing from the original files.
Folder layout
A typical layout
s3://acme-lake/ raw/orders/ingest_date=2025-03-01/part-0000.json.gz silver/orders/order_date=2025-03-01/part-00000.zstd.parquet gold/daily_revenue/...
- Hive-style folders (
column=value) let engines prune partitions from the path. - Partition by a low-cardinalitycardinality: How many distinct values a column has. User ids are high cardinality; country codes are low. Learn more → column that queries filter on, usually a date. Partitions should hold at least about 1 GB.
- Aim for files of 128 MB to 1 GB.
- Separate buckets or prefixes per zone make access control simple: few people can write to raw, many can read gold.
- Never rely on listing folders to know what a table contains: concurrent writers make that unsafe. That is the problem table formats solve with a transaction logtransaction log: The ordered list of commits that defines which files make up a Delta table at each version. Learn more →.
Common mistakes
Analytics on CSV or JSON
Large gzip CSV files
Partitioning by a high-cardinality column
No raw zone
Key takeaways
- Row formats suit landing and exchange; columnar formats suit analytics.
- Parquet gives column pruning, compression and row-group skipping.
- Avoid big gzip text files: they cannot be split.
- Use zones, date partitions and large files; add a table format for transactions.
Check yourself
3 questions1. A query sums one column of a 50-column table. Which format reads the least data?
Show the answer
Parquet. Columnar formats read only the needed column.
2. Why is a 10 GB .csv.gz file slow to read in Spark?
Show the answer
gzip is not splittable, so one task reads the whole file. Without split points, one task must decompress from the start.
3. What is the raw zone for?
Show the answer
Keeping data exactly as received so it can be reprocessed. It is the replayable source of truth.
Practice it
Interview problems that use this: write the PySpark, run it, and get graded on hidden tests.
Keep going
Up next · lesson 3 of 26 · 4 min readParquet and columnar storage
Row groups, column chunks and statistics: why columnar files let engines skip most of the data.
Related lessons
Partitioning done rightData lake & lakehouse · 3 min read
The medallion architecture
Previous: Lake, warehouse, lakehouse
Primary sources: Apache Parquet · Apache Avro · Spark data sources