diff --git a/README.md b/README.md
index c678758c649ca7208d36ffdfdbac74c7b96938e3..bbdf2433f8f48829ec6f5a9d28f55d90b5880ea5 100644
--- a/README.md
+++ b/README.md
@@ -78,6 +78,7 @@ Bugs
 - [ ] initialize dd_keys for new node (→ bootstrap)
 - [ ] fix merging blocked when inode unreachable, timeout seems ignored
 - [ ] fix pubsub cid can not be fetched triggers pubsub abort (dirty workaround for know)
+- [ ] fix `UND_ERR_HEADERS_TIMEOUT` that happen very often when pinning 📌
 Features
 - [x] pubkey instead of ss58 address if we want data to be compatible across networks → ss58
 - [ ] add periodic sync with a list of trusted peers (IPNS entries)
diff --git a/src/indexer/database.ts b/src/indexer/database.ts
index 468a0f972828fa4a565f1c8e865974dbb3f20230..da91c81ea38cfbe0f0fd5fe5b70a7b5e2c4428f8 100644
--- a/src/indexer/database.ts
+++ b/src/indexer/database.ts
@@ -87,7 +87,7 @@ const cesiumPlusProfile: QueryBuilder = {
       avatar = EXCLUDED.avatar,
       geoloc = EXCLUDED.geoloc,
       city = EXCLUDED.city,
-      socials = EXCLUDED.socials;
+      socials = EXCLUDED.socials
     WHERE EXCLUDED.time > profiles.time;
         `,
   dataGetter: defaultDataGetter,
@@ -195,15 +195,14 @@ async function handleIrWithNonNullData<T>(irCID: CID, ir: IndexRequest, q: Query
   }
   q.dataGetter(dataCID)
     .then((data) => q.dataTransform(irCID, ir, dataCID, data).then(dataHandler<T>(q, irCID, ir, dataCID)))
-    .catch((e) => {
-      console.log('☁️  error indexing ' + dataCID)
-      console.error(e)
+    .catch((_e) => {
+      console.log('😭 error indexing ' + dataCID)
     })
 }
 
 // insert index request in database
 export async function handleInsertRequest(irCID: CID, ir: IndexRequest) {
-  console.log('💾 indexing ' + irCID)
+  // console.debug('💾 indexing ' + irCID)
 
   switch (ir.kind) {
     // insert cesium plus profile
@@ -220,6 +219,8 @@ export async function handleInsertRequest(irCID: CID, ir: IndexRequest) {
 
     // delete cesium plus profile
     case CESIUM_PLUS_PROFILE_DELETE:
+      // FIXME if delete instruction is received from past, this should be ignored
+      // i.e.: database should keep track of deleted profiles with a timestamp to allow items to be inserted in any order
       await client.query(`DELETE FROM profiles WHERE pubkey = $1;`, [ir.pubkey])
       break
 
diff --git a/src/indexer/handlers.ts b/src/indexer/handlers.ts
index 3706a44c195d27d0c7ce38386c4761badc5cb1ac..0b4baf8f35ee1c333f5ec40776251f7f227e310f 100644
--- a/src/indexer/handlers.ts
+++ b/src/indexer/handlers.ts
@@ -3,7 +3,13 @@ import { CID } from 'multiformats'
 import EventEmitter from 'events'
 import { getLatestIndexedCID, handleInsertRequest, setLatestIndexedCID } from './database'
 import { kubo } from '../kubo'
-import { getDiff, getAll } from '../interface'
+import { getDiff } from '../interface'
+import type { IndexRequest } from '../types'
+import { arrayToVinode, mergeInodesSyncCID, timestampToKey } from '../processor'
+import { DD_TAMT_OPT } from './ipns'
+import type { Globals } from './start'
+
+const BATCH_SIZE = 1000
 
 // === EVENTS ===
 
@@ -14,16 +20,19 @@ export const events = new EventEmitter()
 export enum evtype {
   // event to trigger collecting new index requests in queue
   trigger = 'trigger',
+  // event to trigger collecting peer index requests from queue
+  triggerCollect = 'triggerCollect',
   // event to trigger injestion of new requests in database
   indexDiff = 'indexThat',
-  // event to trigger database sync from scratch or last state
-  indexStart = 'start'
+  // event to trigger computing diff
+  computeDiff = 'computeDiff'
 }
 
 // === INDEXING ===
 
-// queue of Start waiting to be processed
-const indexQueueStart: Array<CID> = []
+// queue of index requests waiting to be added to the tree
+// these are the requests coming from other pods
+const mergeQueue: Array<[string, CID]> = [] // FIXME at the moment the key is not used
 // queue of DiffData waiting to be processed
 const indexQueueDiff: Array<DiffData> = []
 // lock to prevent multiple database edits which would fake the last root cid
@@ -32,7 +41,96 @@ let isIndexing = false
 
 // === HANDLERS ===
 
-// diff indexer event handler
+/// ----- pubsub message handler -----
+export function getMessageHandler(processQueue: Array<[CID, IndexRequest]>) {
+  async function validMessageHandler(_cid: CID, dag: IndexRequest): Promise<void> {
+    // re-build the index request (because the type is loosely defined)
+    const ir: IndexRequest = {
+      kind: dag.kind,
+      time: dag.time,
+      data: dag.data,
+      pubkey: dag.pubkey,
+      sig: dag.sig
+    }
+    // then store the index request locally
+    kubo.dag
+      .put(ir)
+      .then((cid) => {
+        // cids should be the same
+        if (cid.toString() != _cid.toString()) console.log('👾 ', cid, '!=', _cid)
+        console.log('adding valid index request to process queue')
+        // pin the index request we just added
+        kubo.pin.add(cid).catch(() => console.log(`📌📌 could not pin index request that we just added ${cid}`))
+        // add index request to the process list
+        processQueue.push([cid, ir])
+        // ask to process the request
+        events.emit(evtype.trigger)
+      })
+      .catch(() => console.log(`📌 could not add valid index request ${_cid}`))
+    return
+  }
+  return validMessageHandler
+}
+
+/// insert a batch of index requests in tree
+async function insertBatch(rootCID: CID, items: Array<[CID, IndexRequest]>): Promise<DiffData> {
+  // convert it to a list of [key, cid] for batch insert (merge)
+  const requests = items.map(([cid, ir]) => [timestampToKey(ir.time), cid]).sort() as Array<[string, CID]>
+  const tree = arrayToVinode(requests)
+  // insert them
+  const newCID = await mergeInodesSyncCID(rootCID, tree)
+  const diffData: DiffData = { oldCID: rootCID, newCID, newItems: items }
+  return diffData
+}
+
+/// ----- queue event handler -----
+export function getBatchHandler(glob: Globals) {
+  async function handleBatchFromQueue(): Promise<void> {
+    // ignore event if already processing something or if queue is empty
+    if (glob.lockTree) {
+      console.log('busy')
+      return
+    }
+    if (glob.processQueue.length == 0) {
+      return
+    }
+    // if not processing, do lock process
+    glob.lockTree = true
+    // take elements from queue
+    let i = undefined
+    const items: Array<[CID, IndexRequest]> = []
+    let num = 0
+    while ((i = glob.processQueue.shift()) != undefined && num < BATCH_SIZE) {
+      num += 1
+      items.push(i)
+    }
+    console.log('merge queue', mergeQueue.length, 'process queue', glob.processQueue.length)
+
+    // try inserting items
+    try {
+      // insert batch and get diff
+      const diffData = await insertBatch(glob.rootCID, items)
+      // update root cid and publishes it
+      const newCID = diffData.newCID
+      console.log(`👉 new root CID ${newCID}`)
+      glob.rootCID = newCID
+      glob.lockTree = false
+      kubo.name.publish(newCID, DD_TAMT_OPT).catch(console.log)
+      // add new data to database
+      events.emit(evtype.indexDiff, diffData)
+    } catch (e) {
+      console.error(`🥊 error merging ${glob.rootCID} with ${items.length} items`, e)
+      glob.processQueue.push(...items) // add them back to the process queue
+      glob.lockTree = false
+      // try again to collect items
+      events.emit(evtype.trigger)
+    }
+    return // nothing
+  }
+  return handleBatchFromQueue
+}
+
+// diff event handler
 export async function indexKnownDiff(diff: DiffData): Promise<void> {
   // --- 1. manage lock
   // if locked, add to index queue
@@ -47,69 +145,91 @@ export async function indexKnownDiff(diff: DiffData): Promise<void> {
   const latestCID = await getLatestIndexedCID()
   // if not, unlock and go to indexStart with the new CID instead
   if (latestCID == null || diff.oldCID.toString() != latestCID?.toString()) {
-    console.log('diff is not based on same cid as database, re-computing diff')
-    isIndexing = false
-    await indexStart(diff.newCID)
-  } else {
-    // insert all index requests
-    diff.newItems.forEach((ir) => handleInsertRequest(ir[0], ir[1]))
-    // write new CID as latest indexed
-    await setLatestIndexedCID(diff.newCID)
-    // unlock
-    isIndexing = false
+    console.log('🤔 db is not at diff start, computing missing diff')
+    events.emit(evtype.computeDiff, diff.oldCID, diff.newCID)
   }
+  console.log('➕ adding', diff.newItems.length, 'items to the db')
+  // insert all index requests
+  diff.newItems.forEach((ir) => handleInsertRequest(ir[0], ir[1]))
+  // write new CID as latest indexed (this is purely informative)
+  console.log(`🦐 latest db cid ${diff.newCID}`)
+  await setLatestIndexedCID(diff.newCID)
+  // unlock
+  isIndexing = false
   // --- 3. check queues
   checkQueues()
 }
 
-// start indexer event handler
-export async function indexStart(cid: CID): Promise<void> {
-  // --- 1. manage lock
-  // if locked, add to index queue 
-  if (isIndexing) {
-    indexQueueStart.push(cid)
-    return
-  }
-  // else lock
-  isIndexing = true
-  // --- 2. handle
-  // read latest indexed root CID from database
-  const latestCID = await getLatestIndexedCID()
-  console.log('👀 latest indexed cid ' + latestCID)
+// compute diff with remote tree and add index requests to merge queue
+export async function computeDiff(fromCID: CID, toCID: CID): Promise<void> {
   // if they differ
-  if (latestCID?.toString() != cid.toString()) {
-    // if defined iterate over all index requests of diff
-    // else iterate over all index requests of given cid
-    const iterator = latestCID ? getDiff(latestCID, cid) : getAll(cid)
+  if (fromCID.toString() != toCID.toString()) {
+    console.log(`👐 computing diff from ${fromCID} to ${toCID}`)
+    // iterate over all index requests of diff
+    const iterator = getDiff(fromCID, toCID)
+    let num = 0
     for await (const leaf of iterator) {
       for (let irCID of leaf) {
-        // make sure to pin the index request to be able to serve its content later
-        kubo.pin.add(irCID, { recursive: true }).catch(() => console.log('📌 could not pin index request ' + irCID))
-        // when the index request is there, save it to the database
-        kubo.dag
-          .get(irCID)
-          .then((ir) => handleInsertRequest(irCID, ir.value))
-          .catch(() => console.log('☁️  could not get index request ' + irCID))
+        // add it to the process queue to be added in the tree
+        mergeQueue.push(['key', irCID]) // FIXME get key while iterating
+        num += 1
+      }
+      // make sure that collection is triggered regularly
+      if (num > BATCH_SIZE) {
+        num = 0
+        events.emit(evtype.triggerCollect)
       }
     }
-    // write root CID as lastest indexed CID
-    await setLatestIndexedCID(cid)
-    console.log('👍 new latest indexed cid ' + cid)
+    events.emit(evtype.triggerCollect)
   } else {
-    console.log('👌 already indexed ' + cid)
+    console.log(`👌 already at ${toCID}`)
   }
-  // unlock
-  isIndexing = false
-  // --- 3. check queues
-  checkQueues()
+}
+
+// get collector from mergeQueue to processQueue
+export function getItemsCollector(glob: Globals) {
+  // takes item from merge queue, fetch index request, and put them in process queue
+  async function fetchItemsFromMergeQueue() {
+    // sort merge queue by key to give a better chance of good batching
+    // mergeQueue.sort() // FIXME while key is not there, we can not sort
+    // number of items retreived
+    let num = 0
+    // item taker
+    let i = undefined
+    const items: Array<Promise<[CID, IndexRequest]>> = []
+    // takes items in queue but no more than batch and avoid duplicates and not when queue is full
+    const seen: Map<string, boolean> = new Map()
+    while ((i = mergeQueue.shift()) != undefined && num < BATCH_SIZE && glob.processQueue.length < BATCH_SIZE) {
+      const [_k, cid] = i
+      if (!seen.get(cid.toString())) {
+        seen.set(cid.toString(), true)
+        num += 1
+        items.push(Promise.all([cid, kubo.dag.get(cid).then((r) => r.value)]))
+      }
+    }
+    const awaitedItems = await Promise.all(items)
+    awaitedItems.forEach(([c, _ir]) => {
+      // make sure to pin the index request to be able to serve its content later
+      kubo.pin.add(c, { recursive: true }).catch((_e) => console.log(`📌 could not pin remote index request ${c}`))
+    })
+    // add index requests to process queue
+    glob.processQueue.push(...awaitedItems)
+    // ask them to be processed if not processing
+    if (!glob.lockTree) {
+      events.emit(evtype.trigger)
+    }
+    // ask next batch if any
+    if (mergeQueue.length) {
+      events.emit(evtype.triggerCollect)
+    }
+  }
+  return fetchItemsFromMergeQueue
 }
 
 // check queues
 function checkQueues() {
-  // check queue to see if diff came in the meanwile
+  // check queue to see if new diff came in the meanwile
   checkQueueDiff()
-  // when kown diff if clean, check sync
-  checkQueueStart()
 }
 
 // if diff came in the meanwhile, index them
@@ -118,10 +238,3 @@ function checkQueueDiff() {
     indexKnownDiff(indexQueueDiff.shift()!)
   }
 }
-
-// if start came in the meanwhile, index them
-function checkQueueStart() {
-  if (indexQueueStart.length != 0) {
-    indexStart(indexQueueStart.shift()!)
-  }
-}
diff --git a/src/indexer/start.ts b/src/indexer/start.ts
index ebdbabaf03b6373bccf7c8fd73a7ea23da5faf36..c7065dd552b2086e606cf6457a665c574af07e0a 100644
--- a/src/indexer/start.ts
+++ b/src/indexer/start.ts
@@ -1,108 +1,37 @@
-import { TOPIC } from '../consts'
-import { timestampToKey, arrayToVinode, mergeInodesSyncCID, resolveHist } from '../processor'
+import { EMPTY_NODE_CID, TOPIC } from '../consts'
+import { resolveHist } from '../processor'
 import { getPubSubHandler } from '../collector'
 import { KUBO_RPC, kubo, kubo2 } from '../kubo'
 import type { IndexHist, IndexRequest } from '../types'
 import { CID } from 'multiformats'
-import { events, evtype, indexKnownDiff, indexStart } from './handlers'
-import type { DdKeys, DiffData } from './types'
+import { getBatchHandler, getMessageHandler, indexKnownDiff, computeDiff, getItemsCollector } from './handlers'
+import { events, evtype } from './handlers'
+import type { DdKeys } from './types'
 import { getRootCIDfromArgs } from './utils'
-import { DD_TAMT_HIST_OPT, DD_TAMT_OPT, ddKeys } from './ipns'
+import { DD_TAMT_HIST_OPT, ddKeys } from './ipns'
 import { initHistIfNull, publishKeys, trusted_peer_list } from './bootstrap'
+import { getLatestIndexedCID, setLatestIndexedCID } from './database'
 
-// === HANDLERS ===
-
-/// ----- pubsub message handler -----
-async function validMessageHandler(_cid: CID, dag: IndexRequest): Promise<void> {
-  // re-build the index request (because the type is loosely defined)
-  const ir: IndexRequest = {
-    kind: dag.kind,
-    time: dag.time,
-    data: dag.data,
-    pubkey: dag.pubkey,
-    sig: dag.sig
-  }
-  // then store the index request locally
-  kubo.dag
-    .put(ir)
-    .then((cid) => {
-      // cids should be the same
-      if (cid.toString() != _cid.toString()) console.log('⚠️ ' + cid + ' != ' + _cid)
-      console.log('adding valid index request to process queue')
-      // pin the index request we just added
-      kubo.pin.add(cid).catch(() => console.log('📌 could not pin index request that we just added ' + cid))
-      // add index request to the process list
-      processQueue.push([cid, ir])
-      // ask to process the request
-      events.emit(evtype.trigger)
-    })
-    .catch(() => console.log('📌 could not add valid index request ' + _cid))
-  return
-}
-const handleMessage = getPubSubHandler(validMessageHandler)
-
-/// ----- queue event handler -----
-function handleBatch() {
-  // console.log('entering handleBatch')
-  // ignore event if already processing something or if queue is empty
-  if (isProcessingQueue) {
-    console.log('busy')
-    return
-  }
-  if (processQueue.length == 0) {
-    // console.log('nothing to process')
-    return
-  }
-  // if not processing, do lock process
-  isProcessingQueue = true
-  // console.log('processing handleBatch')
-  // take elements from queue
-  let i = undefined
-  const items: Array<[CID, IndexRequest]> = []
-  while ((i = processQueue.shift()) != undefined) {
-    items.push(i)
-  }
-  // convert it to a list of [key, cid] for batch insert (merge)
-  const requests = items.map(([cid, ir]) => [timestampToKey(ir.time), cid]).sort() as Array<[string, CID]>
-  const tree = arrayToVinode(requests)
-
-  // insert them
-  // console.log('merging tree on ' + rootCID)
-  mergeInodesSyncCID(rootCID, tree)
-    .then((cid) => {
-      // ➡️ update CID
-      const oldCID = rootCID
-      rootCID = cid
-      console.log(`👉 new root CID ${cid}`)
-      // ➡️ publish new CID
-      kubo.name.publish(rootCID, DD_TAMT_OPT).catch(console.log)
-      isProcessingQueue = false
-      // trigger an other event in case new requests arrived meanwhile
-      events.emit(evtype.trigger)
-      // emit event to be processed by indexer
-      // FIXME there is a vulnerability here since we to not check that items were not submitted twice
-      // this allows to submit data multiple times for repeated add in the database
-      // the merge function should return a list of cids that were *really* added
-      const diffData: DiffData = { oldCID: oldCID, newCID: rootCID, newItems: items }
-      events.emit(evtype.indexDiff, diffData)
-    })
-    .catch((e) => {
-      console.log('error merging ' + rootCID + ' ' + requests)
-      isProcessingQueue = false
-      events.emit(evtype.trigger)
-      console.log(e)
-    })
+// === GLOBALS ===
+export interface Globals {
+  // queue of index requests waiting to be processed
+  // these are the requests received by the network
+  processQueue: Array<[CID, IndexRequest]>
+  // lock to avoid triggering multiple simultaneous edits
+  lockTree: boolean
+  // root CID of tree
+  rootCID: CID
 }
 
 // ----- regularly publish history
 function periodicHistPublish(interval: number) {
   setInterval(async () => {
     // if history is up to date, to nothing
-    if (hist.current_index.toString() == rootCID.toString()) return
+    if (hist.current_index.toString() == glob.rootCID.toString()) return
     // else, update the history
     const newHist: IndexHist = {
       last_history: histCID,
-      current_index: rootCID,
+      current_index: glob.rootCID,
       number: hist.number + 1,
       timestamp: Date.now()
     }
@@ -131,7 +60,7 @@ async function peerSync(trusted_peer_list: string[]) {
         for await (const name of kubo.name.resolve(peerDdKeys.tamt, { nocache: true, timeout: 100 })) {
           const cid = CID.parse(name.slice(6))
           // found peer tree, request index diff
-          events.emit(evtype.indexStart, cid)
+          events.emit(evtype.computeDiff, glob.rootCID, cid)
         }
       }
     } catch (e) {
@@ -163,7 +92,9 @@ function anyErrorCallback(e: any) {
   pubsubSubscribe()
 }
 function pubsubSubscribe() {
-  kubo2.pubsub.subscribe(TOPIC, handleMessage, pubsubSubscribeOptions).catch(pubsubAbortCallback)
+  kubo2.pubsub
+    .subscribe(TOPIC, getPubSubHandler(getMessageHandler(glob.processQueue)), pubsubSubscribeOptions)
+    .catch(pubsubAbortCallback)
   console.log('🔌 connected to', KUBO_RPC)
   console.log('👂 listening on topic', TOPIC)
 }
@@ -184,24 +115,30 @@ const HIST_PUBLISH_PERIOD = 10 * MINUTE
 // regularly sync form peers to compensate from network outage
 const PEERSYNC_PERIOD = 1 * DAY
 
-// === GLOBALS ===
-// queue of index requests waiting to be processed
-const processQueue: Array<[CID, IndexRequest]> = []
-// lock to avoid triggering multiple simultaneous edits
-// this prevents from branching the local AMT
-let isProcessingQueue = false
-
-/// global rootCID variable
-// set it from CLI args
-let rootCID = await getRootCIDfromArgs(process.argv)
-await initHistIfNull(rootCID) // make sure history is available until then
+// init globals
+const glob: Globals = {
+  processQueue: [],
+  lockTree: false,
+  // set global rootCID from CLI args
+  rootCID: await getRootCIDfromArgs(process.argv)
+}
+await initHistIfNull(glob.rootCID) // make sure history is available until then
 let histCID: CID = await resolveHist()
 let hist: IndexHist = (await kubo.dag.get(histCID)).value
 
+// get latest db CID
+let latestCID = await getLatestIndexedCID()
+if (latestCID == null) {
+  latestCID = EMPTY_NODE_CID
+  setLatestIndexedCID(latestCID)
+}
+console.log(`🛢 latest indexed cid ${latestCID}`)
+
 // bind event handlers
-events.on(evtype.trigger, handleBatch)
+events.on(evtype.trigger, getBatchHandler(glob))
 events.on(evtype.indexDiff, indexKnownDiff)
-events.on(evtype.indexStart, indexStart)
+events.on(evtype.computeDiff, computeDiff)
+events.on(evtype.triggerCollect, getItemsCollector(glob))
 pubsubSubscribe() // subscribe to index requests channel
 periodicHistPublish(HIST_PUBLISH_PERIOD) // regularly publish history
 periodicPeerSync(PEERSYNC_PERIOD) // regularly sync from peers
@@ -209,7 +146,7 @@ periodicPeerSync(PEERSYNC_PERIOD) // regularly sync from peers
 // emit event to tell indexer to start indexing to database
 // if it is starting from scratch (emtpy database), it will iterate over all values
 // if it already indexed up to a given cid (last_indexed_cid in db), it will only iterate over the diff
-events.emit(evtype.indexStart, rootCID)
+events.emit(evtype.computeDiff, latestCID, glob.rootCID)
 // at startup browse peer list
 peerSync(trusted_peer_list)
 
diff --git a/src/processor.ts b/src/processor.ts
index bcc2a25f25e83320664bd5c0992c69f5da494c65..350418f49bebee00451501e1aee5e8e22aafe53c 100644
--- a/src/processor.ts
+++ b/src/processor.ts
@@ -200,11 +200,12 @@ export async function processLeaf(node: IndexLeaf, val: CID): Promise<CID> {
 export async function mergeInodesSyncCID(nodeACID: CID, nodeB: IndexVinode | IndexLeaf): Promise<CID> {
   // fail with small timeout since this data is supposed to be pinned locally
   // console.log('fetching ' + nodeACID)
-  const nodeA = (await kubo.dag.get(nodeACID, { timeout: 100 })).value
+  const nodeA = (await kubo.dag.get(nodeACID, { timeout: 1000 })).value // FIXME decrease this timeout without bug
   const newCID = await mergeInodesSync(nodeA, nodeB)
   // unpin old node CID if different
   // we do not mind if it was not pinned
-  if (nodeACID.toString() != newCID.toString()) kubo.pin.rm(nodeACID).catch(() => {})
+  // WIP pin des not work well
+  // if (nodeACID.toString() != newCID.toString()) kubo.pin.rm(nodeACID).catch(() => {})
   // no need to pin new node CID like:
   // kubo.pin.add(newCID)
   // this is already done with the pin option kubo.dag.put(cid, { pin: true })
@@ -224,7 +225,8 @@ export async function mergeInodesSync(nodeA: IndexInode | IndexLeaf, nodeB: Inde
       leaf: cidList
     }
     return kubo.dag.put(newLeaf).then((cid) => {
-      kubo.pin.add(cid).catch(() => console.log('could not pin newly created leaf'))
+      // WIP pin des not work well
+      // kubo.pin.add(cid).catch((_e) => console.log(`📌📌 could not pin newly created leaf ${cid}`))
       return cid
     })
   } else if (isAleaf || isBleaf) {
@@ -280,7 +282,8 @@ export async function mergeInodesSync(nodeA: IndexInode | IndexLeaf, nodeB: Inde
           newNode.children[c.b1] = [c.nk1, childA]
           newNode.children[c.b2] = [c.nk2, await concretizeCid(childB)]
           const newNodeCid = await kubo.dag.put(newNode).then((cid) => {
-            kubo.pin.add(cid).catch(() => console.log('could not pin newly created node'))
+            // WIP pinning does not work well
+            // kubo.pin.add(cid).catch((_e) => console.log(`📌📌 could not pin newly created node ${cid}`))
             return cid
           })
           noda.children[b] = [c.common, newNodeCid]
@@ -293,7 +296,8 @@ export async function mergeInodesSync(nodeA: IndexInode | IndexLeaf, nodeB: Inde
   }
   // now that we have the new node, we can upload it and return its cid
   return kubo.dag.put(noda).then((cid) => {
-    kubo.pin.add(cid).catch(() => console.log('could not pin newly merged node'))
+    // WIP pinning does not work well
+    // kubo.pin.add(cid).catch((e) => console.log(`📌📌 could not pin newly merged node ${cid}`))
     return cid
   })
 }
diff --git a/src/scripts/index-database.ts b/src/scripts/index-database.ts
index d5a208fcc34f234d0cba9f83499160387406e1a0..0dccb9dfaa1cbf8976e75021decc3a1fa708348b 100644
--- a/src/scripts/index-database.ts
+++ b/src/scripts/index-database.ts
@@ -1,12 +1,10 @@
 import { CID } from 'multiformats'
-import { indexStart } from '../indexer/handlers'
 import { client, handleInsertRequest } from '../indexer/database'
 import { getAll } from '../interface'
 import { kubo } from '../kubo'
 import type { IndexRequest } from '../types'
 
 const cid = CID.parse('bafyreiay2zpectyuxb4d5nxxkwcpdk76ivrm36qmrutpbaaxldh6yt46xi')
-await indexStart(cid)
 // await client.end()
 
 
diff --git a/src/views/DiffView.vue b/src/views/DiffView.vue
index 42bd2f6fafeda8df41532f40496db35f2b56e1df..8461511cf47a15ac65d9a3be9f07bb78b71e7a6c 100644
--- a/src/views/DiffView.vue
+++ b/src/views/DiffView.vue
@@ -22,14 +22,19 @@ function setRightRoot() {
 }
 
 async function compareRoots() {
+  // reset diff
+  addedLeft.value = []
+  addedRight.value = []
+  // manage trivial cases
   if (leftRootCid.value == null || rightRootCid.value == null) {
     result.value = 'cid undefined'
     return
   }
-  if (leftRootCid.value == rightRootCid.value) {
+  if (leftRootCid.value.toString() == rightRootCid.value.toString()) {
     result.value = 'same'
     return
   }
+  // do compute
   result.value = 'computing diff...'
   // fetch root nodes
   const [leftRoot, rightRoot] = await Promise.all([kubo.dag.get(leftRootCid.value), kubo.dag.get(rightRootCid.value)])
@@ -55,7 +60,7 @@ function initWithLastCommit() {
         kubo.dag.get(hist.value.last_history).then((hist1) => {
           leftRootCid.value = hist1?.value.current_index
           if (leftRootCid.value) {
-            compareRoots()
+            // compareRoots()
           }
         })
       }
@@ -83,13 +88,13 @@ onMounted(initWithLastCommit)
     <h2>removed:</h2>
     <ul>
       <li v-for="e in addedLeft" :key="e[1].toString()">
-        <span class="mono">{{ e[0] + '*'.repeat(KEYSIZE - e[0].length) }}</span> {{ e[1].toString() }}
+        <span class="mono">{{ e[0] + '*'.repeat(KEYSIZE - e[0].length) }} {{ e[1].toString() }}</span>
       </li>
     </ul>
     <h2>added:</h2>
     <ul>
       <li v-for="e in addedRight" :key="e[1].toString()">
-        <span class="mono">{{ e[0] + '*'.repeat(KEYSIZE - e[0].length) }}</span> {{ e[1].toString() }}
+        <span class="mono">{{ e[0] + '*'.repeat(KEYSIZE - e[0].length) }} {{ e[1].toString() }}</span>
       </li>
     </ul>
   </div>