You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
parallelize S3 uploads for .index and .kfs to shave off s3 round trip latency #109
When producing messages basically all the latency comes back to the sequential s3 uploads. Currently .kfs is uploaded to s3 first and only afterwards .index is uploaded. Total processing time is roughly segment_latency + index_latency.
Proposed solution
We can parallelize the s3 uploads to reduce the e2e latency to max(segment_latency, index_latency). This is effectively the same as segment_latency. I.e. we can eliminate a whole S3 round-trip in latency for the .index. For small segments / high throughput s3 connection where the s3 round trip time dominates the actual time to upload I'd estimate that this would shave off 30-45% in e2e produce latency.
Risks
Prior to this we only had to consider what happens if .kfs is uploaded but .index is missing because .kfs was uploaded first.
Now we also have to consider what happens if .index is uploaded but .kfs is missing if we upload in parallel.
The code paths filter out incomplete pairs where either .index or .kfs is missing. RestoreFromS3 fails if the .kfs file exists and .index is missing but that is an easily fixable, preexisting behavior. Parallel uploads introduce the chance that .index upload succeeds while .kfs upload fails which doesn't matter for RestoreFromS3.
Analysis of the code paths reading .kfs and .index files:
Reader
Reads .kfs?
Reads .index?
Handles missing .index?
Handles missing .kfs?
Orphan risk?
Broker: Read() pkg/storage/log.go:315
Yes, via DownloadSegment (lines 343, 354)
No — uses in-memory l.indexEntries populated at flush time (line 324)
Yes: segmentRangeForOffset() returns false (line 455), falls through to full segment download (lines 352-364). Slower but correct.
SQL Processor: time index builder sql-processor/internal/discovery/time_index_builder.go:105
Indirectly (calls Decode() at line 156)
Indirectly (calls Decode() at line 156)
Skips if SegmentKey == "" or IndexKey == "" (line 109), plus Decode() errors swallowed (lines 157-158)
Same skip logic (line 109)
None — double-protected
SQL Processor: time index reader sql-processor/internal/discovery/time_index.go:58
No — reads .kfst sidecars
No — reads .kfst sidecars
N/A — different file type
N/A — different file type
None
Next Steps
Please double check whether I overlooked something for my first contribution. If my analysis is correct I'd like to implement this. Should just be a few lines of code.
changed the title [-]parallel S3 uploads for .index and .kfs to shave off 30-45% e2e latency[/-][+]parallelize S3 uploads for .index and .kfs to shave off 30-45% e2e produce latency[/+]on Feb 24, 2026
changed the title [-]parallelize S3 uploads for .index and .kfs to shave off 30-45% e2e produce latency[/-][+]parallelize S3 uploads for .index and .kfs to shave off s3 round trip latency[/+]on Feb 24, 2026
HI @klaudworks - great idea to tackle that this way. I thought about that, but then also discovered that we might intensify S3 backpressure in high load scenarios, mainly in self-hosted S3 environments. Provider hosted ones should handle this.
Can we make this feature configurable, let's say admin enable parallelism, and we dynamically adapt depending on backpressure? Like no backpressure, more writes, backpressure raises, we reduce writes?
What would be also awesome to allow parallel reads for processors, like iceberg / SQL and KafClaw agents? Thoughts?
I think the clean solution for back pressure is to limit the combined throughput of all partitions e.g. via a shared semaphore. This could then be configured to optionally limit the load on s3. Feels wrong to hold back users on fast AWS S3 storage. In the meantime, a user can already limit their partitions to lighten the load on their s3. What do you think?
Regarding, parallel reads: Good point. This is an even bigger win than this PR. Didn't notice that a processor with N new segments has to perform 2*N sequential s3 roundtrips to download the .kfs and .index files. I'd be happy to implement that. Does that work for you?
I'd like to create 3 new issues afterwards. Then you can provide feedback on my proposals:
back pressure via shared semaphore
parallelize processor s3 reads
fix / improve RestoreFromS3(): even before this PR it would fail when .kfs was uploaded but .index was not and the whole restore would require manually resolving this in s3. I have a proposal in mind.
Activity
[-]parallel S3 uploads for .index and .kfs to shave off 30-45% e2e latency[/-][+]parallelize S3 uploads for .index and .kfs to shave off 30-45% e2e produce latency[/+]perf: parallelize S3 segment and index uploads in flushLocked
[-]parallelize S3 uploads for .index and .kfs to shave off 30-45% e2e produce latency[/-][+]parallelize S3 uploads for .index and .kfs to shave off s3 round trip latency[/+]novatechflow commentedon Feb 25, 2026
HI @klaudworks - great idea to tackle that this way. I thought about that, but then also discovered that we might intensify S3 backpressure in high load scenarios, mainly in self-hosted S3 environments. Provider hosted ones should handle this.
Can we make this feature configurable, let's say admin enable parallelism, and we dynamically adapt depending on backpressure? Like no backpressure, more writes, backpressure raises, we reduce writes?
What would be also awesome to allow parallel reads for processors, like iceberg / SQL and KafClaw agents? Thoughts?
klaudworks commentedon Feb 25, 2026
@novatechflow thanks for checking this out! 🙌
I think the clean solution for back pressure is to limit the combined throughput of all partitions e.g. via a shared semaphore. This could then be configured to optionally limit the load on s3. Feels wrong to hold back users on fast AWS S3 storage. In the meantime, a user can already limit their partitions to lighten the load on their s3. What do you think?
Regarding, parallel reads: Good point. This is an even bigger win than this PR. Didn't notice that a processor with N new segments has to perform 2*N sequential s3 roundtrips to download the .kfs and .index files. I'd be happy to implement that. Does that work for you?
klaudworks commentedon Feb 25, 2026
I'd like to create 3 new issues afterwards. Then you can provide feedback on my proposals:
novatechflow commentedon Feb 25, 2026
Yes let's do that :)
perf: parallelize S3 segment and index uploads (#110)
perf: parallelize S3 segment and index uploads in flushLocked