Sanity pricing: More documents vs. more attributes on documents?

3 replies
Last updated: Sep 22, 2021
Do I understand correctly that the pricing plans encourage using structured content more (so having more documents) than using attributes on documents (unique attributes)? 🙂
AI Update

Your understanding is partially correct, but it's important to clarify what the pricing plans actually incentivize:

The Real Story: Attributes vs Documents

Sanity's attribute limits don't necessarily "encourage" more documents over attributes - rather, they reflect technical realities of how the datastore works. Here's what you need to know:

What Counts as an Attribute?

According to the Sanity documentation on technical limits, an attribute is counted as any unique path/datatype combination across your dataset:

  • An attribute attr containing a string, integer, and null value in different documents counts as 3 attributes (not 1)
  • Arrays add 1 extra attribute per unique datatype they contain
  • Complex nested structures (like block content fields) create many unique paths

The Limits

Dataset-wide limits:

  • Free plan: 2,000 unique attributes
  • Growth plan: 10,000 unique attributes
  • Enterprise: Custom limits

Per-document limits:

  • Free/Growth: 1,000 attributes per document
  • Enterprise: 8,000 attributes per document

The Practical Reality

The attribute limit is more about schema complexity than document count. You could have:

  • 1 million documents with simple schemas (few attributes each) ✅
  • 10,000 documents with extremely complex, deeply nested schemas ❌

As one community member explained: "The unique paths count the same for one document as for a million using those paths."

What This Means for Your Architecture

You should optimize for:

  1. Structured, normalized content - Breaking content into logical document types
  2. Avoiding overly complex schemas - Deeply nested objects and arrays with many custom types increase attribute count quickly
  3. Reusing schema patterns - The same field structure across documents doesn't multiply the attribute count

Common attribute-heavy patterns to watch:

  • Multiple block content fields with custom marks/blocks
  • Page builders with many component types
  • Field-level localization across many languages
  • Complex arrays of objects with varying structures

So yes, Sanity's architecture naturally encourages well-structured content broken into logical documents, but not because documents are "cheaper" than attributes - rather because clean, normalized schemas are more maintainable and less likely to hit technical limits. The Free plan's 10 million document limit is quite generous, while the 2,000 attribute limit can be reached with complex schemas, which does indirectly encourage simpler, more normalized content models.

Show original thread
3 replies
I've always thought of it as more of a technical limitation. But at any rate, you can't wrong with structured content 😉 In my about 8 projects with Sanity, unique attributes have never been a problem.The only case I can see being problematic is a website that have supports a lot of different languages. But then there are properly better ways to handle this than using attributes.
Attribute limits can be a pretty opaque concept to understand. Generally, the follow (long read, sorry) helps to keep in mind when thinking about them:
The attribute limit is essentially about how many unique paths you have in your dataset. Let's take a structure like this:
{ "foo": [ { "bar":…, "baz":… }, { "bar":…, "baz":… }, { "bat": { "bar":… } } ] }
This leads to the following six attributes:
foo -> an array
foo[] -> an object
foo[].bar -> a string
foo[].baz -> a string
foo[].bat -> an object
foo[].bat.bar -> a string
A simple array of strings will give you a lower attribute count than a block content field, because a block content field has, among others:
the blockContent array, with inside of it:
blocks objects, with inside of them:
markDefs and children arrays, with inside of them:
span types, with inside of them:
a marks array and a text field
This nested structure is further extended by any custom structures you might add to it, each with its own content, so having a bunch of block content fields may lead to a hefty amount of different paths and therefore unique attributes. The same would be true for array fields of complex objects, such as page builders. You may even have block content inside of complex objects inside of arrays. Localisation is another candidate to boost the number of attributes.
In terms of reducing your attribute count, the above examples are good places to start looking. What is also noteworthy is that deleting documents will not lower attribute count, unless you delete every last document that follows a certain schema. The unique paths count the same for one document as for a million using those paths. It's basically about how many paths are occupied by data.
To keep an eye on things while you optimise, you can use this url: https://<projectId>.api.sanity.io/v2021-03-25/data/stats/ <datasetName>. The attribute count is the value of fields.count.value and the limit is inside fields.count.limit.
A final note is that it also helps to remove any unused content from schema revisions. For example, if you used to have a particular document type with a bunch of documents, but later removed that type, or even just some fields within a type, make sure to clean up the content so there are no leftovers in the datastore that will count towards the attribute limit.
This clarifies a lot. Thanks!

Sanity – Build the way you think, not the way your CMS thinks

Sanity is the developer-first content operating system that gives you complete control. Schema-as-code, GROQ queries, and real-time APIs mean no more workarounds or waiting for deployments. Free to start, scale as you grow.

Was this answer helpful?