Hi All,
If you run streaming or continuous pipelines that commit to Delta tables on S3 every few minutes, your _delta_log folders are probably much bigger than your tables. A CDC or MERGE flow commits every cycle whether or not data arrived, and with the default 30 day log retention that adds up fast. A table committing every two minutes carries roughly 20,000 log files. We learned this when our S3 bill doubled in a month with storage flat, nearly all of it Tier-1 request charges against _delta_log prefixes.
The expensive part is the read path. S3 LIST returns 1,000 keys per call, so a version lookup against a 16,000 file log folder takes about 16 calls, and every streaming cycle does those lookups. Commit rate drives both how often you look up and how many pages each lookup costs, so request spend grows with the square of the commit rate. Speed a pipeline up 5x and this line of the bill goes up about 25x.
Commit files are named by version, the reader knows the last checkpoint, and S3 ListObjectsV2 has a start-after parameter, so one page should be enough. Open source Delta fixed exactly this in 2022 (issue #1191, shipped in Delta 2.3.0 as delta.enableFastS3AListFrom). But that flag is implemented inside the S3A filesystem, and the Databricks runtime uses its own S3 client, so as far as I can tell it does nothing there.
The platform answer seems to be catalog-managed commits, which skip the listing entirely, but streaming tables need Public Preview enrollment and materialized views are not supported yet.
So, for those running high commit rate tables on Databricks and S3:
- Have you found any runtime or table configuration that makes _delta_log listing start at the checkpoint instead of paging the whole folder?
- Has anyone been through the catalog-managed commits preview with streaming tables, and did it help with request costs?
- Or is the current answer just triggered schedules, slower cadence, and a shorter delta.logRetentionDuration?
For us the workarounds cut the cost fine, but they trade freshness for money, and that tradeoff should not have to exist when the object store supports the precise lookup. If there is a knob I have missed I would like to know about it.