How are attributes counted when reusing custom object types in Sanity?

15 replies
Last updated: May 2, 2022
I'm a little confused by how the attributes limit is determined. Really, I'm just a little confused what an attribute actually is. Let's say I have and object called
nameFull
and it has two string fields
firstname
and
lastName
This object is in my document twice, one reference has the name
yourName
and the other has the name
yourFathersName
. How many unique attributes would this be? I'll show a rough example:
Document:

{
type: "document",
name: "familyMembers",
fields: [
  {
    name: "yourName",
    type: "nameFull"
  },
  {
    name: "yourFathersName",
    type: "nameFull"
  },
]
}
nameFull Object:

{
type: "object",
name: "nameFull",
fields: [
  {
    name: "firstName",
    type: "string"
  },
  {
    name: "lastName",
    type: "string"
  }
]
}
AI Update

In your example, you would have 6 unique attributes counting toward your limit.

Here's how Sanity counts attributes based on the attribute limit documentation:

An attribute is defined as a unique combination of path and datatype through your content. Think of it as the different paths through your documents. What matters is the structure, not how many times you use it.

For your familyMembers document with the nameFull object used twice:

  1. yourName → object
  2. yourName.firstName → string
  3. yourName.lastName → string
  4. yourFathersName → object
  5. yourFathersName.firstName → string
  6. yourFathersName.lastName → string

Since yourName and yourFathersName are different field names, they create separate paths. Even though they're both using the same nameFull object type, each field name creates its own unique path through your content structure.

Key things to understand:

  • Each unique path is counted once, regardless of how many documents use it
  • Different field names create different paths, even when using the same object type
  • If you had used an array of nameFull objects instead (like names[]), you'd only have 3 attributes: names (array), names[].firstName (string), and names[].lastName (string) - because array items share the same path pattern
  • Attributes only count when they hold actual content - just defining them in your schema doesn't increase the count

The good news: If you had 100 documents all using this same structure, it would still be just 6 attributes. The count doesn't multiply by the number of documents.

Plan limits:

  • Free: 2,000 attributes
  • Growth: 10,000 attributes
  • Enterprise: Custom

To check your current usage, visit: https://<projectId>.api.sanity.io/v1/data/stats/<datasetName> and look at fields.count.value.

If you're concerned about hitting limits, consider best practices like using arrays for repeated structures (which share paths), avoiding excessive nesting, and being mindful of field-level translation approaches that can multiply your attribute count.

Show original thread
15 replies
hmmm - references are a way of linking documents. Each document existing on its own.
objects* like this are re-usable prescribed sets of data. If you wanted each ‘name’ to be a person document with nicely mapped relations you would need to change this into a document of its own or add your own additional fields to assign IDs or check for duplicates in each document where you use the object.
If you’re doing something like a family tree, maybe take out the “father/mother name” fields and use references between each person document. Then you can create a nice set of relationships between each person.
bit of pseudocode - messy off the top of my head, some strings implied…

// people schema
{
name: "person"
type: "document"
fields: [
{name: "name", type: "array", "of": [
{name: "namefield", type: "object": "fields": [
{name: "nametype", type: "array": of: [first, surname, middle, maiden, nickname, other]}, {name: "name", type: "string"}
]}]...
// then add another object of references to other people as relatives
{name: "relations", type: "object", fields: [
{name: "relation", type: "array", of: [mom, dad, sib, spouse, etc]},
{
      title: 'Relative',
      name: 'relative',
      type: 'reference',
      to: [{type: 'person'}]
}]}...
I like to get a visual of the data layout I want to design and then use different arrays and objects to work the actual schema into this visual model. This visualization is pretty easy with family trees.
you can add various flags for genetic vs marriage relations and keep going with as much detail as you’d like. Fun project.
You should check out and repost this on content-modeling &amp; content-strategy for possibly a bit more community feedback with examples. Keep it up!
ah good question, I’ll dig into it a bit more thanks!
my gut feeling is that since each of those imported objects doesn’t have a unique ID on its own, they’ll count toward the attribute limit. And this is what I was alluding to in my brainstorm using arrays and references to both cut down on attribute limits and provide improved relationship data (something like a grandfather with a few children who have a few children each can get out of hand pretty fast - if not with attributes then with 12+1 versions of the grandfather’s name that are otherwise unrelated in the dataset)
And I believe this is generally what the documentation’s suggestions on cutting down on attribute limits are referring to as well. I’m just not absolutely certain off-hand what the differences in attribute limits might be between your imported object fields and something like block text, which in it its own document is an imported array of objects, each with their own defined content types.
To my knowledge, generally focussing on meaning, not presentation like my example hints at is a best practice both for easier organization and keeping attribute limits to a minimum. I’m not sure what your ultimate use-case my be, but I have yet to see community or team plan projects come up against attribute limits since starting here.
I think in your example use case, I would advise nesting name fields in each person document and then creating an array of references between each person to keep overall attributes from becoming exponential unique values. It is a little more work up front to plan but with the benefit of saving a ton of editing time and avoiding something like grandpa “User” being listed 12 additional times for himself, his kids, and his grandkids.
personDoc.nameObject.first.last
personDoc.relatedRef.personDoc
then use queries to get the referenced data from each referenced document
but this is something that would be WAY easier to whiteboard ^_^
That’s how I think about it. If you have a lot of fields, the goal is to keep those unique object values to a minimum, and you would best do this by thinking of it as primitive datatypes with as many arrays and references as possible.
Bonus: this also makes queries and searching immensely easier.
An attribute is a unique combination of properties and datatypes and must hold content to count toward your limit. In your first example, I count 8 attributes (assuming they all have data):

yourName
yourName.nameFull
yourName.nameFull.firstName
yourName.nameFull.lastName
yourFathersName
yourFathersName.nameFull
yourFathersName.nameFull.firstName
yourFathersName.nameFull.lastName
Block content can impact the attribute count quite a bit, though it’s often justified given its return. Duplicated fields, including field level translations, can drive the attribute count up a lot.
Focussing on using references, you can see how much this cuts down on attributes on its own as an array of references just copies the referenced document ID instead of all of the subsequent values:(“article” document with a referenced “category” document)

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?