Build the mental model
To index a single document, use `PUT /index/_doc/id` (you choose the ID) or `POST /index/_doc` (Elasticsearch auto-generates an ID) — reusing the same ID with `PUT` replaces (updates) that document, while `POST` creates a new document per request. Each single-document request is one network round trip, and indexing hundreds of documents that way is slow because of round-trip overhead. The `_bulk` API solves this by packing multiple index, update, and delete operations into one HTTP request using NDJSON (newline-delimited JSON) format, processing thousands of documents in a single round trip. The bulk request format is a sequence of line pairs: an action/metadata line (which operation, which index, which ID) followed immediately by a document data line — a malformed pair can fail the whole request. Even when the overall bulk request returns HTTP 200, individual items inside it can still fail, so you must always check the response's `errors` field and each item's status. This is like handing a stack of packages to the post office in one trip: getting an overall shipment confirmation does not mean every single package had a correct address.
Connect it to a real scenario
When first syncing the Tutorial Platform's PostgreSQL `tutorials` table into Elasticsearch, indexing 5,000 tutorials with one `POST` per document would take hundreds of seconds from round-trip overhead alone — instead, use the `_bulk` API in chunks (say 500 documents per request). When a bulk response reports `errors: true`, log which items failed and retry only those, without re-processing the ones that already succeeded. For a single-document update (an author editing one tutorial), use `PUT /tutorials/_doc/<postgresql-id>` so the ID matches — reusing the PostgreSQL row ID as the Elasticsearch document ID keeps the sync logic simple.
Try the working example
PUT /tutorials/_doc/42
{
"title": "Redis Basics",
"tags": ["redis", "cache"],
"publishedAt": "2026-08-01"
}
POST /_bulk
{ "index": { "_index": "tutorials", "_id": "43" } }
{ "title": "GraphQL Basics", "tags": ["graphql", "api"], "publishedAt": "2026-08-15" }
{ "index": { "_index": "tutorials", "_id": "44" } }
{ "title": "Elasticsearch Basics", "tags": ["elasticsearch", "search"], "publishedAt": "2026-08-29" }You can index a single document and index two more documents at once with a `_bulk` request.5-minute try-it
Write a single `_bulk` request that indexes three tutorials (id 100, 101, 102) — intentionally malform document 101's line (missing closing brace) and predict how the response reports it.
One important caution
Sending many documents through a loop of single-document `PUT`/`POST` requests — round-trip overhead can badly degrade performance.
Assuming an HTTP 200 on the bulk request means every document succeeded, without checking the response body's `errors` field and item-level statuses.
Elasticsearch Guide — Bulk API — Elastic