datomic

rutledgepaulv 2026-01-14T15:15:41.741479Z

Hey I'm trying to get a handle on why a couple of our databases are encountering this error when trying to transact some new schema (a few thousand attrs) ๐Ÿงต

"java.lang.IllegalArgumentException: :db.error/schema-count-exceeded Schema can contain at most 1048576 elements",

๐Ÿคฏ 1
rutledgepaulv 2026-01-14T15:15:59.903659Z

My first way to confirm how many attributes we used was a simple count:

(datomic.api/q
  '[:find (count ?a) .
    :where 
    [?a :db/valueType]]
  (datomic.api/history db))

=> 52850
which is obviously less than 2^20 However if I check the ID numbers that were assigned I see a number very close to 2^20 (1048576):
(datomic.api/q
  '[:find (max ?e) .
    :where 
    [?e :db/valueType]]
  (datomic.api/history db))

=> 1047018
I guess my questions are how could there be a discrepancy and is there anything i can do aside from migrating the db into a new db?

rutledgepaulv 2026-01-14T15:20:08.361729Z

And in the error message does "elements" refer to "schema entities" or to something else like datoms?

favila 2026-01-14T15:25:33.400609Z

It refers to entities in partition 0 (:db.part/db)

favila 2026-01-14T15:25:51.785399Z

do you have lots of those? e.g. maybe partition entities or idents?

favila 2026-01-14T15:28:28.736289Z

if you are on peer, you can do this:

favila 2026-01-14T15:28:38.625009Z

(->> db :elements (map class) frequencies)

rutledgepaulv 2026-01-14T15:40:18.859219Z

(->> db :elements (map class) frequencies)
=> {datomic.db.Partition 3, nil 994148, datomic.db.Attribute 52850, datomic.db.ValueType 16, datomic.db.Function 2}

favila 2026-01-14T15:41:00.763499Z

did you manually assign the db-id of an attribute and skip a whole bunch of numbers?

favila 2026-01-14T15:42:55.808479Z

or accidentally transact data into partition 0 using :db.part/db tempids?

favila 2026-01-14T15:43:27.574189Z

or maybe you have a schema metalayer that uses lots of entities in partition 0?

favila 2026-01-14T15:43:52.763029Z

nil 994148 is the problem; those are either real entities consuming the count, or skipped numbers

๐Ÿ‘ 1
rutledgepaulv 2026-01-14T15:44:32.693989Z

i don't think so but could it be related to how we transact the schema elements? we don't use the map syntax and use [:db/add ...] with tempids. we do have some meta schema stuff that might be ending up partition 0 although I thought they were all just ref datoms hanging off schema elements and pointing to entities in the user partition

favila 2026-01-14T15:46:55.365729Z

> I thought they were all just ref datoms hanging off schema elements and pointing to entities in the user partition Not sure what you mean here. To clarify: [:db/add attr :my-schema-meta x] doesn't consume an entity id in part0; [:db/add (d/tempid :db.part/db -1) ...] or {:db/id attr :component-attr {...}} does

๐Ÿ‘ 1
rutledgepaulv 2026-01-14T15:50:08.107119Z

k i'll dig into what the others things are in partition 0 a bit

favila 2026-01-14T15:56:28.843459Z

this may help

favila 2026-01-14T15:56:34.140509Z

(transduce
 (take-while #(zero? (d/part (:e %))))
 (completing
  (fn [m [e a]] (update m (d/ident db a) (fnil inc 0))))
 {}
 (d/seek-datoms db :eavt 0))

rutledgepaulv 2026-01-14T15:58:39.424109Z

{:db/index 42178,
 :db/unique 9,
 :db/valueType 52850,
 :meta/schema 947,
 :db/tupleType 2,
 :db/isComponent 4547,
 :db/lang 2,
 :db/fulltext 2,
 :attribute/content-type 4,
 :db/cardinality 177986,
 :db/doc 166,
 :db/ident 58971,
 :db/code 2,
 :attribute/malli-schema 4,
 :db.install/valueType 16,
 :db.alter/attribute 73445,
 :attribute/resolves 26,
 :db.install/function 2,
 :db.install/partition 3,
 :db/tupleAttrs 2,
 :db.install/attribute 52850,
 :fressian/tag 16,
 :attribute/groups 31}

favila 2026-01-14T15:59:58.804729Z

...schema alteration

favila 2026-01-14T16:00:05.794929Z

oof

favila 2026-01-14T16:00:12.235659Z

I did not see that coming

rutledgepaulv 2026-01-14T16:01:22.912729Z

yeah i know we had an issue a while ago with some of our attributes toggling back and forth between one/many cardinality (we infer schema and two competing tools weren't agreeing on cardinality). Maybe that's still in play. The above is from running your snippet on the history db

rutledgepaulv 2026-01-14T16:04:43.227499Z

if I sum those i get 464061 though which is less than the 994148 nil entries, should I not expect those to match?

favila 2026-01-14T16:07:01.992809Z

it's not the full story, but it's more than doubling your attr count

๐Ÿ‘ 1
rutledgepaulv 2026-01-14T16:08:47.449099Z

what does :db.alter/attribute represent?

favila 2026-01-14T16:09:11.075339Z

a schema alteration

rutledgepaulv 2026-01-14T16:10:16.922549Z

what classifies as an alteration? changing the ident on an attribute?

favila 2026-01-14T16:10:45.696449Z

any of these: https://docs.datomic.com/schema/schema-change.html

๐Ÿ‘ 1
favila 2026-01-14T16:11:58.769159Z

is implicit, and was explicit on older syntax. see e.g. https://docs.datomic.com/schema/schema-change.html#removing-avet-index

rutledgepaulv 2026-01-14T16:16:29.934069Z

(->> (datomic.api/seek-datoms (datomic.api/history db) :eavt 0)
     (take-while (fn [x] (zero? (datomic.api/part (:e x)))))
     (map :e)
     (dedupe)
     (count))
=> 52880
(->> (datomic.api/seek-datoms (datomic.api/history db) :eavt 0)
     (take-while (fn [x] (zero? (datomic.api/part (:e x)))))
     (map :e)
     (count))
=> 464061

rutledgepaulv 2026-01-14T16:17:15.846319Z

what might the rest of the story be if both of those are still well below 2^20? something causing it to skip IDs?

favila 2026-01-14T16:20:37.267519Z

that's all I can think of

favila 2026-01-14T16:21:14.601519Z

maybe informative to seek over EAVT, noting delta of E vs previous E, looking for big delta

favila 2026-01-14T16:21:45.023399Z

surprised at the number of retractions

rutledgepaulv 2026-01-14T16:26:30.740169Z

there are 2831 gaps in numbering ranging in size from 2 to 10781