# Limits and limitations

Plan your integration around custom object limits and current constraints.

Custom objects are in private preview. Review these limits and constraints before building your integration.

## Limits and quotas

These limits apply during private preview. You can’t request increases.

| Resource | Limit |
| --- | --- |
| Object definitions | 50 per account, with up to 100 fields each. |
| Records | 150,000,000 per object definition. |
| Request size | 1 MB (1,048,576 bytes). Larger requests fail with `invalid_request_json_body`. |
| Values per request | 1,000 entries in the `fields` object. Each field, array item, and property inside a reference counts as an entry. |
| Names and descriptions | 40 characters for object API names, 64 for field API names and object display names, and 100 for object definition descriptions. Display-name length counts UTF-16 code units, so an emoji can count as 2 or more characters. |
| Rate limits | Stripe’s standard [rate limits](https://docs.stripe.com/rate-limits.md). Each endpoint’s limit is shared across your object definitions. |

For field types, validation ranges, and naming rules, see [Define custom objects](https://docs.stripe.com/custom-objects/define.md). For pagination and query limits, see [Create and manage records](https://docs.stripe.com/custom-objects/records.md) and [Search records](https://docs.stripe.com/custom-objects/search.md).

## Integration constraints

Plan around these constraints when choosing how to store and manage data:

- **Account scope**: Use a private app installed in your own account. Connect platforms can’t create or read custom objects on connected accounts, organizations can’t share definitions across accounts, and public apps can’t use custom objects.
- **Record management**: The Dashboard is read-only. Create, update, and delete records with the API or generated SDK. Bulk creation, updates, deletion, and imports aren’t available. Records aren’t available in Stripe Sigma or Stripe Data Pipeline.
- **Permissions and sensitive data**: Permissions cover all custom objects in an account, not individual objects, fields, or records. Custom roles can’t include custom object permissions. Every field is indexed for search. Don’t store sensitive information, such as payment card details, bank account details, government-issued ID numbers, passwords, or API keys. See [Data you store](https://docs.stripe.com/custom-objects/define.md#data-you-store).
- **Duplicate records after retries**: Creating a record doesn’t support idempotency keys. Retrying a failed create can create duplicates. Store your own identifier to reconcile uncertain results, but don’t use a search-before-create check to guarantee uniqueness. Search is eventually consistent, and concurrent writers can both find no match.
- **Schema changes and retained data**: Upload an app to create or change definitions. Published versions can’t be retired. Removing an optional field doesn’t delete its stored values. To clear them, update records through a version that declares the field, or delete the records. Review the [schema change rules](https://docs.stripe.com/custom-objects/versioning.md#allowed-and-blocked-schema-changes) before your first upload.
- **References**: Stripe doesn’t check that referenced objects exist or update references when you delete their targets. Your integration must handle missing targets.
- **Search consistency**: New or changed records can take up to 10 seconds to appear in search results, and recently deleted records can still appear. Retrieve records by ID when you need their current state. Only the first 1,024 characters of a string are searchable and returned in search results.

## Issues and workarounds

These issues can block setup or affect your integration’s results:

- **References between new definitions**: An upload that adds two definitions where one references the other can fail with a `referenced_type` error. Upload the referenced definition first, then add the definition that references it. For mutual references, make one reference optional and add it in a later upload.
- **Upload version errors**: Before your first upload, omit `custom_object_definitions.version` from `stripe-app.yaml`. If an upload fails after Stripe accepts it, restore that value to your latest published version and upload again. A failed upload can leave a version unfinished or published in only some modes. Upload again to finish publishing it. If it keeps failing, contact [Stripe support](https://support.stripe.com/contact).
- **Local app development**: Custom object requests from UI extensions return a 403 error during `stripe apps start`. Upload your app and test the installed version. Use a sandbox, because custom object Dashboard pages don’t work in legacy test mode.
- **Delays after writes or uploads**: New endpoints can return `not_found` for a few minutes after an upload. New and changed records can take a few minutes to display in Dashboard lists. If a record remains missing or out of date in search, update it to re-index it.
- **Workflow execution**: Manual runs fail with a 403 error when a workflow has custom object steps. Runs triggered by events aren’t affected. A workflow triggered by a record’s deletion can’t retrieve the record, so its run is blocked and its steps don’t run. Use created or updated events when the workflow needs the record’s data.
- **Dashboard monetary filters**: Filters on monetary amount fields expect amounts in the currency’s minor units, even though the Dashboard displays values in major units.
- **Removed fields in Dashboard views**: Search can match a field removed from the latest version. Saved views that use removed fields can show errors or ignore those settings. Update saved views to use fields in the latest version.
