> ## Documentation Index
> Fetch the complete documentation index at: https://algolia.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Sending records in batches

> Learn how to send record updates to Algolia for faster indexing and less network calls.

export const Records = () => <Tooltip tip="A record is a searchable object in an Algolia index. Each record consists of named attributes." cta="Algolia records" href="/doc/guides/sending-and-managing-data/prepare-your-data#algolia-records">
    records
  </Tooltip>;

export const Application = () => <Tooltip tip="An Algolia application is a self-contained environment with its own indices, configuration, and API keys. Applications don't share data or settings with each other.">
    application
  </Tooltip>;

export const AlgoliaSearch = () => <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 80 80" width="20" height="20" className="inline" fill="none" role="presentation" ariaLabel="Algolia Search">
    <circle cx="40" cy="32" r="28" fill="#5468FF"></circle>
    <rect x="30" y="22" width="20" height="20" rx="10" fill="#fff"></rect>
    <path d="M43 63.5 54.5 60l6 17h-12L43 63.5Z" fill="#36395A"></path>
  </svg>;

When [sending data to Algolia](/doc/guides/sending-and-managing-data/send-and-update-your-data),
it's best to send several <Records /> simultaneously instead of individually.
It reduces network calls and speeds up indexing,
especially when you have a lot of records,
but everyone should send indexing operations in batches whenever possible.

For example, you might decide to send all the data from your database and end up with a million records to index.
That's too big to send all at once because Algolia limits you to 1 GB per batch per request.
In reality, sending that much data in a single network call would fail before reaching the API.
You could loop over each record and send them with the [`saveObjects`](/doc/libraries/sdk/v1/methods/save-objects) method.
The problem is that **you would perform a million individual network calls**,
which would take way too long and saturate your Algolia cluster with indexing jobs.

A better approach is to **split your collection of records into smaller collections, then send each chunk one by one.**
For optimal indexing performance, aim for a batch size of about 10 MB,
representing between 1,000 and 10,000 records, depending on the average record size.

* **Batching records doesn't reduce your operations count.** [Algolia counts indexing operations per record](https://support.algolia.com/hc/en-us/articles/18138875086865), not per method call, so from a pricing perspective, batching records is the same as indexing records individually.
* **Be careful when approaching your plan's [maximum number of records](https://www.algolia.com/pricing/).** If you're close to the record limit,
  batch operations may fail. The error message
  "You have exceeded your Record quota" means the engine doesn't know if the batch operation will update records or add new ones.
  If this happens, upgrade to a plan with a higher record limit or reduce your batch size.

## Using the API

To run the code examples on this page, [install the latest API client](/doc/libraries/sdk/install).

When using the [`saveObjects`](/doc/libraries/sdk/v1/methods/save-objects) method,
the API clients automatically chunk your records into batches of 1,000.

With this approach, you would make 100 API calls instead of 1,000,000.
Depending on your records' sizes and your network speed, you could create bigger or smaller chunks.

<CodeGroup>
  ```cs C# theme={"system"}
  var response = await client.SaveObjectsAsync(
    "INDEX_NAME",
    new List<Object>
    {
      new Dictionary<string, string> { { "objectID", "1" }, { "name", "Adam" } },
      new Dictionary<string, string> { { "objectID", "2" }, { "name", "Benoit" } },
    }
  );
  ```

  ```go Go theme={"system"}
  response, err := client.SaveObjects(
    "INDEX_NAME",
    []map[string]any{{"objectID": "1", "name": "Adam"}, {"objectID": "2", "name": "Benoit"}})
  if err != nil {
    // handle the eventual error
    panic(err)
  }
  ```

  ```java Java theme={"system"}
  List response = client.saveObjects(
    "INDEX_NAME",
    Arrays.asList(
      new HashMap() {
        {
          put("objectID", "1");
          put("name", "Adam");
        }
      },
      new HashMap() {
        {
          put("objectID", "2");
          put("name", "Benoit");
        }
      }
    )
  );
  ```

  ```js JavaScript theme={"system"}
  const response = await client.saveObjects({
    indexName: 'cts_e2e_saveObjects_javascript',
    objects: [
      { objectID: '1', name: 'Adam' },
      { objectID: '2', name: 'Benoit' },
    ],
  });
  ```

  ```kotlin Kotlin theme={"system"}
  var response =
    client.saveObjects(
      indexName = "INDEX_NAME",
      objects =
        listOf(
          buildJsonObject {
            put("objectID", JsonPrimitive("1"))
            put("name", JsonPrimitive("Adam"))
          },
          buildJsonObject {
            put("objectID", JsonPrimitive("2"))
            put("name", JsonPrimitive("Benoit"))
          },
        ),
    )
  ```

  ```php PHP theme={"system"}
  $response = $client->saveObjects(
      'INDEX_NAME',
      [
          ['objectID' => '1',
              'name' => 'Adam',
          ],

          ['objectID' => '2',
              'name' => 'Benoit',
          ],
      ],
  );
  ```

  ```python Python theme={"system"}
  response = client.save_objects(
      index_name="INDEX_NAME",
      objects=[
          {
              "objectID": "1",
              "name": "Adam",
          },
          {
              "objectID": "2",
              "name": "Benoit",
          },
      ],
  )
  ```

  ```ruby Ruby theme={"system"}
  response = client.save_objects(
    "INDEX_NAME",
    [{objectID: "1", name: "Adam"}, {objectID: "2", name: "Benoit"}]
  )
  ```

  ```scala Scala theme={"system"}
  val response = Await.result(
    client.saveObjects(
      indexName = "INDEX_NAME",
      objects = Seq(
        JObject(List(JField("objectID", JString("1")), JField("name", JString("Adam")))),
        JObject(List(JField("objectID", JString("2")), JField("name", JString("Benoit"))))
      )
    ),
    Duration(100, "sec")
  )
  ```

  ```swift Swift theme={"system"}
  let response = try await client.saveObjects(
      indexName: "INDEX_NAME",
      objects: [["objectID": "1", "name": "Adam"], ["objectID": "2", "name": "Benoit"]]
  )
  ```
</CodeGroup>

For more information, see:

* [Large indexing jobs](/doc/guides/scaling/scaling-to-larger-datasets)
* [Import with the API](/doc/guides/sending-and-managing-data/send-and-update-your-data/how-to/importing-with-the-api)

## Using the dashboard

You can also send your records in your Algolia dashboard.

### Add records manually

1. Go to the [Algolia dashboard](https://dashboard.algolia.com/explorer/browse) and select your Algolia <Application />.
2. On the left sidebar, select <AlgoliaSearch /> **Search**.
3. Select your Algolia index.
4. Open the **Add records** menu and select **Add manually**.
5. Paste your records in the JSON editor and click **Save**.

### Upload a file

1. Go to your dashboard and select your index.
2. Click the **Add records** tab and select **Upload file**.
3. Select the file you want to upload and click **Upload**.

For more information, see [Import from the dashboard](/doc/guides/sending-and-managing-data/send-and-update-your-data/how-to/importing-from-the-dashboard).
