Bulk writes implementation recommendations
Last updated: April 1, 2026
Overview
This article walks through how Merge’s bulk writes work across different third-party integrations. This article will cover:
Runtime behavior by integration
Rate limit behavior and suggested concurrency per integration
General best practices & FAQs when using the endpoint
We suggest reading the below guide that provides an overview of Merge bulk writes functionality, complete with sample payloads.
Runtime behavior
Bulk write performance is largely influenced by how each third-party system's API is designed. Below are several factors that explain how NetSuite, QuickBooks Online, and Xero can affect overall runtime performance.
NetSuite
When you make a request to Merge's bulk write endpoint, behind the scenes Merge utilizes NetSuite addList SOAP action. This action supports a maximum of 100 objects per request, meaning each request to Merge is a single request to NetSuite.
Through extensive testing, we observed an average runtime of 7 minutes per 100-object bulk write request.
Bulk writes in a NetSuite sandbox may take longer than expected. Sandbox environments have fewer resources, which can extend response times and increase runtimes to up to 10 minutes. For faster performance, use a production NetSuite account.
Currently supported Netsuite objects:
Invoices
Sales Orders
Item Fulfillments
Expenses (Checks)
Netsuite currently doesn't support batch POST'ing CreditCardCharges/CreditCardRefunds
QuickBooks Online
Merge utilizes the /batch endpoint to make bulk write requests. The /batch endpoint supports a maximum of 30 objects per batch request, meaning a request to create 100 objects results in 4 separate requests to QuickBooks Online's API.
Through extensive testing, we observed an average runtime of 16 minutes per 100-object bulk write request, with responses from QuickBooks Online (QBO) taking up to 3 minutes.
Currently supported Quickbooks Online objects:
Invoices
Expenses
Xero
Xero's normal POST endpoints actually support writing more than one object at a time! For example, the /BankTransactions endpoint that Merge uses to create Expenses supports an array of objects in addition to just one object. All Xero's POST endpoints support a max of 30 objects per batch request, meaning a request to create 100 objects results in 4 separate requests to Xero's API.
Through extensive testing, we observed an average runtime of 2 minutes per 100-object bulk write request.
Currently supported Xero objects:
Expenses
Sage Intacct
Sage Intacct supports batching multiple create operations within a single request; however, each object in the batch is still processed as an individual operation.
Sage Intacct enforces a maximum request processing time of approximately 15 minutes. To reduce the risk of timeouts and improve reliability, Merge splits larger batches (e.g., 100 objects) into smaller batches of 50 objects per request.
Additionally, Sage Intacct enforces tenant-level concurrency limits. Sending a high volume of requests in parallel does not guarantee faster throughput—excess requests may be queued and processed in a first-in, first-out (FIFO) order.
Bulk writes in a Sage Intacct sandbox environment may take longer than expected due to reduced system resources and stricter performance constraints. For optimal performance, use a production Sage Intacct account when possible.
Entity-level constraints: Sage Intacct does not support batching transactions across multiple entities (also referred to as locations or levels). All transactions within a single batch request must belong to the same entity. To post transactions across different entities, you must send separate batch requests for each entity, using the corresponding account ID in Merge.
Currently supported Sage Intacct objects:
Expenses
Rate limits & concurrency
Our bulk writes feature let you create multiple records in third-party systems in a single request. There are limits to how many records you can create in a single request, though - you can't just POST 10,000 objects in one request.
So, how can you POST 10,000 objects efficiently? Chunking - you break up that 10,000 into different chunks, and process those chunks concurrently. Then the question becomes: how many chunks should you break them up into? The answer will depend on third-party rate limits, so we've outlined what to expect for each integration below.
You'll notice our recommendations below are less the overall limit for each integration. We suggest leaving room for any other requests that may be occurring outside of your bulk write requests (data retrieval syncs, passthrough requests, etc).
NetSuite
NetSuite's rate limit is strictly concurrency-based. The tricky part is that it's dependent on the NetSuite instance: some may have a 15 request limit, while some may have a 3 request limit. Exceeding the limit at any point results in an error.
Our recommendation: 2-3 concurrent requests/processes
Due to the nature of NetSuite's rate limit, this is not foolproof. You may still see rate limits even with a 2 concurrent request limit.
QuickBooks Online
QuickBooks Online's rate limits are outlined below (see their full documentation here).
10 concurrent requests per instance, per app
40 requests per minute per instance, per app on the
/v3/company/{realmID}/batchendpoint120 requests per minute per instance on the
/v3/company/{realmID}/batchendpoint
Our recommendation: 4 concurrent requests/processes
Xero
Xero's rate limits are outlined below (see their full documentation here).
5 concurrent requests per instance, per app
60 requests per minute per instance, per app
5,000 requests per day per instance, per app
Our recommendation: 2 concurrent requests/processes
General best practices & FAQs
Why does a bulk write request take minutes to process?
Bulk writes requests can take a while to process for a few reasons:
Merge may be making multiple requests to the third party. For example, Merge makes 4 different requests to QuickBooks Online for a 100 object bulk write request.
The third-party APIs process each object synchronously. Not only does each object need to be inserted, each object also needs to be validated. A single request to the third party can take minutes to process.
Third party rate limits may cause merge to pause/queue during runtime.
What do the different statuses mean and how can I handle them?
See our main Bulk writes guide for a full list of statuses! The ones you'll probably be wondering about are listed below:
PARTIAL_SUCCESS- Some objects have been created successfully and some have failed. Failures are generally a validation error. Merge will give you the validation error in the/<common_model>/batch/<batch_id>/objectsresponse. You'll need to review each failed object and determine the resolution based on the error response.FAILED- Generally speaking this is an error on Merge's end. Please reach out to us if you encounter this!RATE_LIMITED- Merge has run up against the third party rate limit. We've paused the task and will pick back up again shortly. There is no action required on your end.
What is the item_id and what should I pass?
Merge requires an item_id for each object in a bulk write request because some third parties require it (see the bId in QuickBook Online's docs). The value just needs to be unique per bulk write request. What you decide to populate it with is up to you, but it is something you should be able to identify in case you need to review any failures. If you have a unique transaction identifier in your application, we suggest using it here!