Skip to content

The Bank Teller and the 18-Wheeler

Module 1 of 8 in the chapter Moving Data at Scale, chapter 10 of the Integration Architect course. Each module stands on its own. Next: A Job, Call by Call

The question this module answers: When is a load too big for the APIs you’ve used so far, and what changes when you switch to the Bulk API?

Say you want to bring a cargo of data into Salesforce: a million records. The APIs from chapter 8 take up to 200 records a call (module 3). How many calls is a million records, 200 at a time? A million divided by 200: 5,000 calls.

Here’s how I picture it. You go to the bank with your deposit slips, and you’ve got a million deposits to make. The teller says, “Give me the first 200. Now get back in line.” Then the next 200, and back in line again. Your program is going back and forth, 200 records a call.

Then you notice somebody pulling up to the back of the bank in a pickup truck, or an 18-wheeler. Twenty or thirty minutes later they drive away, done, while you’re still going in and out of the line.

Going to the teller 5,000 times costs you three things:

  1. You’re burning your API calls. Every trip counts against the org’s daily allowance (chapter 8 module 7), shared with every other integration.
  2. Every trip is a chance for failure. A timeout, a dropped connection, a locked record. Five thousand trips, five thousand chances.
  3. You have to track them all separately. Which of the 5,000 worked? Which failed, and which do you send again?
The teller window and the loading dock Two equal panels. The teller window, the synchronous APIs: each trip, up to 200 records a call; a million records, about 5,000 calls, back of the line each time; you get back an answer for every record, right away; it fits singles and sets, fewer than about 2,000 records. The loading dock, the Bulk API: each trip, whole files that Salesforce splits into batches; a million records, a handful of calls; you get back a job ID now and the results later; it fits bulk, more than about 2,000 records. Underneath: same records, different door; over about 2,000 records, Salesforce points you to the loading dock. {"author": "Steve Simpson", "blueprint": "1.0.0", "builder": "standard 1.46.0", "built": "2026-10-27", "id": "DGM-DA-MG-20", "rights": "\u00a9 2026 Twinshark LLC. All rights reserved.", "template": "comparison 0.4.0", "theme": "stevetecharc 1.4.0"} The teller window the synchronous APIs EACH TRIP Up to 200 records a call A MILLION RECORDS About 5,000 calls, back of the line each time YOU GET BACK An answer for every record, right away FITS Singles and sets: fewer than about 2,000 records The loading dock the Bulk API EACH TRIP Whole files; Salesforce splits them into batches A MILLION RECORDS A handful of calls YOU GET BACK A job ID now, the results later FITS Bulk: more than about 2,000 records Same records, different door. Over about 2,000 records, Salesforce points you to the loading dock. © 2026 Twinshark LLC · stevetecharc.com
Click to enlarge

Same records, different door. (From the Data Architect course.)

The truck at the back of the bank is the Bulk API. It’s a REST API, but it’s a very special one. You don’t hand over records and wait for an answer to each one. You open a job, unload your files, and leave. Salesforce processes them in the background, and you come back for the results later. In Salesforce’s words, “You submit a request and come back for the results later. Salesforce processes the request in the background” (Introduction to Bulk API 2.0 and Bulk API (opens in a new tab), Bulk API 2.0 and Bulk API Developer Guide, checked 2026-11-01).

A million records now costs a handful of calls instead of 5,000. That solves the first cost. The other two change shape:

  • Failure moves inside the job. Salesforce retries for you, and what still fails comes back in a file. Module 6 is about reading it.
  • You track one job, not 5,000 calls. But nobody answers you per record, right away. Your program has to come back and ask.

And because it runs in the background, there’s no promise about when. “Because both Bulk APIs are asynchronous, Salesforce doesn’t guarantee a service level agreement” (same page). If someone needs an answer in seconds, the loading dock is the wrong door.

The loading dock isn’t only for unloading. If you try to pull a million records out of Salesforce with an ordinary REST query, it’ll time out. It just won’t work. So the Bulk API is how you put in a million records, and the Bulk API is how you take out a million records or more. Salesforce calls them ingest jobs (insert, update, upsert, delete) and query jobs. Module 2 is the ingest job; module 5 is the query job.

Notice who drives the truck in both cases. When data comes in, a program outside Salesforce calls in and unloads. When data goes out, a program outside Salesforce still calls in and loads up. Salesforce never drives the truck to anyone. On chapter 8’s map of the ways in, Bulk is a door in, even for the jobs that carry data out. So the arrow on your landscape points at Salesforce, from whoever starts the job, as chapter 7 taught.

