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 size25 MB (direct upload)32 MB

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.

Files up to 25 MB upload directly, and the app tells you straight away if a file is too large.

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 app tells you straight away that the file is too large. Split it into smaller files and import them one at a time.

The real limit on a very large import is time

Rows are processed in parallel (up to 20 at a time), automatically slowed to stay within Shopify's rate limits. 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 for metaobject entries and blog articles. Sent to Shopify as-is for metafield values
Cell valuesTrimmed of leading and trailing whitespace

Full file requirements →

Throughput and retries

Behaviour
Concurrency Up to 20 rows in parallel, automatically slowed to stay within Shopify's rate limits.
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 A background worker on our servers. Each row's progress is saved as it goes.
Interrupted jobs If the server restarts mid-import, the job stops safely and Retry carries on from the rows that hadn't started. Rows interrupted mid-write are marked uncertain, refunded and flagged for you to check.

Parallel processing is paced automatically so it stays within Shopify's Admin API rate limits, and every row still gets its own recorded outcome.

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, because 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 can't be reached yet. Customer and order support is coming very soon.

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
Rows needing attention downloadimport-<jobId>-errors.csv with the row number, label, Shopify ID, message and warnings of every error and uncertain row. Doesn't include your original columns
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. Credits don't expire while the app is installed
EnforcementOne credit reserved before each row is written, released if the row isn't written
Out of creditsThe import stops cleanly mid-file. Retry isn't offered: buy credits and run the file again in Skip mode

Credits and billing →

Things ImportKit deliberately doesn't do

The reasoning behind each of these →

Next