ImportKit's limits

Every limit ImportKit imposes, with the reason for it. Where a limit exists because of a real trade-off, the trade-off is named rather than hidden.

Looking for Shopify's limits?

Shopify separately caps how many definitions you can have, how large a metafield value can be, and how many items fit in a list. Those are on Shopify's limits — along with an honest account of which ones ImportKit checks before your import runs, and which only surface when Shopify rejects a row.

File size and rows

ImportPre-import check
Maximum rows1,000,00050,000
Maximum file size50 GB32 MB
Need more than that?

Both the file size limit and the number of files per import can be raised — email support@importkit.app with a rough idea of the volume and what you're importing. The 50 GB figure is a sensible default rather than a technical ceiling.

Two very different budgets, because two very different jobs. The import path streams: the browser parses the file row by row without holding it, the upload is consumed as a byte stream, and rows are written to storage in batches. Memory stays flat whatever the file size, so those caps are guard rails against absurd input rather than a memory ceiling.

Very large uploads don't pass through the app server at all — they go to storage as a resumable multipart upload, which is why the ceiling can be this high. Direct in-browser posts are capped much lower (25 MB) because they have to survive proxy body limits; the app picks the right path for you based on file size.

The pre-import check can't stream and never will. It reports a verdict for every row, detects duplicates across the whole file, and totals the credits required — all three are whole-file questions. So it holds the file in memory and has a much lower cap.

Over the check's limit

You'll see a “This file is too large to preview” notice, and the import is still allowed. You lose the preview, not the safety: every row is still checked against your store as it's imported, and your conflict mode is applied per row identically.

If you'd rather keep the preview, split the file into parts under 50,000 rows. Rows are independent, so splitting is always safe.

Over the import's limit

The upload is refused, with a message telling you to split the file — or to ask us for a higher limit:

error
This file is over the 50.0 GB upload limit. Split it into smaller
files and import them one at a time, or contact support to request a
higher limit.

The size check runs as bytes arrive, so an oversized file is never pulled into memory in the first place.

The real limit on a very large import is time

Rows go to Shopify one at a time. A million-row file is allowed, but it will take a long while — the constraint is the Admin API, not ImportKit. For anything at that scale, split it and run the parts in sequence so you get checks, clearer results and manageable retries.

File format

ConstraintValue
Accepted extension.csv only
DelimiterComma
EncodingUTF-8
Header rowMust be the first row
Empty rowsSkipped automatically
Blank cellsSkipped, not written — can't clear an existing value
Cell valuesTrimmed of leading and trailing whitespace

Full file requirements →

Throughput and retries

Behaviour
Concurrency Rows are processed strictly one at a time.
Transient failures Up to 3 attempts per row on a rate limit or server error, backing off 1 second then 2.
Other failures Not retried. A validation error won't become valid on a second attempt.
Cancellation Checked every 5 rows, so a cancel takes effect within a handful of rows rather than instantly.
Execution An in-process background job on our servers, not a durable external queue.
Interrupted jobs A job stuck for more than 15 minutes is marked interrupted and can be resumed with Retry.

Serial processing is a deliberate choice, not a missing feature. Shopify's Admin API throttles hard enough that parallel writes get rejected and end up slower, and one-at-a-time keeps row ordering predictable and every row's outcome unambiguous.

Cancellation is polled rather than checked per row because checking per row would add a database query per row, for every import, to serve a feature used occasionally.

Read pagination

ImportKit reads your store to detect collisions and resolve references. Most of those reads are fully paginated; two aren't, and one of those is worth knowing about.

ReadLimit
Metafield definitions (collision detection)All pages, 250 per page
Metaobject definitionsAll pages, 250 per page
Metaobject entry handles (collision detection)All pages, 250 per page
Blogs offered as import targetsFirst 50
Article metafield definitions offered for mappingFirst 100
Metaobject entries used to resolve a reference by handle or name First 250 only, not paginated
The one that can bite

Referencing a metaobject entry by handle or display name works only for the first 250 entries of the referenced type. Beyond that, use a full gid://shopify/Metaobject/… value, which needs no lookup. Collision detection for entries is fully paginated, so create-versus-update decisions are unaffected. More →

Data rules enforced before any API call

RuleDetail
Metafield key2–64 characters, letters, numbers, hyphens, underscores
Namespace3–255 characters, same character set, defaults to custom
Reserved namespaces$app, app--, shopify-- and shopify are rejected — a CSV import creates merchant-owned definitions
Metaobject type3–255 characters, same character set. An $app: prefix is stripped with a warning
Metaobject entry handleLetters, numbers, hyphens, underscores
Metafield types recognised113, including every list.* variant. An unrecognised type is a warning, not an error, so Shopify stays the authority
Metafield definition typeImmutable. A row whose type differs from the existing definition is a conflict in every conflict mode
Metaobject definition fieldsField types immutable. Update mode adds new fields only and warns on any type mismatch

Owner types

Metafield definitions: 13 owner types. Metafield values: 7 owner types. Customers, orders, draft orders, companies and gift cards are unreachable by design.

The full lists, and why →

Limits that aren't ours

Everything above is a constraint ImportKit imposes. Shopify imposes its own, and they bite differently — a 64 KB metafield value size, 128 items per list, 40 fields per metaobject definition, 256 definitions per owner type. Most are measured by the pre-import check; the whole-store ceilings still surface as failed rows.

That's worth understanding before a large import: Shopify's limits →

Results and history

Behaviour
Row results paging200 rows per page
Large job detail viewShows the first portion of rows with a banner saying how many of how many
Errors downloadimport-<jobId>-errors.csv with Row,Title,Error
History retentionKept while the app is installed; deleted on shop redaction after uninstall, or on request

Billing

Behaviour
Cost1 credit per row written
Not chargedSkipped, conflicting, errored and uncertain rows; the pre-import check; uploads; mapping; templates
ModelPrepaid one-time purchases. No subscription, no expiry
EnforcementOne credit reserved before each row is written, released if the row isn't written
Out of creditsThe import stops cleanly mid-file and is resumable with Retry

Credits and billing →

Things ImportKit deliberately doesn't do

The reasoning behind each of these →

Next