Who’s that program? Usually not one you write from scratch. Data Loader uses this API. MuleSoft uses it. Informatica and the other data tools use it. This is the main gateway for getting data in and out of Salesforce at volume. Even when you never see a job, knowing how the dock works tells you what your tool is doing, and what it can’t do for you.

So which feeds need the truck? Count the records in one trip. Steve Trucking runs about 3,300 deliveries a day, and each Retail Partner sends about a third of them.

  • Redrock’s evening manifests come in one set per distribution center: about 370 deliveries a set. That’s the teller window. A few calls with Composite, and Redrock gets an answer for every delivery right away.
  • Keystone’s nightly status file is every status change on Keystone’s deliveries that day: about 1,100 deliveries, about eight updates each, so about 8,800 rows a night, read out of Salesforce. That’s the loading dock.
  • The weekly export to Snowflake for the analytics team is a week of deliveries, about 23,000, with their status history. The loading dock, every week.
  • The RouteDesk migration in the Data Architect course was about 707,000 records, once. The same dock, for a load that happens one time.
The teller window or the loading dock The teller window or the loading dock: Steve Trucking's feeds, one per row, each counted and sent to a door. Redrock's evening manifest set, one set per distribution center into Salesforce, is about 370 deliveries, under 2,000, so it goes to the teller window, in grey: Composite, chapter 8 module 3. Keystone's nightly status file, read out of Salesforce, is about 8,800 status rows every night, so it goes to the loading dock, highlighted: a bulk query, module 5. The weekly export to Snowflake, read out of Salesforce, is about 23,000 deliveries and their status history, so the loading dock: a bulk query, module 5. The RouteDesk migration, once, into Salesforce, is about 707,000 records, from the Data Architect course's chapter 10, so the loading dock: a bulk load, module 2. The legend: grey is under about 2,000 records, the synchronous APIs. Underneath: count the records in one trip; over about 2,000, Salesforce points you to the loading dock. {"author": "Steve Simpson", "blueprint": "1.0.0", "builder": "standard 1.57.1", "built": "2026-11-01", "id": "DGM-INT-BK-01", "rights": "\u00a9 2026 Twinshark LLC. All rights reserved.", "template": "cells 0.5.0", "theme": "stevetecharc 1.4.0"} THE FEED HOW MANY IN ONE TRIP THE DOOR Redrock's evening manifest set one set per distribution center, into Salesforce About 370 deliveries under 2,000 The teller window Composite: chapter 8 module 3 Keystone's nightly status file read out of Salesforce About 8,800 status rows every night The loading dock a bulk query: module 5 The weekly export to Snowflake read out of Salesforce About 23,000 deliveries and their status history The loading dock a bulk query: module 5 The RouteDesk migration once, into Salesforce About 707,000 records Data Architect, chapter 10 The loading dock a bulk load: module 2 count so count so count so count so Count the records in one trip. Over about 2,000, Salesforce points you to the loading dock. HOW TO READ IT Under about 2,000 records: the synchronous APIs © 2026 Twinshark LLC · stevetecharc.com
Click to enlarge

Count the records in one trip, and the count picks the door.

That’s the difference between a migration and an integration. A migration drives the truck once. An integration drives it every night, or every week, for years. So everything in this chapter, the job, the results, the limits, has to work without a person watching, on the night nobody’s looking. Where exactly the line between the teller and the dock falls, and how to check a feed against the dock’s limits, is module 7.

Test knowledge. Know when the Bulk API is the answer: large volumes, thousands of records or more, where nobody waits for an answer per record. It’s asynchronous: you submit a job and come back for the results, with no guaranteed time. It does both ingest (insert, update, upsert, delete) and query. Fewer records, or parents and children arriving together many times a minute, go through the synchronous APIs, such as Composite.

In 2023 I made a short video of the loading dock: the Bulk API’s steps, from opening a job to collecting the results. The note under the video says what’s still right and what’s changed since.

STA 1.7 · Salesforce Bulk API Steps: Importing Data at the Loading Dock · 7:12 · published 2023-09-15 · plays from YouTube when you click it · Watch on YouTube · More videos: Salesforce Integration Architecture Videos
  • For every feed on the landscape, how many records in one trip, at today’s numbers and at year three’s (chapter 6).
  • Teller or dock. And if it’s the dock: does anyone need an answer sooner than “later”? If so, the design needs something else.
  • Who drives the truck. Which program or tool opens the jobs, under which integration user, and who owns it when it fails at two in the morning.
  • Once, or forever. A migration’s load and a nightly feed use the same dock, but the nightly feed has to run unattended.