<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"><channel><title>upgbp — arquitetura de dados e stacks web modernas</title><description>Erros reais de produção em Next.js, Postgres e serverless: o log, o diagnóstico e o código que resolveu. Sem teoria genérica.</description><link>https://upgbp.com/</link><language>pt-br</language><item><title>Cortando o custo de API de LLM: medir, rotear e cachear</title><link>https://upgbp.com/artigos/reduzir-custo-api-llm-cache-roteamento-contexto/</link><guid isPermaLink="true">https://upgbp.com/artigos/reduzir-custo-api-llm-cache-roteamento-contexto/</guid><description>A fatura triplicou sem o uso triplicar. Como atribuir custo por funcionalidade e quais alavancas realmente rendem, na ordem de retorno.</description><pubDate>Sun, 23 Aug 2026 00:00:00 GMT</pubDate><category>APIs &amp; Resiliência</category><category>llm</category><category>custo</category><category>cache</category><category>prompt</category><category>observabilidade</category><author>bruno@upgbp.com (Bruno Oliveira Rodrigues)</author></item><item><title>Push não chega no iOS: as regras da Apple para PWA instalada</title><link>https://upgbp.com/artigos/push-nao-chega-no-ios-pwa-instalada-safari/</link><guid isPermaLink="true">https://upgbp.com/artigos/push-nao-chega-no-ios-pwa-instalada-safari/</guid><description>No Safari móvel a API de notificação nem existe até o site ser adicionado à tela de início. As cinco condições, e como detectar cada uma.

ReferenceError: Can&apos;t find variable: Notification</description><pubDate>Fri, 21 Aug 2026 00:00:00 GMT</pubDate><category>Performance Web</category><category>ios</category><category>pwa</category><category>web push</category><category>safari</category><category>service worker</category><author>bruno@upgbp.com (Bruno Oliveira Rodrigues)</author></item><item><title>Fila no Postgres com SKIP LOCKED, ou serviço de fila: qual escolher</title><link>https://upgbp.com/artigos/fila-no-postgres-skip-locked-vs-qstash/</link><guid isPermaLink="true">https://upgbp.com/artigos/fila-no-postgres-skip-locked-vs-qstash/</guid><description>Dois workers pegando a mesma tarefa é o defeito clássico de fila caseira. A cláusula que resolve, e quando vale trocar o banco por um serviço.

ERROR: deadlock detected — Process 18442 waits for ShareLock on transaction 9912</description><pubDate>Wed, 19 Aug 2026 00:00:00 GMT</pubDate><category>APIs &amp; Resiliência</category><category>postgres</category><category>filas</category><category>concorrência</category><category>qstash</category><category>background jobs</category><author>bruno@upgbp.com (Bruno Oliveira Rodrigues)</author></item><item><title>Web Push do zero: Service Worker, VAPID e o pedido de permissão</title><link>https://upgbp.com/artigos/web-push-service-worker-vapid-do-zero/</link><guid isPermaLink="true">https://upgbp.com/artigos/web-push-service-worker-vapid-do-zero/</guid><description>A implementação inteira, do registro do worker ao envio. E o erro de UX que queima a permissão do usuário para sempre, sem possibilidade de desfazer.

DOMException: Registration failed - permission denied</description><pubDate>Sun, 16 Aug 2026 00:00:00 GMT</pubDate><category>Performance Web</category><category>web push</category><category>service worker</category><category>pwa</category><category>vapid</category><category>next.js</category><author>bruno@upgbp.com (Bruno Oliveira Rodrigues)</author></item><item><title>Prisma, Drizzle ou postgres.js: medindo o que importa em serverless</title><link>https://upgbp.com/artigos/prisma-drizzle-postgres-js-benchmark-serverless/</link><guid isPermaLink="true">https://upgbp.com/artigos/prisma-drizzle-postgres-js-benchmark-serverless/</guid><description>A maioria dos benchmarks de ORM mede a coisa errada. O que pesa em função efêmera é a primeira query, não a milésima — e o script para medir isso.</description><pubDate>Fri, 14 Aug 2026 00:00:00 GMT</pubDate><category>Dados &amp; Migrações</category><category>prisma</category><category>drizzle</category><category>postgres</category><category>benchmark</category><category>serverless</category><author>bruno@upgbp.com (Bruno Oliveira Rodrigues)</author></item><item><title>Cron em serverless: Vercel Cron, pg_cron ou Cloudflare Workers</title><link>https://upgbp.com/artigos/cron-serverless-vercel-pg-cron-cloudflare/</link><guid isPermaLink="true">https://upgbp.com/artigos/cron-serverless-vercel-pg-cron-cloudflare/</guid><description>As três opções resolvem agendamento de formas incompatíveis. O critério de escolha, e os quatro erros que aparecem em qualquer uma delas.

Cron job failed: GET /api/cron/faturas returned 401 Unauthorized</description><pubDate>Wed, 12 Aug 2026 00:00:00 GMT</pubDate><category>APIs &amp; Resiliência</category><category>cron</category><category>serverless</category><category>vercel</category><category>supabase</category><category>cloudflare</category><author>bruno@upgbp.com (Bruno Oliveira Rodrigues)</author></item><item><title>Streaming e Suspense: eliminando o waterfall que trava a página</title><link>https://upgbp.com/artigos/streaming-ssr-suspense-eliminando-waterfall/</link><guid isPermaLink="true">https://upgbp.com/artigos/streaming-ssr-suspense-eliminando-waterfall/</guid><description>Um await depois do outro num Server Component soma latências. Como paralelizar e, melhor ainda, entregar a página antes dos dados chegarem.</description><pubDate>Sun, 09 Aug 2026 00:00:00 GMT</pubDate><category>Performance Web</category><category>next.js</category><category>react</category><category>suspense</category><category>streaming</category><category>ttfb</category><author>bruno@upgbp.com (Bruno Oliveira Rodrigues)</author></item><item><title>RLS no Supabase: por que sua query retorna array vazio</title><link>https://upgbp.com/artigos/rls-supabase-query-retorna-array-vazio/</link><guid isPermaLink="true">https://upgbp.com/artigos/rls-supabase-query-retorna-array-vazio/</guid><description>Com Row Level Security ligada, o SELECT bloqueado não dá erro — devolve nada. Como depurar a política sem desligar a segurança para &quot;testar&quot;.

new row violates row-level security policy for table &quot;pedidos&quot; (42501)</description><pubDate>Fri, 07 Aug 2026 00:00:00 GMT</pubDate><category>Dados &amp; Migrações</category><category>supabase</category><category>postgres</category><category>rls</category><category>segurança</category><category>prisma</category><author>bruno@upgbp.com (Bruno Oliveira Rodrigues)</author></item><item><title>429 em API de IA: fila com concorrência e orçamento de tokens</title><link>https://upgbp.com/artigos/rate-limit-429-api-de-ia-fila-com-concorrencia/</link><guid isPermaLink="true">https://upgbp.com/artigos/rate-limit-429-api-de-ia-fila-com-concorrencia/</guid><description>Promise.all sobre quinhentos itens não é paralelismo, é um ataque. Como respeitar os dois limites que essas APIs impõem sem serializar tudo.

