Iceberg answers "what is the table right now" with a small tree of metadata, not by listing the object store. A query plans by walking this tree and comparing stats — it never opens a data file it can rule out first.
The tree below is the whole table as Iceberg sees it: metadata pointer → snapshot → manifest list → manifests → data files. Each data file shows a fake min/max for its date column.
Query plans against the current snapshot only. Files whose min/max range cannot contain the filter value are skipped without being opened.
Raw Parquet on an object store has no "what is the table right now" — only a prefix you'd have to LIST, which gets slower and more expensive as file counts grow (see Object Storage Internals). Iceberg's metadata tree — metadata file → snapshot → manifest list → manifests → data files — is the table. Planning a query means walking a small tree of Avro/JSON files with embedded stats, never listing the bucket. See Apache Iceberg for the full hierarchy and why this is one of the reasons table formats exist over raw files.
expire_snapshots removes them, which is what makes time travel possible.