Skip to content

Send _bulk actions in batches#184

Merged
matthinea merged 5 commits into
masterfrom
bulk-size-limit
Jun 4, 2026
Merged

Send _bulk actions in batches#184
matthinea merged 5 commits into
masterfrom
bulk-size-limit

Conversation

@matthinea

@matthinea matthinea commented Jun 4, 2026

Copy link
Copy Markdown
Contributor

Problem

It's deceptively easy to load hundreds of thousands of records into a single _bulk request. These can result in 413: Request too large exception, failing silently.

Solution

Batch _bulk requests and only send max 1000 records at a time.

instructions = { _index: index_name, _id: id, retry_on_conflict: 3 }
instructions[:routing] = routing if routing
batch << { delete: instructions }
batch << [{ delete: instructions }]

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

index_document and update_document bulk actions require 2 lines each, but delete bulk actions only require 1. By grouping them together as they're added, we can paginate them correctly at HTTP request time

expected_body = <<~DOC
{"index":{"_index":"widgets","_id":"5"}}
{"color":"green"}
{"delete":{"_index":"widgets","_id":"3","retry_on_conflict":3}}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here we can see that the single-action delete bulk is correctly grouped with the 2-line index action before it.

@j1wilmot j1wilmot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

slice_size = options.delete(:actions_per_bulk) || ACTIONS_PER_BULK

current_bulk_batch.each_slice(slice_size) do |actions|
body = actions.flatten.map { |action| "#{ActiveSupport::JSON.encode(action)}\n" }.join

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be nice to extract bulk post to a separate method so that slice behavior can be done optionally. Then method with slicing calls extracted method.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we'll want to always slice though, no? In any case, actions_per_bulk can be specified if different slice sizes are needed

@matthinea matthinea merged commit a1b8f53 into master Jun 4, 2026
1 check passed
@matthinea matthinea deleted the bulk-size-limit branch June 4, 2026 21:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants