DEV Community

Felipe Rohde
Felipe Rohde

Posted on

Por que eu parei de usar Cloudinary e construí minha própria API de imagens

Tudo começou com uma fatura que não fazia sentido.

Não foi uma fatura absurda — foi pior do que isso. Foi uma fatura razoável, de um serviço que eu estava usando corretamente, seguindo a documentação à risca. E ainda assim, no fim do mês, a conta me incomodava.

Eu rodava o Cloudinary num projeto de e-commerce com volume moderado. Nada explosivo: algumas centenas de milhares de imagens, transformações básicas, entrega via CDN. O feijão com arroz. Só que o feijão com arroz do Cloudinary tem uma característica que eu não tinha entendido direito até olhar os números de perto.

A parte que ninguém lê com atenção: banda

O Cloudinary cobra por um sistema de créditos unificados. Um crédito equivale a 1.000 transformações, ou 1 GB de armazenamento, ou 1 GB de banda. Tudo sai do mesmo pote.

A boa notícia, e eu quero ser justo aqui: transformação em cache não é recobrada. Uma vez que o Cloudinary gera uma versão derivada da imagem (resize, crop, AVIF), as próximas requisições daquela mesma URL vêm do cache sem custo de transformação. Nesse ponto o modelo deles é honesto.

O problema é a outra ponta. Cada entrega consome banda — e banda é crédito. Servir a mesma imagem já processada mil vezes do CDN não custa transformação nenhuma, mas queima 1 crédito a cada GB entregue, requisição após requisição, mês após mês.

Ou seja: o trabalho pesado você paga uma vez. A entrega você paga sempre. E num e-commerce com tráfego decente, a entrega é justamente a parte que não para de crescer.

Foi isso que me fez acordar de madrugada fazendo conta. Não era um bug, não era uso errado. Era o modelo funcionando exatamente como projetado — só que projetado pra escalar a fatura junto com o teu sucesso.

O degrau

Some a isso o salto entre planos.

O plano gratuito te dá 25 créditos mensais. Quando você estoura, o próximo nível — o Plus — pula direto pra $99/mês (ou $89/mês se você fechar anual). Esse plano te dá 225 créditos: 9x mais do que o gratuito.

O detalhe que dói: você dá o salto pro $99 às vezes usando uma fração desses 225 créditos. Não existe meio-termo. Você está confortável no gratuito até o dia em que não está, e aí o pulo é direto pra três dígitos por mês.

A gota d'água não foi o preço

Mas se eu for sincero, o preço não foi o motivo principal. Foi a fragmentação.

Pra montar uma pipeline básica de imagens de produto, eu precisava de quatro coisas diferentes:

  • Transformação (resize, crop, AVIF/WebP)
  • Paleta de cores + metadados
  • BlurHash para loading progressivo
  • Remoção de fundo para fotos de produto

Quatro responsabilidades. Na prática, isso virava múltiplos SDKs, múltiplos contratos e múltiplos pontos de falha. Cada um com sua própria forma de cobrar, sua própria documentação, seu próprio jeito de quebrar.

Eu queria uma URL. Decidi construir uma.

O que eu construí: img apis

A ideia central do img apis é simples: uma única URL GET faz tudo.

GET /info/r2/produto.jpg

Retorna metadados, as cores dominantes (com uma paleta de seis tons — vibrant, muted e suas variações claras e escuras) e BlurHash — numa única chamada.

GET /r2/produto.jpg?w=800&format=avif&bg-remove=true

Entrega a imagem redimensionada, convertida para AVIF, com fundo removido. Parâmetros na query string. Sem SDK.

O billing que eu queria ter encontrado

Como a banda foi o que me machucou no Cloudinary, foi exatamente nela que eu decidi ser diferente:

  • Cache hits custam zero — incluindo a banda. Você paga o processamento uma vez. As próximas 999 requisições, transformação e entrega, são de graça.
  • Erros custam zero. Um 404 não consome crédito.
  • Banda inclusa. Sem medidor de GB rodando a cada entrega.

O contraste com o Cloudinary não é que eles recobram processamento — eles não recobram, e seria desonesto dizer que sim. O contraste é a banda: lá, cada entrega do CDN queima crédito; aqui, depois do primeiro processamento, o cache é seu de graça.

O plano começa em $9/mês, com domínio customizado e SSL inclusos.

Por que Cloudflare

A escolha não foi arbitrária. O img apis roda inteiro em Cloudflare Workers e serve de 300+ PoPs globais — a imagem é processada e entregue do ponto mais perto do usuário, sem viagem de volta a uma origem central. Na prática isso aparece nos números: latência mediana na casa dos 47 ms e taxa de cache hit acima de 94%.

E aqui mora a sinergia com o billing. Se você usa R2 como storage, não há egress fees — os bytes nunca saem da rede da Cloudflare pra serem processados. Foi exatamente o egress, somado à banda de entrega, que tornava a conta de outros serviços imprevisível. Mantendo storage, processamento e CDN dentro da mesma rede, o custo de mover dados some.

Suas imagens continuam sendo suas. Você registra a fonte uma vez — R2, S3, ou qualquer prefixo HTTPS — e o img apis busca o original ao vivo, transforma na edge e descarta: nada do seu original fica armazenado do lado deles. Trocar de provider depois não muda nenhuma URL que você já publicou.

E não tem SDK nem chave de API pra gerenciar: cada workspace ganha um namespace embutido na própria URL. Você joga num <img src> ou num fetch() e pronto — o controle de quem pode chamar fica numa allowlist de CORS no dashboard.

Honestidade sobre limitações

O img apis não tem storage próprio, não faz upload direto, e não processa vídeo. Se você precisa de storage gerenciado com upload, o Cloudinary ainda faz isso — e faz bem.

O img apis é para quem já tem o storage resolvido e quer parar de pagar banda a cada entrega de uma imagem que já foi processada uma vez.

Começando

As free tools em imgapis.com/tools funcionam sem conta — cole qualquer URL pública e veja a resposta ao vivo. O trial de 200 créditos não pede cartão.

Top comments (0)