RateLimitError: 429 Rate limit reached. Limit: 30000 tokens/min. Try again in 1.28s</description><pubDate>Wed, 05 Aug 2026 00:00:00 GMT</pubDate><category>APIs &amp; Resiliência</category><category>rate limit</category><category>llm</category><category>concorrência</category><category>typescript</category><category>filas</category><author>bruno@upgbp.com (Bruno Oliveira Rodrigues)</author></item><item><title>Bundle analyzer: as dependências que sempre estouram o JavaScript</title><link>https://upgbp.com/artigos/bundle-analyzer-dependencias-que-estouram-o-javascript/</link><guid isPermaLink="true">https://upgbp.com/artigos/bundle-analyzer-dependencias-que-estouram-o-javascript/</guid><description>Quando o peso está no pacote compartilhado, o problema não é uma rota — é uma biblioteca. As seis que mais aparecem e o que colocar no lugar.</description><pubDate>Sun, 02 Aug 2026 00:00:00 GMT</pubDate><category>Performance Web</category><category>next.js</category><category>bundle</category><category>dependências</category><category>webpack</category><category>performance</category><author>bruno@upgbp.com (Bruno Oliveira Rodrigues)</author></item><item><title>Query lenta no Postgres: do pg_stat_statements ao índice certo</title><link>https://upgbp.com/artigos/query-lenta-postgres-explain-analyze-indice-faltando/</link><guid isPermaLink="true">https://upgbp.com/artigos/query-lenta-postgres-explain-analyze-indice-faltando/</guid><description>Como achar qual consulta derruba o banco, ler o plano de execução sem adivinhação e escolher o índice que resolve — em vez de criar cinco na esperança.

ERROR: canceling statement due to statement timeout (57014)</description><pubDate>Fri, 31 Jul 2026 00:00:00 GMT</pubDate><category>Dados &amp; Migrações</category><category>postgres</category><category>performance</category><category>índices</category><category>explain</category><category>supabase</category><author>bruno@upgbp.com (Bruno Oliveira Rodrigues)</author></item><item><title>fetch failed com ECONNRESET no Node: undici, keep-alive e timeouts</title><link>https://upgbp.com/artigos/econnreset-fetch-failed-node-22-undici-keepalive/</link><guid isPermaLink="true">https://upgbp.com/artigos/econnreset-fetch-failed-node-22-undici-keepalive/</guid><description>A mensagem do fetch nativo não diz nada sozinha. O erro real está em err.cause, e a causa quase sempre é uma conexão reaproveitada tarde demais.

TypeError: fetch failed { cause: Error: read ECONNRESET (code: ECONNRESET, syscall: read) }</description><pubDate>Wed, 29 Jul 2026 00:00:00 GMT</pubDate><category>APIs &amp; Resiliência</category><category>node</category><category>undici</category><category>fetch</category><category>keep-alive</category><category>timeout</category><author>bruno@upgbp.com (Bruno Oliveira Rodrigues)</author></item><item><title>LCP travado por fonte: preload, font-display e métricas de fallback</title><link>https://upgbp.com/artigos/lcp-travado-fontes-locais-preload-font-display/</link><guid isPermaLink="true">https://upgbp.com/artigos/lcp-travado-fontes-locais-preload-font-display/</guid><description>Quando o maior elemento da tela é texto, o LCP espera a fonte chegar. Como fazer o texto pintar de imediato sem trocar LCP por deslocamento de layout.</description><pubDate>Sun, 26 Jul 2026 00:00:00 GMT</pubDate><category>Performance Web</category><category>core web vitals</category><category>lcp</category><category>cls</category><category>fontes</category><category>next.js</category><author>bruno@upgbp.com (Bruno Oliveira Rodrigues)</author></item><item><title>Supabase: porta 5432, 6543 ou conexão direta — qual usar</title><link>https://upgbp.com/artigos/supabase-pooler-porta-5432-6543-qual-usar/</link><guid isPermaLink="true">https://upgbp.com/artigos/supabase-pooler-porta-5432-6543-qual-usar/</guid><description>São três formas de conectar no mesmo banco, com limitações diferentes. Escolher errado gera erros que parecem de código e são de infraestrutura.

MaxClientsInSessionMode: max clients reached - in Session mode max clients are limited to pool_size</description><pubDate>Fri, 24 Jul 2026 00:00:00 GMT</pubDate><category>Dados &amp; Migrações</category><category>supabase</category><category>postgres</category><category>pooler</category><category>supavisor</category><category>serverless</category><author>bruno@upgbp.com (Bruno Oliveira Rodrigues)</author></item><item><title>Retry com backoff, jitter e circuit breaker em TypeScript</title><link>https://upgbp.com/artigos/retry-backoff-jitter-circuit-breaker-typescript/</link><guid isPermaLink="true">https://upgbp.com/artigos/retry-backoff-jitter-circuit-breaker-typescript/</guid><description>Repetir na hora piora a queda que você está tentando contornar. As quatro regras que separam um retry útil de um ataque contra o seu próprio fornecedor.

