vê se a responsta do chatgpt te ajuda:

Para lidar com a inserção de um grande número de contatos no banco de dados sem interferir no restante das operações, você pode usar uma abordagem assíncrona e/ou paralela para inserir os contatos em lotes. Aqui está um exemplo de como você pode fazer isso no Adonis.JS usando async/await e Promise.all:

const upsert: BaileysEventHandler<'contacts.upsert'> = async (contacts: BaileysContact[]) => {
    try {
        // Dividir os contatos em lotes para inserção
        const batchSize = 100; // Número de contatos em cada lote
        const batches = [];
        for (let i = 0; i < contacts.length; i += batchSize) {
            batches.push(contacts.slice(i, i + batchSize));
        }

        // Executar a inserção em lotes em paralelo
        await Promise.all(batches.map(async (batch) => {
            const trx = await Database.transaction();
            const transformedContacts = await Promise.all(batch.map(async (data) => {
                return transformDataOnStore(data);
            }));

            const wppIds = transformedContacts.map((contact) => contact.wpp_id);
            const images = await contactService.getMultipleImages(wppIds, client);

            if (images?.length) {
                transformedContacts.forEach((contact, index) => {
                    const matchedImage = images.find((img) => img.wpp_id === contact.wpp_id);
                    transformedContacts[index]['img_url'] = matchedImage?.image ?? null;
                });
            }

            await Contact.updateOrCreateMany('wpp_id', transformedContacts, trx);
            await trx.commit();
        }));
    } catch (error) {
        Logger.error(error, 'Ocorreu um erro ao criar/atualizar contatos');
    }
};

Neste código, os contatos são divididos em lotes de tamanho batchSize e cada lote é inserido em uma transação separada. Isso permite que as inserções ocorram em paralelo, melhorando a eficiência e reduzindo o tempo total de processamento. Certifique-se de ajustar o tamanho do lote conforme necessário com base na capacidade do seu banco de dados e nos requisitos de desempenho.

E também tem isso aqui

Aqui estão cinco formas de lidar com o caso de inserir muitas linhas no banco de dados em Node.js, considerando a necessidade de inserir os contatos em background sem interferir no restante das iterações:

  1. Utilizando Filas de Tarefas (ex: Bull):

    • Crie uma fila de tarefas utilizando uma biblioteca como Bull.
    • Adicione os contatos à fila para serem processados em background.
    • Implemente um worker que irá processar os contatos da fila e inseri-los no banco de dados.
    • Isso permite que a inserção seja feita de forma assíncrona e em background, sem interferir nas outras operações.
  2. Utilizando Promessas e Assincronia:

    • Envie a inserção dos contatos para uma função assíncrona que será executada em segundo plano.
    • Isso pode ser feito utilizando setTimeout com um tempo curto para garantir que a função seja executada em background.
  3. Dividindo em Lotes (Batching):

    • Divida os contatos em lotes menores e insira cada lote separadamente.
    • Isso evita sobrecarregar o banco de dados com um grande número de inserções de uma vez.
    • Utilize uma estratégia de controle de taxa para garantir que os lotes sejam inseridos de forma eficiente.
  4. Utilizando Threads de Trabalho (Worker Threads):

    • Utilize threads de trabalho para realizar a inserção dos contatos em paralelo.
    • Isso permite que a inserção seja feita de forma concorrente, aproveitando melhor os recursos do sistema.
  5. Utilizando Processos Secundários (Child Processes):

    • Crie processos secundários para lidar com a inserção dos contatos.
    • Isso permite que a inserção seja feita em um processo separado, deixando o processo principal livre para outras operações.

Escolha a abordagem que melhor se adapta às necessidades do seu projeto e à infraestrutura disponível.

Acabei vendo que no adonis tem algo pré pronto (Knex) pra fazer inserções particionadas, que seria o batchInsert. Ficou ligeiramente mais eficaz, porém não sei se atingi a melhor prática ainda, sabendo que é um SaaS, então serão muitas empresas salvando os contatos (embora seja apenas uma vez ao ler o QRCode).

Agradeço a ajuda <3