11. How would you partition data in S3 for query performance?
Choose an S3 layout using common predicates, event time, customer or marketplace keys, cardinality, late arrivals, and file size. Explain partition pruning, compaction, small-file control, skew, partition evolution, metadata registration, and avoidance of over-partitioning.
I would organize S3 around event date and add a low-to-moderate-cardinality key such as marketplace_id when it is a common predicate. I would keep customer_id as a column, compact small columnar files, register metadata in Glue, and let Athena prune irrelevant partitions.
Multiple producers can send transactional data, application logs, event streams, and partner data into the same reusable S3-based data platform. The recurring problem is that Athena should not scan unrelated objects for every query, while excessive partitioning creates metadata overhead and often many small files. I would therefore choose partition dimensions from common predicates, use event time as the main temporal boundary, and add marketplace_id only when its cardinality and distribution are manageable. The design prioritizes partition pruning, healthy columnar files, correct handling of late events, skew control, and explicit partition evolution when query patterns change.
- Which columns appear most often in Athena WHERE clauses: event time, marketplace, customer, or other dimensions?
- How late can events arrive, and are historical event-date partitions still queried while late records are being written?
- Is marketplace_id low or moderate cardinality, and can a small number of marketplaces contain most of the data?
- Is the current performance problem mainly excessive S3 scanning, too many small files, or slow partition-metadata lookup?
- How often do query patterns change enough that the physical partition scheme may need to evolve?
I would start from the filters used by the most important Athena queries. The diagram uses a Hive-style S3 layout such as s3://data-lake/events/marketplace_id=US/event_date=2024-01-01/part-0001.parquet.
Event time supplies the main temporal partition criterion. If marketplace_id is also commonly filtered and has manageable cardinality, I would use it as another partition dimension, as shown in the path. I would not partition by customer_id because its high cardinality could create a very large number of small partitions. customer_id remains a normal column in the Parquet or ORC files.
The trade-off is that additional useful partition dimensions can improve pruning, but unnecessary dimensions increase partition count, metadata work, and the risk of tiny files.
The design supports multiple producer types: transactional systems, application logs, event streams, and partner or third-party data. Records enter the ingestion and processing layer with fields such as event_time, marketplace_id, customer_id, and payload.
The processing layer parses and validates records, uses event_time to determine the correct event_date partition, and writes optimized columnar files. The diagram names Glue, EMR, or Amazon Managed Service for Apache Flink as possible processing choices. They are alternative processing technologies selected according to workload needs; the diagram does not imply that every record passes through all of them in sequence.
The exact organizational ownership model is not supplied, so I would not invent team boundaries. The visible responsibility boundary is clear: producers supply records, the shared processing path validates and writes them, and consumers query the published S3 data through Athena.
Amazon S3 stores the production records as partitioned Parquet or ORC objects. AWS Glue Data Catalog stores table and partition metadata. Production records do not flow through the catalog.
After partitioned data is written to S3, the table and partition metadata is registered or synchronized with Glue. Athena uses that metadata to locate the table and its partitions. This separation matters operationally because a healthy S3 object layout and correct catalog metadata are both needed for predictable querying.
For tables with large numbers of registered partitions, Glue partition indexes can reduce partition lookup work. Athena partition projection is another optional strategy for predictable partition layouts. With partition projection, Athena derives partition locations from configured rules rather than relying on registered partition entries for those projected partitions. These are metadata-management choices; they do not justify creating unnecessary physical partitions.
Consumers query the S3-backed table through Amazon Athena. Queries should include predicates on the relevant partition columns, such as marketplace_id and event_date.
Partition pruning means Athena can eliminate partitions that cannot satisfy the query predicate and read only matching S3 locations. That reduces unnecessary data scanning. Partitioning therefore helps most when query predicates align with the physical partition keys.
If a query does not filter on useful partition keys, the partition layout provides much less pruning benefit. That is why I would design partitions from common access patterns rather than from every column in the schema.
The processing layer writes Parquet or ORC. Columnar formats let analytical engines avoid reading unnecessary columns and provide efficient storage for analytical scans.
Partitioning by itself is not enough. A partition containing many tiny objects can still create significant planning and file-opening work. The Compaction & Maintenance path therefore merges small files into fewer, larger files.
The diagram intentionally does not prescribe one universal file-size target. I would choose file size from the workload and engine behavior instead of inventing a fixed threshold. The important design rule is to avoid both an excessive number of tiny objects and a partition layout so granular that every partition receives only a small amount of data.
Late events should be written to the partition representing their actual event date, not simply the date on which the processing system received them. That keeps the physical organization aligned with the event-time semantics used by queries.
A late event can add new small files to an older event_date partition that was already compacted. The maintenance path therefore re-compacts affected partitions when needed. The visible signals are new files, rising file counts, and changes in partition size after the normal write period.
If a late-data write fails, the retry boundary is the affected write or partition rather than unrelated partitions. After recovery, the records should be validated in the correct event_date location before the maintenance cycle is considered complete.
Cardinality and skew are different problems. Cardinality is the number of distinct partition values. Skew is an uneven distribution of data across those values.
A marketplace dimension may have acceptable cardinality but still be skewed if one marketplace receives much more data than the others. The result can be uneven file counts, larger partitions, and disproportionate query or maintenance work for the hot value.
I would observe relative partition sizes and file counts. If one marketplace becomes very hot, I would reconsider the layout based on actual query patterns. I would not automatically add customer_id as another partition key because that high-cardinality dimension could create a much worse over-partitioning problem.
The design deliberately keeps high-cardinality values such as customer_id out of the partition hierarchy. The physical layout should contain only dimensions that provide useful pruning while still producing healthy partition sizes.
Too many partitions create two related problems. First, each partition may contain too little data and therefore produce small files. Second, the metadata surface becomes larger, increasing partition-management and lookup work.
Before adding a partition dimension, I would ask whether it is frequently used in selective predicates, whether its cardinality is manageable, and whether its value distribution is balanced enough to create useful partitions.
The diagram shows a metadata and maintenance flow from the Compaction & Maintenance process to AWS Glue Data Catalog. When maintenance changes the physical files or partition locations in a way that affects registered metadata, the corresponding metadata must be updated.
S3 remains the production-data boundary and Glue remains the metadata boundary. A catalog update does not move or rewrite S3 data by itself. Likewise, rewriting S3 objects does not automatically mean every required catalog entry has been updated.
For projected partitions, Athena derives partition information from projection configuration instead of using registered partition entries in the same way. I would therefore choose one consistent metadata-management strategy for the table and operate it according to that strategy.
Partition design can change when access patterns change. The Partition Evolution path in the diagram says that new data can use the new scheme and that metadata and paths are migrated explicitly when the scheme changes.
I would not assume that modifying a Glue table definition reorganizes existing objects. Existing S3 data either remains under the old layout while consumers are kept compatible, or it is deliberately rewritten into the new layout and its metadata is updated.
The migration should be validated before the old path is retired. The trade-off is migration effort versus the ongoing scan, file, and metadata cost of keeping a layout that no longer matches query behavior.
Compaction rewrites file organization; it should not change the logical records or their partition meaning. If compaction fails, the affected partition is the recovery boundary.
The diagram does not specify a transactional table format or atomic file-replacement protocol, so I would not claim one. Operationally, the maintenance process must avoid treating an incomplete rewrite as successfully published. After retrying or rerunning compaction, I would verify that the intended files exist in S3 and that any required catalog metadata matches the final physical layout.
This keeps a maintenance failure from being confused with a change to business data semantics.
The reusable platform pattern in this diagram consists of multiple producers, shared ingestion and processing, partitioned Amazon S3 storage, AWS Glue Data Catalog metadata, Amazon Athena serving, and compaction and maintenance.
The diagram does not define a self-service provisioning portal, tenant isolation model, regional disaster-recovery design, security policy system, compliance boundary, or numerical service-level objective. I would not invent those capabilities in the interview. For this question, the important operating concerns are partition selection, pruning, file size, late data, skew, metadata registration, compaction, and partition evolution.
- Measure the common Athena predicates and choose partition dimensions from those access patterns.
- Use event_time to assign records to event_date.
- Add marketplace_id when it is commonly filtered and has manageable cardinality and distribution, matching the illustrated marketplace_id/event_date S3 layout.
- Keep high-cardinality fields such as customer_id inside the Parquet or ORC files rather than in the partition hierarchy.
- Parse and validate incoming records and write them to the correct S3 partition.
- Register or synchronize table and partition metadata in AWS Glue Data Catalog, unless the table intentionally uses Athena partition projection for projected partitions.
- Have Athena queries filter on partition columns so irrelevant partitions can be pruned.
- Observe file counts and partition sizes and compact small files into fewer, larger files.
- Write late events to their actual event_date partitions and re-compact affected partitions when necessary.
- Detect skew by comparing partition sizes and file counts instead of relying only on cardinality.
- Avoid adding high-cardinality partition keys simply to spread hot data.
- When query patterns change, introduce the new partition scheme deliberately and migrate affected S3 paths and metadata explicitly.
The main cost trade-off is between scanning too much data and managing too many partitions and files. Useful partitions let Athena skip unrelated S3 locations. Too many partitions can increase metadata work and often create tiny files. High-cardinality keys such as customer_id can multiply partition count quickly. Skew can make one marketplace much larger than the others even when marketplace cardinality is low. Compaction adds background compute and object rewrites but reduces the number of small files that queries must handle. Late arrivals add maintenance work because older event_date partitions can receive new files and may need re-compaction. Partition evolution also has migration cost because S3 paths and metadata may need to change together. No data volume, query concurrency, latency target, or file-size target is supplied, so I would measure those rather than invent numerical thresholds.
Interviewers want to see whether I can turn real query predicates into an effective physical S3 layout instead of partitioning by every available field. The key judgment is balancing partition pruning against partition count, file size, skew, late arrivals, metadata maintenance, and future partition evolution.
Common mistakes include partitioning by every available column, using customer_id as a partition key despite its high cardinality, choosing partition keys without examining actual query predicates, confusing cardinality with skew, using ingestion time when the design requires event-time partitions, ignoring late data that reopens old partitions, writing large numbers of tiny files, assuming Parquet or ORC alone solves the small-file problem, failing to maintain catalog metadata when physical partitions change, assuming a Glue metadata change automatically reorganizes S3 objects, and expecting effective partition pruning from queries that do not filter on the partition keys.
Start with the query predicates, not with S3 folder syntax. Explain why event time is the main temporal dimension, why marketplace_id is conditional, and why customer_id stays inside the file. Then connect pruning, small-file control, compaction, late arrivals, skew, metadata registration, and partition evolution to that choice.




