Limits
Apps/Assistant and plans/Limits

Limits

Every hard limit an app can run into, in one place. Check here before committing to a design; each row links to where it's explained.

Framework

LimitValuePast it
Web frameworkNext.js only (App Router, under web/)The dev server runs next dev and deploys run next build; nothing else is served
Versions a build starts fromnext ^16, react ^19, react-dom ^19, typescript ^5.8The app's own package.json can pin others; @inferencebureau/apps-sdk is always the bundled one
What a deploy shipsweb/, api/ and the root package.jsonOther folders stay in the app's files, not the build
Deploy build4 minutesThe deploy fails: "The build took too long." See Deploys

Files and pushes

LimitValuePast it
One file, pushed inline1 MiBThe CLI uploads bigger files to storage first (Getting started)
One file, uploaded50 MiBRefused: "Files can be at most 50 MiB." Not synced
Files in an environment2,000The push is refused
Changes in one push200 (and 8 MiB)The CLI splits bigger pushes for you
Path length512 charactersThe file is refused
Never synced.git, .ib, node_modules, .next, .vercel, .turbo, .DS_Store, .ibignore entriesSkipped

Environments

LimitValuePast it
Development environments per app10, development includedAdding another is refused
Production1 per appChanges only through a deploy
Environment name20 characters: lowercase letters, digits and single hyphens, starting with a letter. Not production, development, prod, dev, both, deploy, new or previewRefused
Dev serverSleeps after about 30 minutes without activity (kept awake while ib-apps dev is connected); 2 vCPU. A wake takes about 7 seconds, a first start (or a changed package.json, which reinstalls) about 20Wakes on the next request while you've synced, previewed or run ib-apps dev in the last 6 hours; after that only those wake it (Preview). A start that keeps failing is retried after 1, 5 and 30 minutes, then waits for your next sync. Or run it on your computer with ib-apps dev --local
Local dev serverib-apps dev --local: a heartbeat every 5 seconds keeps the environment pointed at your computer; 45 seconds without one hands it backThe hosted dev server wakes on the next request

Records and queries

LimitValuePast it
A record's stored JSON256 KiBThe write is refused (Models)
Page size (first)50 by default, at most 250Clamped to 250 (Records)
Filter operatorsequals, notEquals, in, notIn, lessThan, lessThanOrEqual, greaterThan, greaterThanOrEqual, isSet, startsWith, contains; combined with AND, OR, NOTAn unknown operator is an error naming the ones there are
containsText fields only: string, richText, email, url, enumAn error
Not filterable or sortablepassword, encryptedString, file, and fields that aren't stored (relationships, computed, vector)An error
Text searchEvery word, across the model's text fields; a model needs at least oneAn error for a model without text fields
Vector fieldsAt most 4,000 dimensions, matching the field's dimensionsThe schema or write is refused
Inline (base64) file in a writeAbout 3 MB, within the 4 MiB bodyUse a direct upload or copyURL
Direct file upload1 GiB; the upload URL lasts an hour, and the upload must be written to a record within 24 hoursRefused, or swept away
copyURL50 MiB, fetched within 30 secondsThe write fails
One query (records API, MCP)15 secondsRefused with query_timeout: declare an index for the filter or sort, and page with after rather than a deep skip (Models)
Calls to the records API and MCP500 a second per environment, in bursts of up to 1,000429 with Retry-After
Records API and MCP calls running at once20 per environment; a watch for changes doesn't count429 concurrency_limit_exceeded with Retry-After: 1
Storage reads (list, get)50 a second per environment, in bursts of up to 300429 with Retry-After
Storage writes (put, delete, upload URLs)10 a second per environment, in bursts of up to 60429 with Retry-After
Development emails (logged, not sent)60 a minute per environment, in bursts of up to 20429 with Retry-After
Copying production's data to development50,000 records and 2,000 filesRefused: copy a model at a time

Actions, jobs and schedules