HTTP 503 Service Unavailable: upstream connect error or disconnect/reset before headers</description><pubDate>Wed, 22 Jul 2026 00:00:00 GMT</pubDate><category>APIs &amp; Resiliência</category><category>resiliência</category><category>retry</category><category>circuit breaker</category><category>typescript</category><category>fetch</category><author>bruno@upgbp.com (Bruno Oliveira Rodrigues)</author></item><item><title>INP acima de 200 ms: achando a long task que trava o clique</title><link>https://upgbp.com/artigos/inp-acima-de-200ms-cacando-long-tasks/</link><guid isPermaLink="true">https://upgbp.com/artigos/inp-acima-de-200ms-cacando-long-tasks/</guid><description>O INP mede o clique mais lento da sessão, não a média. Como achar exatamente qual interação e qual linha de código estão travando a thread principal.</description><pubDate>Sun, 19 Jul 2026 00:00:00 GMT</pubDate><category>Performance Web</category><category>core web vitals</category><category>inp</category><category>react</category><category>performance</category><category>next.js</category><author>bruno@upgbp.com (Bruno Oliveira Rodrigues)</author></item><item><title>prepared statement s0 already exists: por que o pooler quebra</title><link>https://upgbp.com/artigos/prepared-statement-s0-already-exists-pooler/</link><guid isPermaLink="true">https://upgbp.com/artigos/prepared-statement-s0-already-exists-pooler/</guid><description>O erro só aparece depois que você troca a conexão direta pelo pooler em modo transaction. A causa está em como o Postgres guarda statements preparados.

ERROR: prepared statement &quot;s0&quot; already exists (42P05)</description><pubDate>Fri, 17 Jul 2026 00:00:00 GMT</pubDate><category>Dados &amp; Migrações</category><category>postgres</category><category>pgbouncer</category><category>supabase</category><category>prisma</category><category>drizzle</category><author>bruno@upgbp.com (Bruno Oliveira Rodrigues)</author></item><item><title>FUNCTION_INVOCATION_TIMEOUT: quebrando trabalho longo em lotes</title><link>https://upgbp.com/artigos/function-invocation-timeout-vercel-trabalho-longo/</link><guid isPermaLink="true">https://upgbp.com/artigos/function-invocation-timeout-vercel-trabalho-longo/</guid><description>Aumentar o maxDuration só empurra a falha para um arquivo maior. A correção é a requisição iniciar o trabalho em vez de executá-lo até o fim.

504: GATEWAY_TIMEOUT Code: FUNCTION_INVOCATION_TIMEOUT</description><pubDate>Wed, 15 Jul 2026 00:00:00 GMT</pubDate><category>APIs &amp; Resiliência</category><category>vercel</category><category>serverless</category><category>background jobs</category><category>next.js</category><category>filas</category><author>bruno@upgbp.com (Bruno Oliveira Rodrigues)</author></item><item><title>O &apos;use client&apos; que dobrou o bundle: onde fica a fronteira</title><link>https://upgbp.com/artigos/use-client-que-dobrou-o-bundle-javascript/</link><guid isPermaLink="true">https://upgbp.com/artigos/use-client-que-dobrou-o-bundle-javascript/</guid><description>A diretiva não marca um arquivo, marca uma fronteira. Tudo que ela importa desce junto para o navegador — inclusive o que você jurava ser código de servidor.</description><pubDate>Sun, 12 Jul 2026 00:00:00 GMT</pubDate><category>Performance Web</category><category>next.js</category><category>react</category><category>bundle</category><category>server components</category><category>app router</category><author>bruno@upgbp.com (Bruno Oliveira Rodrigues)</author></item><item><title>Migrar do MongoDB para PostgreSQL sem perder os dados aninhados</title><link>https://upgbp.com/artigos/migrar-mongodb-para-postgresql-documentos-aninhados/</link><guid isPermaLink="true">https://upgbp.com/artigos/migrar-mongodb-para-postgresql-documentos-aninhados/</guid><description>Documentos com arrays e objetos embutidos não viram tabela por conversão automática. O critério para decidir o que vira tabela e o que vira jsonb.