LimitValuePast it
An action, run and onSuccess together (timeoutMS)30 seconds by default (5 minutes as a background job), between 1 second and 15 minutesThe run fails with a timeout (How actions run)
A background job's attemptIts action's timeoutMS: 5 minutes unless it says, at most 15The attempt fails and is retried (Retries)
Other records written with a run500The run fails and writes nothing (Writing other records)
A job's params1 MiB of JSONRefused
Retries6 by default, at most 20; backoff from 15 seconds doubling to an hourThe job fails
Queued ahead30 daysRefused
concurrency1 to 100, with a concurrencyKey (200 characters); dedupeKey 300 charactersRefused, or the key is cut
SchedulesFive-field cron, so at most once a minuteMissed occurrences older than 10 minutes are skipped
Listing jobs100 by default, at most 500Clamped

Request bodies

LimitValuePast it
The API4 MiB of JSON413 payload_too_large
MCP512 KiB per message413
Shopify webhooks1 MiB (Shopify's own limit)Refused
App proxy and extension URL responses (Storefront)5 MiB, answered within 25 seconds502 "The app's answer was too large." or 504 "The app didn't answer."
A sleeping development app behind the proxyWaits up to 8 seconds for it to wake (a wake usually takes about 7)The store is told the app is starting; the next request finds it awake
Bulk metafield edits250,000 changes a run; past 2,500 they go in bulkRefused (Bulk metafield edits)
A metafield run's CSV4.5 MB in the request, or 100 MB by csvUrl413, or the plan fails

Environment variables

LimitValuePast it
Variables per environment200Adding another is refused
A value32 KiBRefused
A nameLetters, digits and _, not starting with a digit, at most 128Refused
Reserved namesIB_*, VERCEL*, __NEXT*, NEXT_RUNTIME*, NODE_ENV, PORT, HOSTNAME, PATH, HOME, NEXT_PUBLIC_SHOPIFY_API_KEYRefused: Inference Bureau or the runtime sets them

Shopify

LimitValuePast it
Admin API pacingPaced against the store's cost bucket; waits up to 8 seconds in a request, 60 in the background (The Admin API)Shopify's throttled answer comes back to the call
A sync run's paged partAbout 29 minutesStops: "The run ran out of time." Start it again with since. Models listed in bulk carry on until they're done
Listed in bulkPast 100 pages: about 1,000 products or orders, 2,500 customers or inventory items, 10,000 collectionsOne bulk pass per store at a time (Big stores)
App name and proxy subpath30 charactersCut to 30
Production installs on Free5 storesRefused before Shopify's approval page (Free's limits)

Extensions

LimitValuePast it
Handle50 lowercase letters, digits and dashesThe extension isn't released (Folders and handles)
Sidekick tools20 per app; names 64 characters, descriptions 512; the app's summary 1,000Reported on the release (Sidekick tools)
Web pixel script128 KiB builtThe pixel stays out of the release
Flow template description1,024 charactersThe template isn't released
Types not releasedPayments extensions (payments_extension)Reported, never sent
One release's builds10 minutesExtensions not built stay out

Custom domains

LimitValuePast it
Count, across the team's appsFree none, Pro 5, Scale 25Refused until one is removed (Custom domains)
UniquenessOne team and app per hostnameRefused

Plan quotas

Pooled across the team's production environments; development is never counted. Pro and Scale charge overage past an allowance; Free pauses its apps until the month ends. Details on Plans and usage.

FreeProScale
Runs a month50,000500,0005,000,000
Requests a month100,0001,000,00010,000,000
Storage0.5 GB-month5 GB-months50 GB-months
Bandwidth5 GB50 GB500 GB
Production apps1UnlimitedUnlimited
Production store installs5UnlimitedUnlimited
Custom domainsNone525
Logs kept1 day14 days30 days
Restore records back1 day7 days30 days
Dev servers awake at once21025
Dev server hours100 awake hours per app a monthAbout 100 per app a month, fair useSame as Pro

A dev server that can't start for one of these limits shows as asleep to visitors, and Logs say which limit held it. One goes to sleep 30 minutes after it was last used, which frees its place. Dev servers also start only once one of the team's owners or admins has verified their email address. When development servers are at capacity across Inference Bureau, a start waits a few minutes; production is never affected. None of this applies to ib-apps dev --local, which runs development on your own computer.