ERROR: invalid input syntax for type uuid: &quot;{&quot;&quot;$oid&quot;&quot;:&quot;&quot;66f1a2b3c4d5e6f7a8b9c0d1&quot;&quot;}&quot;</description><pubDate>Fri, 10 Jul 2026 00:00:00 GMT</pubDate><category>Dados &amp; Migrações</category><category>mongodb</category><category>postgres</category><category>migração</category><category>jsonb</category><category>modelagem</category><author>bruno@upgbp.com (Bruno Oliveira Rodrigues)</author></item><item><title>Hydration mismatch no App Router: as 5 causas reais</title><link>https://upgbp.com/artigos/hydration-mismatch-app-router-cinco-causas/</link><guid isPermaLink="true">https://upgbp.com/artigos/hydration-mismatch-app-router-cinco-causas/</guid><description>O erro de hidratação do React quase sempre vem de uma destas cinco origens. Como identificar qual é a sua em minutos, em vez de tentar no escuro.

Hydration failed because the server rendered HTML didn&apos;t match the client.</description><pubDate>Wed, 08 Jul 2026 00:00:00 GMT</pubDate><category>Performance Web</category><category>next.js</category><category>react</category><category>hidratação</category><category>ssr</category><category>app router</category><author>bruno@upgbp.com (Bruno Oliveira Rodrigues)</author></item><item><title>Webhook executando duas vezes: como garantir idempotência</title><link>https://upgbp.com/artigos/webhook-executando-duas-vezes-idempotencia/</link><guid isPermaLink="true">https://upgbp.com/artigos/webhook-executando-duas-vezes-idempotencia/</guid><description>Todo provedor de webhook entrega pelo menos uma vez, o que significa às vezes duas. A trava que resolve é uma constraint de banco, não um if.

Webhook signature verification failed: No signatures found matching the expected signature for payload</description><pubDate>Sun, 05 Jul 2026 00:00:00 GMT</pubDate><category>APIs &amp; Resiliência</category><category>webhooks</category><category>stripe</category><category>idempotência</category><category>postgres</category><category>next.js</category><author>bruno@upgbp.com (Bruno Oliveira Rodrigues)</author></item><item><title>Prisma em serverless: resolvendo o timeout do connection pool</title><link>https://upgbp.com/artigos/prisma-connection-pool-timeout-serverless/</link><guid isPermaLink="true">https://upgbp.com/artigos/prisma-connection-pool-timeout-serverless/</guid><description>O pool do Prisma estoura quando cada função serverless abre o próprio conjunto de conexões. O diagnóstico completo e as três correções que aplicamos.

Timed out fetching a new connection from the connection pool. (Current connection pool timeout: 10, connection limit: 9)</description><pubDate>Fri, 03 Jul 2026 00:00:00 GMT</pubDate><category>Dados &amp; Migrações</category><category>prisma</category><category>postgres</category><category>supabase</category><category>serverless</category><category>connection pool</category><author>bruno@upgbp.com (Bruno Oliveira Rodrigues)</author></item><item><title>Por que este blog sobre Next.js roda em Astro</title><link>https://upgbp.com/artigos/por-que-este-blog-sobre-nextjs-roda-em-astro/</link><guid isPermaLink="true">https://upgbp.com/artigos/por-que-este-blog-sobre-nextjs-roda-em-astro/</guid><description>A escolha não foi ideológica: um site de conteúdo tem exigências diferentes das de um aplicativo. Os números deste site e onde o Next.js ganharia.</description><pubDate>Wed, 01 Jul 2026 00:00:00 GMT</pubDate><category>Performance Web</category><category>astro</category><category>next.js</category><category>core web vitals</category><category>ssg</category><category>arquitetura</category><author>bruno@upgbp.com (Bruno Oliveira Rodrigues)</author></item></channel></rss>