<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>produção Archives - Leonardo Nascimento | Engenheiro de Software</title>
	<atom:link href="https://leonardonascimento.dev/tag/producao/feed/" rel="self" type="application/rss+xml" />
	<link>https://leonardonascimento.dev/tag/producao/</link>
	<description>Especializado em backend, APIs e sistemas escaláveis. Experiência em arquitetura de sistemas, integrações, mensageria, performance e aplicações de alta disponibilidade.</description>
	<lastBuildDate>Thu, 29 Jan 2026 16:56:16 +0000</lastBuildDate>
	<language>pt-BR</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	

<image>
	<url>https://leonardonascimento.dev/wp-content/uploads/2021/05/cropped-programming-32x32.png</url>
	<title>produção Archives - Leonardo Nascimento | Engenheiro de Software</title>
	<link>https://leonardonascimento.dev/tag/producao/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Como monitorar aplicação e servidor pelo WhatsApp (logs, erros e alertas)</title>
		<link>https://leonardonascimento.dev/blog/como-monitorar-aplicacao-e-servidor-pelo-whatsapp-logs-erros-e-alertas/</link>
					<comments>https://leonardonascimento.dev/blog/como-monitorar-aplicacao-e-servidor-pelo-whatsapp-logs-erros-e-alertas/#respond</comments>
		
		<dc:creator><![CDATA[Leonardo]]></dc:creator>
		<pubDate>Thu, 29 Jan 2026 15:19:35 +0000</pubDate>
				<category><![CDATA[Arquitetura]]></category>
		<category><![CDATA[Backend]]></category>
		<category><![CDATA[Produção]]></category>
		<category><![CDATA[Programação]]></category>
		<category><![CDATA[Alertas]]></category>
		<category><![CDATA[logs]]></category>
		<category><![CDATA[monitoramento]]></category>
		<category><![CDATA[notifish]]></category>
		<category><![CDATA[produção]]></category>
		<category><![CDATA[WhatsApp]]></category>
		<guid isPermaLink="false">https://leonardonascimento.dev/?p=2290</guid>

					<description><![CDATA[<p>WhatsApp é um canal excelente para alerta porque ele tem uma característica que e-mail e dashboard não têm: chega onde você está. O problema é que a maioria das implementações vira bagunça rápido — alerta demais, duplicado, sem contexto, e em pouco tempo todo mundo ignora. A forma correta de fazer isso é tratar WhatsApp [&#8230;]</p>
<p>The post <a href="https://leonardonascimento.dev/blog/como-monitorar-aplicacao-e-servidor-pelo-whatsapp-logs-erros-e-alertas/">Como monitorar aplicação e servidor pelo WhatsApp (logs, erros e alertas)</a> appeared first on <a href="https://leonardonascimento.dev">Leonardo Nascimento | Engenheiro de Software</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>WhatsApp é um canal excelente para alerta porque ele tem uma característica que e-mail e dashboard não têm: <strong>chega onde você está</strong>. O problema é que a maioria das implementações vira bagunça rápido — alerta demais, duplicado, sem contexto, e em pouco tempo todo mundo ignora.</p>



<p>A forma correta de fazer isso é tratar WhatsApp como <strong><a href="https://leonardonascimento.dev/blog/updown-io-receba-notificacao-no-whatsapp-caso-seu-site-fique-indisponivel/" type="post" id="164">camada de notificação</a></strong>, não como sistema de monitoramento. Você continua monitorando com ferramentas e sinais confiáveis (uptime, métricas, logs, filas, erros), mas centraliza o envio e a governança dos alertas em um lugar só — e aí o <a href="http://notifish.com/" type="link" id="http://notifish.com/" target="_blank" rel="noreferrer noopener nofollow">Notifish </a>entra bem.</p>



<p>A ideia é simples: <strong>qualquer evento relevante → vira um “evento de notificação” → Notifish entrega no WhatsApp</strong>.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading" id="h-o-que-vale-a-pena-mandar-para-o-whatsapp-e-o-que-nao-vale">O que vale a pena mandar para o WhatsApp (e o que não vale)</h2>



<p>WhatsApp deve receber só o que exige ação ou atenção rápida. Em produção, eu separo em três níveis:</p>



<p><strong>Crítico (manda sempre):</strong></p>



<ul class="wp-block-list">
<li>aplicação fora do ar / endpoint crítico fora</li>



<li>erro 5xx em alta (explosão de taxa de erro)</li>



<li>fila parou de consumir / backlog crescendo rápido</li>



<li>disco quase cheio / risco de indisponibilidade</li>



<li>falha em integração crítica (pagamento, mensagens, etc.)</li>
</ul>



<p><strong>Alerta (manda com filtro):</strong></p>



<ul class="wp-block-list">
<li>latência acima do normal por X minutos</li>



<li>aumento gradual de erros específicos</li>



<li>Redis indisponível (com fallback) ou lento</li>



<li>uso de CPU/memória alto por período sustentado</li>
</ul>



<p><strong>Informativo (geralmente não manda no WhatsApp):</strong></p>



<ul class="wp-block-list">
<li>deploy realizado</li>



<li>logs de rotina</li>



<li>warnings esporádicos</li>
</ul>



<p>O que destrói o canal é “alerta informativo demais”. WhatsApp é para <strong>sinal forte</strong>.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading" id="h-arquitetura-recomendada-sem-gambiarra">Arquitetura recomendada (sem gambiarra)</h2>



<p>O melhor padrão é este:</p>



<ol class="wp-block-list">
<li>Você tem fontes de evento (monitoramento/observabilidade):</li>
</ol>



<ul class="wp-block-list">
<li>Uptime/health-check (aplicação)</li>



<li>Métricas do servidor (CPU, RAM, disco)</li>



<li>Logs (erros específicos, padrões)</li>



<li>Erros de aplicação (exceptions)</li>



<li>Filas (backlog, falhas, retries)</li>
</ul>



<ol start="2" class="wp-block-list">
<li>Um “gerador de eventos” cria um evento padronizado.</li>



<li>Você envia esse evento para o <a href="https://developers.notifish.com/" type="link" id="https://developers.notifish.com/" target="_blank" rel="noreferrer noopener nofollow"><strong>Notifish via API</strong>.</a></li>



<li>Você define roteamento, deduplicação e templates</li>
</ol>



<ul class="wp-block-list">
<li>para qual número/grupo enviar</li>



<li>se deve agrupar, deduplicar, aplicar rate limit</li>



<li>qual template usar (curto, completo, escalonamento)</li>
</ul>



<p>Esse desenho escala porque você não espalha envio de WhatsApp por todo sistema. Você centraliza.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading" id="h-como-fica-uma-mensagem-boa-no-whatsapp">Como fica uma mensagem boa no WhatsApp</h2>



<p>Uma mensagem útil precisa ter contexto mínimo e ação sugerida:</p>



<ul class="wp-block-list">
<li><strong>Título curto</strong> (o que aconteceu)</li>



<li><strong>Ambiente</strong> (prod, staging)</li>



<li><strong>Serviço</strong> (api, worker, site)</li>



<li><strong>Sintoma</strong> (erro, timeout, backlog)</li>



<li><strong>Impacto</strong> (estimado)</li>



<li><strong>Link</strong> (dashboard/logs, se existir)</li>



<li><strong>Ação recomendada</strong> (1 linha)</li>
</ul>



<p>Exemplo de payload humano:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p><strong>ALERTA CRÍTICO</strong>: API 5xx alto<br>Ambiente: prod | Serviço: api<br>Erros 5xx: 18% (últimos 5 min)<br>Endpoint: /api/orders<br>Ação: verificar logs + dependência “Payments”</p>
</blockquote>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading" id="h-implementacao-via-api-com-notifish-modelo-pratico">Implementação via API com Notifish (modelo prático)</h2>



<p>Você pode integrar de dois jeitos:</p>



<h3 class="wp-block-heading" id="h-1-seu-sistema-envia-eventos-diretamente-laravel-cron-scripts">1) Seu sistema envia eventos diretamente (Laravel, cron, scripts)</h3>



<p>Bom quando você mesmo detecta (fila, logs, métricas internas).</p>



<h3 class="wp-block-heading" id="h-2-ferramentas-externas-chamam-o-notifish-uptime-monitoramento">2) Ferramentas externas chamam o Notifish (uptime/monitoramento)</h3>



<p>Bom para health-check e métricas do servidor (quando a ferramenta já faz o “detector”).</p>



<p>Como você pediu implementação via API, vou te mostrar um modelo que funciona bem</p>



<h3 class="wp-block-heading" id="h-payload-recomendado-evento">Payload recomendado (evento)</h3>



<p></p>



<pre class="wp-block-preformatted">{<br>  "message": "Sua mensagem de alerta",<br>  "identifier": "seu identificador único de disparo",<br>  "link": true,<br>  "typing": "composing",<br>  "delayMessage": 1200<br>}<br></pre>



<p><strong>Por que esse formato funciona:</strong></p>



<ul class="wp-block-list">
<li><strong>identifier</strong>: chave de deduplicação / idempotência do alerta</li>



<li><strong>message</strong>: texto já formatado com contexto (ambiente/serviço/ação)</li>



<li><strong>delayMessage/typing</strong>: ajustes de entrega (opcionais)</li>
</ul>



<h2 class="wp-block-heading">Exemplo em Laravel enviando evento ao Notifish</h2>



<pre class="wp-block-preformatted">class NotifishClient
{
    public function sendToGroups(string $message, string $identifier, bool $link = true, int $delayMs = 0, string $typing = 'composing'): void
    {
        $url = rtrim(config('services.notifish.base_url'), '/')
            . '/api/v2/' . config('services.notifish.instance')
            . '/whatsapp/message/groups';

        $payload = [
            'message' => $message,
            'identifier' => $identifier,
            'link' => $link,
            'typing' => $typing,
            'delayMessage' => $delayMs,
        ];

        $response = Http::withToken(config('services.notifish.token'))
            ->acceptJson()
            ->contentType('application/json')
            ->timeout(8)
            ->post($url, $payload);

        if (!$response->successful()) {
            logger()->error('Notifish send failed', [
                'status' => $response->status(),
                'body' => $response->body(),
                'identifier' => $identifier,
            ]);
        }
    }
}

</pre>



<h2 class="wp-block-heading">Regras importantes para não virar caos</h2>



<p>Se você fizer só “manda mensagem”, em 2 semanas o canal morre. Algumas regras que eu considero obrigatórias:</p>



<p><strong>1) Deduplicação</strong></p>



<ul class="wp-block-list">
<li>Todo alerta precisa de <code>dedupe_key</code>.</li>



<li>Se o mesmo alerta acontecer 100 vezes, você manda 1 e “atualiza”/agrupa.</li>
</ul>



<p><strong>2) Rate limit por severidade</strong></p>



<ul class="wp-block-list">
<li>Crítico: pode repetir, mas com intervalo mínimo (ex.: 5–10 min).</li>



<li>Alerta: intervalo maior (ex.: 15–30 min).</li>



<li>Informativo: geralmente fora do WhatsApp.</li>
</ul>



<p><strong>3) Idempotência</strong></p>



<ul class="wp-block-list">
<li>Eventos iguais devem produzir o mesmo estado.</li>



<li>Se a chamada repetir, não deve disparar em duplicidade.</li>
</ul>



<p><strong>4) Conteúdo curto</strong><br>WhatsApp é leitura rápida. Se precisar detalhe, coloque em <code>meta</code> e mande link para logs/dashboard quando possível.</p>



<p><strong>5) Escalonamento</strong><br>Se continuar crítico por X tempo, notifica outro grupo/gestor.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">O que monitorar para disparar eventos úteis (fontes típicas)</h2>



<p>Você pode começar com estes gatilhos (são os que mais dão retorno):</p>



<ul class="wp-block-list">
<li><strong>Health-check HTTP</strong> (200/500, tempo de resposta, quedas)</li>



<li><strong>Taxa de erro</strong> (5xx e exceções por minuto)</li>



<li><strong>Fila</strong> (backlog, jobs failed, tempo médio)</li>



<li><strong>Banco</strong> (conexões, queries lentas, timeouts)</li>



<li><strong>Redis</strong> (latência, indisponibilidade, memória/eviction)</li>



<li><strong>Servidor</strong> (disco, load alto sustentado)</li>



<li><strong>Integrações externas</strong> (timeout e falha por janela)</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p>Monitorar “pelo WhatsApp” não é substituir observabilidade por chat. É transformar sinais importantes em alertas acionáveis, com governança. O Notifish entra como a peça que centraliza o envio e impede que cada sistema invente seu próprio jeito de notificar.</p>



<p>Se você faz dedupe, rate limit, severidade e contexto mínimo, o WhatsApp vira um canal confiável — e não um spam de produção.</p>
<p>The post <a href="https://leonardonascimento.dev/blog/como-monitorar-aplicacao-e-servidor-pelo-whatsapp-logs-erros-e-alertas/">Como monitorar aplicação e servidor pelo WhatsApp (logs, erros e alertas)</a> appeared first on <a href="https://leonardonascimento.dev">Leonardo Nascimento | Engenheiro de Software</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://leonardonascimento.dev/blog/como-monitorar-aplicacao-e-servidor-pelo-whatsapp-logs-erros-e-alertas/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Deployment de Laravel no Cloud com CI/CD (GitHub Actions e GitLab CI)</title>
		<link>https://leonardonascimento.dev/blog/deployment-de-laravel-no-cloud-com-ci-cd-github-actions-e-gitlab-ci/</link>
					<comments>https://leonardonascimento.dev/blog/deployment-de-laravel-no-cloud-com-ci-cd-github-actions-e-gitlab-ci/#respond</comments>
		
		<dc:creator><![CDATA[Leonardo]]></dc:creator>
		<pubDate>Tue, 13 Jan 2026 15:26:32 +0000</pubDate>
				<category><![CDATA[Arquitetura]]></category>
		<category><![CDATA[Backend]]></category>
		<category><![CDATA[Laravel]]></category>
		<category><![CDATA[Produção]]></category>
		<category><![CDATA[ci/cd]]></category>
		<category><![CDATA[cloud]]></category>
		<category><![CDATA[deployment]]></category>
		<category><![CDATA[devops]]></category>
		<category><![CDATA[laravel]]></category>
		<category><![CDATA[produção]]></category>
		<guid isPermaLink="false">https://leonardonascimento.dev/?p=2295</guid>

					<description><![CDATA[<p>Deploy manual funciona até o dia em que deixa de funcionar. Enquanto o projeto é pequeno e o time é reduzido, subir código via SSH, rodar alguns comandos e torcer para dar certo parece aceitável. Em projetos reais, com mais gente mexendo, deploy frequente e produção rodando 24/7, isso vira risco operacional. CI/CD não é [&#8230;]</p>
<p>The post <a href="https://leonardonascimento.dev/blog/deployment-de-laravel-no-cloud-com-ci-cd-github-actions-e-gitlab-ci/">Deployment de Laravel no Cloud com CI/CD (GitHub Actions e GitLab CI)</a> appeared first on <a href="https://leonardonascimento.dev">Leonardo Nascimento | Engenheiro de Software</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Deploy manual funciona até o dia em que deixa de funcionar. Enquanto o projeto é pequeno e o time é reduzido, subir código via SSH, rodar alguns comandos e torcer para dar certo parece aceitável. Em projetos reais, com mais gente mexendo, deploy frequente e produção rodando 24/7, isso vira risco operacional.</p>



<p>CI/CD não é sobre velocidade. É sobre <strong>previsibilidade, repetibilidade e segurança</strong> no processo de entrega.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading" id="h-o-que-ci-cd-realmente-resolve-em-projetos-laravel">O que CI/CD realmente resolve em projetos Laravel</h2>



<p>Em aplicações Laravel, o pipeline de deploy resolve três problemas clássicos:</p>



<ol class="wp-block-list">
<li><strong>Ambiente inconsistente</strong><br>O código roda local, mas quebra em produção porque algo foi esquecido ou executado fora de ordem.</li>



<li><strong>Deploys inseguros</strong><br>Código sobe sem testes, sem validação, sem rollback fácil.</li>



<li><strong>Processo dependente de pessoas</strong><br>“Só fulano sabe fazer deploy”. Quando ele não está, ninguém sobe nada.</li>
</ol>



<p>CI/CD elimina esses pontos ao transformar deploy em <strong>processo automatizado</strong>, não em ritual manual.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading" id="h-conceito-basico-do-pipeline-independente-da-ferramenta">Conceito básico do pipeline (independente da ferramenta)</h2>



<p>Antes de falar de GitHub Actions ou GitLab CI, é importante entender o fluxo lógico. Um pipeline de Laravel bem definido costuma ter estas etapas:</p>



<ol class="wp-block-list">
<li><strong>Checkout do código</strong></li>



<li><strong>Instalação de dependências</strong></li>



<li><strong>Execução de testes</strong></li>



<li><strong>Build (quando aplicável)</strong></li>



<li><strong>Deploy</strong></li>



<li><strong>Pós-deploy (migrations, cache, filas)</strong></li>
</ol>



<p>Se qualquer etapa falhar, o deploy <strong>não acontece</strong>. Isso é uma proteção, não um obstáculo.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading" id="h-estrutura-minima-de-um-deploy-laravel-saudavel">Estrutura mínima de um deploy Laravel saudável</h2>



<p>Independente de cloud ou CI, alguns princípios não mudam:</p>



<ul class="wp-block-list">
<li><code>composer install</code> sempre em modo produção</li>



<li><code>.env</code> nunca versionado</li>



<li><code>APP_ENV</code> e <code>APP_DEBUG</code> corretos</li>



<li>migrations rodando de forma controlada</li>



<li>cache/config/views limpos e recompilados</li>



<li>workers reiniciados corretamente</li>
</ul>



<p>Se isso não estiver automatizado, o risco é constante.</p>



<h2 class="wp-block-heading">Exemplo de pipeline com GitHub Actions</h2>



<p>Um pipeline simples, mas funcional, usando GitHub Actions:</p>



<pre class="wp-block-preformatted">name: Deploy Laravel<br><br>on:<br>  push:<br>    branches:<br>      - main<br><br>jobs:<br>  deploy:<br>    runs-on: ubuntu-latest<br><br>    steps:<br>      - name: Checkout<br>        uses: actions/checkout@v4<br><br>      - name: Setup PHP<br>        uses: shivammathur/setup-php@v2<br>        with:<br>          php-version: '8.2'<br>          extensions: mbstring, pdo, pdo_mysql<br><br>      - name: Install dependencies<br>        run: composer install --no-dev --optimize-autoloader<br><br>      - name: Run tests<br>        run: php artisan test<br><br>      - name: Deploy via SSH<br>        uses: appleboy/ssh-action@v1<br>        with:<br>          host: ${{ secrets.SERVER_HOST }}<br>          username: ${{ secrets.SERVER_USER }}<br>          key: ${{ secrets.SERVER_SSH_KEY }}<br>          script: |<br>            cd /var/www/app<br>            git pull origin main<br>            composer install --no-dev --optimize-autoloader<br>            php artisan migrate --force<br>            php artisan optimize<br>            php artisan queue:restart</pre>



<h2 class="wp-block-heading">Onde muita gente erra no deploy de Laravel</h2>



<h3 class="wp-block-heading">Rodar migration sem pensar em impacto</h3>



<p>Migration em produção pode travar tabela, gerar lentidão ou indisponibilidade. CI/CD não elimina isso. Ele apenas automatiza. Migration precisa ser escrita com consciência de produção.</p>



<h3 class="wp-block-heading">Cache mal tratado</h3>



<p>Não limpar/recriar cache de config e routes gera bugs difíceis de explicar. Cache antigo em produção é clássico.</p>



<h3 class="wp-block-heading">Workers esquecidos</h3>



<p>Deploy sobe código novo, mas workers continuam rodando código antigo. Resultado: comportamento inconsistente.</p>



<h3 class="wp-block-heading">Falta de rollback</h3>



<p>CI/CD sem rollback é metade da solução. Mesmo que seja manual, precisa existir um caminho claro para voltar.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">Estratégia simples de rollback</h2>



<p>Mesmo sem blue/green ou canary, dá para ter rollback básico:</p>



<ul class="wp-block-list">
<li>manter tags ou releases</li>



<li>usar <code>git checkout</code> para versão anterior</li>



<li>rodar <code>php artisan migrate:rollback</code> quando aplicável</li>



<li>reiniciar workers</li>
</ul>



<p>O importante é <strong>ter plano</strong>. Não improvisar sob pressão.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">CI/CD não substitui observabilidade</h2>



<p>Deploy automatizado reduz erro humano, mas não impede bugs. Por isso, CI/CD precisa andar junto com:</p>



<ul class="wp-block-list">
<li>monitoramento de erros</li>



<li>alertas pós-deploy</li>



<li>logs estruturados</li>



<li>métricas de saúde</li>
</ul>



<p>Deploy sem visibilidade é só um erro mais rápido.</p>



<p>CI/CD em projetos Laravel não é luxo nem modinha. É uma camada básica de segurança operacional. Ele garante que o código passe sempre pelo mesmo caminho, reduz risco humano e cria previsibilidade no processo de entrega.</p>



<p>Quando o deploy deixa de ser um evento tenso e vira algo rotineiro, o time ganha confiança para evoluir o sistema. E isso, no fim, é o que permite crescer sem quebrar tudo a cada release.</p>
<p>The post <a href="https://leonardonascimento.dev/blog/deployment-de-laravel-no-cloud-com-ci-cd-github-actions-e-gitlab-ci/">Deployment de Laravel no Cloud com CI/CD (GitHub Actions e GitLab CI)</a> appeared first on <a href="https://leonardonascimento.dev">Leonardo Nascimento | Engenheiro de Software</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://leonardonascimento.dev/blog/deployment-de-laravel-no-cloud-com-ci-cd-github-actions-e-gitlab-ci/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Rate limiting em APIs: por que é obrigatório em produção</title>
		<link>https://leonardonascimento.dev/blog/rate-limiting-em-apis-por-que-e-obrigatorio-em-producao/</link>
					<comments>https://leonardonascimento.dev/blog/rate-limiting-em-apis-por-que-e-obrigatorio-em-producao/#respond</comments>
		
		<dc:creator><![CDATA[Leonardo]]></dc:creator>
		<pubDate>Mon, 12 Jan 2026 14:55:11 +0000</pubDate>
				<category><![CDATA[Arquitetura]]></category>
		<category><![CDATA[Backend]]></category>
		<category><![CDATA[apis]]></category>
		<category><![CDATA[backend]]></category>
		<category><![CDATA[escalabilidade]]></category>
		<category><![CDATA[produção]]></category>
		<category><![CDATA[rate limiting]]></category>
		<category><![CDATA[segurança]]></category>
		<guid isPermaLink="false">https://leonardonascimento.dev/?p=2285</guid>

					<description><![CDATA[<p>Rate limiting quase sempre entra na conversa tarde demais. Normalmente depois do primeiro pico inesperado, de uma integração mal-comportada ou de um endpoint que começa a consumir recursos de forma descontrolada. Em ambiente local, nada disso aparece. Em produção, aparece rápido. API sem rate limiting não é API aberta. É API frágil. Em produção, você [&#8230;]</p>
<p>The post <a href="https://leonardonascimento.dev/blog/rate-limiting-em-apis-por-que-e-obrigatorio-em-producao/">Rate limiting em APIs: por que é obrigatório em produção</a> appeared first on <a href="https://leonardonascimento.dev">Leonardo Nascimento | Engenheiro de Software</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p><a href="https://leonardonascimento.dev/tag/api/" type="post_tag" id="210">Rate limiting</a> quase sempre entra na conversa tarde demais. Normalmente depois do primeiro pico inesperado, de uma integração mal-comportada ou de um endpoint que começa a consumir recursos de forma descontrolada. Em ambiente local, nada disso aparece. Em produção, aparece rápido.</p>



<p><a href="https://leonardonascimento.dev/blog/erros-comuns-em-apis-que-causam-problemas-em-producao/" type="post" id="2248">API sem rate limiting não é API aberta. É API frágil.</a></p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p>Em produção, você não controla quem consome sua API nem como ela será usada. Mesmo quando o consumidor é “conhecido”, basta um loop mal implementado, um retry agressivo ou um bug simples para gerar milhares de requisições em poucos segundos. Sem limitação, a aplicação tenta atender tudo ao mesmo tempo e começa a degradar de forma silenciosa até parar.</p>



<p>Rate limiting não existe para punir usuários. Ele existe para <strong>proteger o sistema</strong>.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p>O primeiro ponto é <strong>estabilidade</strong>. Uma API precisa continuar respondendo mesmo sob carga anormal. Quando não há limite, uma única origem pode consumir CPU, conexões e threads a ponto de afetar todos os outros consumidores. Com rate limiting, você isola impacto: quem exagera sofre limitação, quem usa corretamente continua funcionando.</p>



<p>Em outras palavras, rate limiting é um mecanismo de contenção de danos.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p>Outro aspecto importante é <strong>previsibilidade</strong>. Em produção, você precisa saber até onde o sistema aguenta. Sem limites, o comportamento sob estresse é imprevisível: timeouts aleatórios, filas acumulando, banco sobrecarregado. Com rate limiting, o sistema passa a falhar de forma controlada, retornando erro claro e mantendo o restante da aplicação saudável.</p>



<p>Falhar rápido e de forma explícita é muito melhor do que degradar tudo lentamente.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p>Rate limiting também é uma <strong>camada básica de segurança</strong>. Não substitui autenticação nem autorização, mas reduz muito a superfície de ataque. Tentativas de força bruta, scraping agressivo e abusos simples ficam automaticamente limitados. Mesmo ataques não intencionais, como integrações mal configuradas, deixam de causar impacto sistêmico.</p>



<p>Segurança em produção não é só impedir acesso indevido, é impedir uso destrutivo.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p>Em APIs que lidam com <strong><a href="https://leonardonascimento.dev/blog/boas-praticas-para-estruturar-projetos-em-laravel-de-medio-e-grande-porte/" type="post" id="2262">integrações externas</a></strong>, rate limiting se torna ainda mais crítico. Muitas integrações fazem retry automático quando recebem erro ou timeout. Sem limite, isso vira efeito cascata: o sistema fica lento, responde pior, recebe mais retries e entra em colapso. Limitar requisições ajuda a quebrar esse ciclo e manter o sistema respirando.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p>Existe também o aspecto de <strong>justiça entre consumidores</strong>. Em APIs públicas ou compartilhadas, sem rate limiting um consumidor pode consumir recursos de forma desproporcional. Com limites bem definidos, você garante que ninguém monopolize a capacidade do sistema. Isso é especialmente importante quando existem planos, SLAs ou diferentes níveis de acesso.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p>Um erro comum é pensar que rate limiting só serve para APIs públicas. Isso não é verdade. APIs internas, usadas por múltiplos serviços ou múltiplos clientes, também precisam de limite. Em produção, erros internos são tão perigosos quanto abusos externos.</p>



<p>Outro erro frequente é implementar rate limiting apenas no gateway ou apenas na aplicação, sem pensar no conjunto. Em sistemas maiores, o ideal é ter defesa em camadas: alguma limitação na borda e alguma consciência de limite dentro da aplicação.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p>Rate limiting também ajuda na <strong>observabilidade</strong>. Quando bem configurado, ele vira sinal. Se muitos consumidores começam a bater no limite, isso indica mudança de comportamento, bug novo ou crescimento não previsto. Ignorar esses sinais é perder uma oportunidade de agir antes do problema escalar.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p>Vale reforçar: rate limiting não deve ser arbitrário. Limites precisam fazer sentido para o tipo de operação, o perfil de uso e a capacidade do sistema. Endpoints críticos e pesados precisam de limites mais restritos do que endpoints simples. Ajustar isso faz parte do amadurecimento da API.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading" id="h-conclusao">Conclusão</h2>



<p>Rate limiting não é detalhe, não é “nice to have” e não é algo que se adiciona depois. Em produção, ele é requisito básico de estabilidade, segurança e previsibilidade. APIs que não limitam uso estão sempre a um passo de um incidente difícil de explicar e mais difícil de corrigir.</p>



<p>Quem projeta APIs pensando em produção entende que proteger o sistema é tão importante quanto fazê-lo funcionar.</p>
<p>The post <a href="https://leonardonascimento.dev/blog/rate-limiting-em-apis-por-que-e-obrigatorio-em-producao/">Rate limiting em APIs: por que é obrigatório em produção</a> appeared first on <a href="https://leonardonascimento.dev">Leonardo Nascimento | Engenheiro de Software</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://leonardonascimento.dev/blog/rate-limiting-em-apis-por-que-e-obrigatorio-em-producao/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Erros comuns ao usar Redis em aplicações Laravel</title>
		<link>https://leonardonascimento.dev/blog/erros-comuns-ao-usar-redis-em-aplicacoes-laravel/</link>
					<comments>https://leonardonascimento.dev/blog/erros-comuns-ao-usar-redis-em-aplicacoes-laravel/#respond</comments>
		
		<dc:creator><![CDATA[Leonardo]]></dc:creator>
		<pubDate>Sun, 11 Jan 2026 10:47:00 +0000</pubDate>
				<category><![CDATA[Arquitetura]]></category>
		<category><![CDATA[Backend]]></category>
		<category><![CDATA[Laravel]]></category>
		<category><![CDATA[cache]]></category>
		<category><![CDATA[concorrência]]></category>
		<category><![CDATA[laravel]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[produção]]></category>
		<category><![CDATA[redis]]></category>
		<guid isPermaLink="false">https://leonardonascimento.dev/?p=2282</guid>

					<description><![CDATA[<p>Redis costuma entrar no projeto como sinônimo de performance. E, de fato, quando bem usado, ele resolve muita coisa. O problema é que em aplicações Laravel — principalmente quando começam a crescer — Redis também vira fonte de bugs difíceis, inconsistências e comportamentos estranhos quando é usado sem critério. A maioria desses problemas não vem [&#8230;]</p>
<p>The post <a href="https://leonardonascimento.dev/blog/erros-comuns-ao-usar-redis-em-aplicacoes-laravel/">Erros comuns ao usar Redis em aplicações Laravel</a> appeared first on <a href="https://leonardonascimento.dev">Leonardo Nascimento | Engenheiro de Software</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Redis costuma entrar no projeto como sinônimo de <a href="https://leonardonascimento.dev/tag/performance/" type="post_tag" id="209">performance</a>. E, de fato, quando bem usado, ele resolve muita coisa. O problema é que em aplicações Laravel — principalmente quando começam a crescer — Redis também vira fonte de bugs difíceis, inconsistências e comportamentos estranhos quando é usado sem critério.</p>



<p>A maioria desses problemas não vem do Redis em si, mas da forma como ele é integrado à aplicação. A seguir estão erros que aparecem com frequência em produção e o que aprender com eles.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p>Um dos erros mais comuns é <strong>tratar Redis como banco de dados principal</strong>. Redis é rápido, mas não é fonte de verdade. Dados em memória podem ser perdidos por restart, eviction ou falha de infraestrutura. Quando o sistema depende do Redis para manter estado crítico, qualquer limpeza vira incidente. Em aplicações maduras, Redis é sempre camada auxiliar; o banco relacional continua sendo a referência.</p>



<p>Outro problema recorrente é <strong><a href="https://leonardonascimento.dev/blog/quando-usar-cache-e-quando-ele-so-complica-o-sistema/" type="post" id="2251">cachear dados sem estratégia clara de invalidação</a></strong>. No começo, tudo parece funcionar: menos queries, respostas mais rápidas. Com o tempo, começam a aparecer dados desatualizados, comportamentos inconsistentes e bugs que “somem sozinhos”. Cache sem invalidação bem definida vira dívida técnica. Toda entrada em cache precisa ter resposta clara para três perguntas: quando expira, quem invalida e o que acontece se falhar.</p>



<p>Também é comum <strong>usar TTL genérico para tudo</strong>. Definir o mesmo tempo de expiração para dados completamente diferentes ignora o contexto. Dados quase estáticos podem ficar horas em cache; dados sensíveis a mudanças podem precisar de expiração curta ou invalidação ativa. TTL não é detalhe de configuração, é parte da regra de negócio.</p>



<p>Em projetos com filas e jobs, aparece bastante o erro de <strong>usar Redis sem pensar em concorrência</strong>. Dois workers acessando e alterando a mesma chave ao mesmo tempo geram condição de corrida. Incrementos, flags e estados intermediários precisam ser atômicos ou protegidos por lock. Ignorar isso funciona em teste, mas quebra sob carga.</p>



<p>Outro ponto crítico é <strong>usar Redis como solução para idempotência sem persistência complementar</strong>. Locks e flags em Redis ajudam, mas não garantem segurança total. Se o Redis reiniciar, o controle some. Para efeitos colaterais críticos (pagamento, notificação, integração externa), o controle final precisa estar no banco, com constraint ou registro explícito de processamento.</p>



<p>Muitos projetos também caem no erro de <strong>não separar namespaces ou prefixos de chave</strong>. Em aplicações maiores, isso gera colisão, dificuldade de debug e limpeza perigosa. Padronizar prefixos por domínio ou tipo de dado facilita manutenção e evita apagar cache errado.</p>



<p>Há ainda o uso excessivo de Redis para <strong>resolver problemas que não são de cache</strong>. Guardar lógica de negócio, estados complexos ou fluxos longos em memória costuma deixar o sistema frágil. Redis é ótimo para acelerar acesso, coordenar concorrência e compartilhar estado temporário, mas não substitui modelagem correta.</p>



<p>Outro erro que só aparece em produção é <strong>ignorar política de eviction e limites de memória</strong>. Quando a memória acaba, o Redis começa a remover chaves de acordo com a política configurada. Se isso não foi considerado no design, o sistema passa a perder cache crítico aleatoriamente, causando degradação inesperada. Monitorar uso de memória e entender eviction é obrigatório.</p>



<p>Também é comum <strong>não monitorar Redis como dependência crítica</strong>. Quando ele fica lento ou indisponível, a aplicação sofre. Sem métricas, alertas e logs específicos, o diagnóstico demora. Redis precisa estar no radar de observabilidade tanto quanto banco e API externa.</p>



<p>Por fim, um erro sutil: <strong>acoplar demais o código ao Redis</strong>. Quando a aplicação assume que Redis sempre está disponível, qualquer fallback vira difícil. Código mais saudável trata Redis como otimização opcional: se falhar, o sistema continua funcionando, mesmo que mais lento.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p>Redis é uma ferramenta poderosa, mas exige disciplina. <a href="https://leonardonascimento.dev/categoria/laravel/" type="category" id="44">Em aplicações Laravel</a>, ele deve acelerar, proteger e coordenar — nunca sustentar a lógica principal do sistema. Quando tratado como camada auxiliar, com invalidação clara, controle de concorrência e observabilidade, ele entrega o que promete. Quando usado como atalho, cobra o preço em produção.</p>
<p>The post <a href="https://leonardonascimento.dev/blog/erros-comuns-ao-usar-redis-em-aplicacoes-laravel/">Erros comuns ao usar Redis em aplicações Laravel</a> appeared first on <a href="https://leonardonascimento.dev">Leonardo Nascimento | Engenheiro de Software</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://leonardonascimento.dev/blog/erros-comuns-ao-usar-redis-em-aplicacoes-laravel/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Na minha máquina funciona. Vamos levar sua máquina para o usuário então</title>
		<link>https://leonardonascimento.dev/blog/na-minha-maquina-funciona-vamos-levar-sua-maquina-para-o-usuario-entao/</link>
					<comments>https://leonardonascimento.dev/blog/na-minha-maquina-funciona-vamos-levar-sua-maquina-para-o-usuario-entao/#respond</comments>
		
		<dc:creator><![CDATA[Leonardo]]></dc:creator>
		<pubDate>Sat, 10 Jan 2026 21:35:00 +0000</pubDate>
				<category><![CDATA[Arquitetura]]></category>
		<category><![CDATA[Produção]]></category>
		<category><![CDATA[Programação]]></category>
		<category><![CDATA[ambiente de produção]]></category>
		<category><![CDATA[backend]]></category>
		<category><![CDATA[boas práticas]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[produção]]></category>
		<guid isPermaLink="false">https://leonardonascimento.dev/?p=2277</guid>

					<description><![CDATA[<p>Todo desenvolvedor já disse ou ouviu essa frase: “Na minha máquina funciona”. Em ambiente local, com poucos dados, sem concorrência real e sem dependências instáveis, quase tudo funciona. O problema é que produção não tem nada a ver com o seu computador. Quando alguém usa “funciona local” como argumento técnico, geralmente está ignorando o contexto [&#8230;]</p>
<p>The post <a href="https://leonardonascimento.dev/blog/na-minha-maquina-funciona-vamos-levar-sua-maquina-para-o-usuario-entao/">Na minha máquina funciona. Vamos levar sua máquina para o usuário então</a> appeared first on <a href="https://leonardonascimento.dev">Leonardo Nascimento | Engenheiro de Software</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Todo desenvolvedor já disse ou ouviu essa frase: <em>“Na minha máquina funciona”</em>. Em ambiente local, com poucos dados, sem concorrência real e sem dependências instáveis, quase tudo funciona. O problema é que <strong>produção não tem nada a ver com o seu computador</strong>.</p>



<p>Quando alguém usa “funciona local” como argumento técnico, geralmente está ignorando o contexto em que o sistema realmente vai operar. E é exatamente aí que os problemas começam.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p>Em local, você tem controle total. O banco está limpo, a latência é praticamente zero, não existem requisições concorrentes, não há retries, não há jobs acumulados, não há serviços externos oscilando. Você executa uma ação, olha o resultado e segue em frente. É um ambiente artificialmente perfeito.</p>



<p>Produção é o oposto disso.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p>A primeira diferença aparece com <strong>concorrência</strong>. Localmente, você clica uma vez. Em produção, dezenas ou centenas de usuários fazem a mesma ação ao mesmo tempo. Jobs rodam em paralelo. Requests competem por recursos. Código que nunca apresentou problema começa a gerar condição de corrida, duplicidade de execução e dados inconsistentes. Nada disso aparece no teste local simples.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p>Outra diferença crítica é <strong>latência</strong>. Em local, chamadas HTTP e queries são praticamente instantâneas. Em produção, uma API externa pode demorar segundos para responder, ou responder de forma intermitente. Um banco pode ficar lento sob carga. Um cache pode expirar no pior momento. Código que assume resposta imediata funciona local, mas degrada ou trava em produção.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p>Existe também a questão do <strong>volume de dados</strong>. Local costuma ter poucos registros. Produção tem milhares ou milhões. Queries que pareciam inofensivas passam a consumir tempo e recursos. Loops simples viram gargalo. Processamentos que eram aceitáveis começam a estourar timeout. O problema não é o código “errado”, é o código <strong>não preparado para escala</strong>.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p>Dependências externas são outro ponto ignorado em ambiente local. Muitas vezes você testa com mock, sandbox ou serviço estável. Em produção, serviços externos falham, ficam lentos ou retornam dados inesperados. Se o sistema não foi desenhado para lidar com isso, o erro externo vira indisponibilidade interna.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p>Local também não expõe problemas de <strong>observabilidade</strong>. Em produção, quando algo dá errado, você precisa responder rápido: o que aconteceu, quando, com qual dado, em qual fluxo. Código que “funciona local” mas não gera logs úteis transforma qualquer incidente em uma investigação longa e cara.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p>Outro ponto comum é <strong>configuração e ambiente</strong>. Local costuma ter permissões amplas, cache limpo, variáveis simples. Produção tem múltiplos ambientes, secrets, variáveis diferentes, limites de recurso e regras de segurança. Código que assume configuração fixa funciona local e quebra fora dele.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p>Existe ainda o fator <strong>tempo</strong>. Local você testa agora. Produção roda por semanas ou meses. Vazamentos de memória, acúmulo de jobs, crescimento de filas e degradação progressiva só aparecem com o tempo. “Funciona local” raramente considera isso.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p>Nada disso significa que testar local não importa. Significa que <strong>teste local valida comportamento</strong>, não valida operação. Ele é necessário, mas está longe de ser suficiente.</p>



<p>Código pronto para produção é aquele que:</p>



<ul class="wp-block-list">
<li>lida bem com concorrência</li>



<li>assume latência e falha</li>



<li>escala com dados reais</li>



<li>é observável</li>



<li>se comporta de forma previsível sob estresse</li>
</ul>



<p>Sem isso, o “funciona local” vira apenas uma falsa sensação de segurança.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p>“Funciona local” não é critério de qualidade. É apenas o primeiro degrau. Produção cobra decisões que local nunca vai cobrar: resiliência, previsibilidade e responsabilidade técnica.</p>



<p>Quando alguém entende isso, muda a forma de escrever código. Quando não entende, continua apagando incêndio e se perguntando por que algo que “funcionava perfeitamente” começou a falhar sem explicação.</p>
<p>The post <a href="https://leonardonascimento.dev/blog/na-minha-maquina-funciona-vamos-levar-sua-maquina-para-o-usuario-entao/">Na minha máquina funciona. Vamos levar sua máquina para o usuário então</a> appeared first on <a href="https://leonardonascimento.dev">Leonardo Nascimento | Engenheiro de Software</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://leonardonascimento.dev/blog/na-minha-maquina-funciona-vamos-levar-sua-maquina-para-o-usuario-entao/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Laravel: Jobs, filas e processamento assíncrono: quando usar e quando evitar</title>
		<link>https://leonardonascimento.dev/blog/laravel-jobs-filas-e-processamento-assincrono-quando-usar-e-quando-evitar/</link>
					<comments>https://leonardonascimento.dev/blog/laravel-jobs-filas-e-processamento-assincrono-quando-usar-e-quando-evitar/#respond</comments>
		
		<dc:creator><![CDATA[Leonardo]]></dc:creator>
		<pubDate>Thu, 08 Jan 2026 14:22:46 +0000</pubDate>
				<category><![CDATA[Arquitetura]]></category>
		<category><![CDATA[Backend]]></category>
		<category><![CDATA[Laravel]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programação]]></category>
		<category><![CDATA[filas]]></category>
		<category><![CDATA[jobs]]></category>
		<category><![CDATA[mensageria]]></category>
		<category><![CDATA[processamento assíncrono]]></category>
		<category><![CDATA[produção]]></category>
		<category><![CDATA[redis]]></category>
		<guid isPermaLink="false">https://leonardonascimento.dev/?p=2271</guid>

					<description><![CDATA[<p>Fila resolve dor real: tirar do request o que não precisa estar ali. O problema é que muita gente usa fila como “remédio genérico” e acaba criando um sistema mais frágil, mais difícil de depurar e com risco de duplicidade. Jobs e processamento assíncrono são excelentes quando usados com critério. Quando usados por impulso, viram [&#8230;]</p>
<p>The post <a href="https://leonardonascimento.dev/blog/laravel-jobs-filas-e-processamento-assincrono-quando-usar-e-quando-evitar/">Laravel: Jobs, filas e processamento assíncrono: quando usar e quando evitar</a> appeared first on <a href="https://leonardonascimento.dev">Leonardo Nascimento | Engenheiro de Software</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Fila resolve dor real: tirar do request o que não precisa estar ali. O problema é que muita gente usa fila como “remédio genérico” e acaba criando um sistema mais frágil, mais difícil de depurar e com risco de duplicidade.</p>



<p><a href="https://leonardonascimento.dev/categoria/laravel/" type="category" id="44">Jobs e processamento</a> assíncrono são excelentes quando usados com critério. Quando usados por impulso, viram fonte de incidentes.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">O que fila realmente te dá (e o que ela não dá)</h2>



<p>Fila te dá principalmente três coisas: desacoplamento do tempo de resposta, capacidade de absorver picos e reprocessamento controlado. Ela não te dá garantia de que algo vai rodar uma vez só, nem te livra de tratar falhas externas. Na verdade, ela te obriga a tratar isso.</p>



<p>Se você joga um processo para a fila sem pensar em idempotência, retries e observabilidade, você só mudou o problema de lugar.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">Quando usar jobs e filas</h2>



<h3 class="wp-block-heading">1) Tudo que não precisa bloquear o usuário</h3>



<p>Se o usuário não precisa do resultado imediato, isso já é um sinal forte de fila.</p>



<p>Exemplos comuns:</p>



<ul class="wp-block-list">
<li>envio de e-mail e notificações</li>



<li>geração de relatórios</li>



<li>criação de thumbnails / processamento de mídia</li>



<li>sincronização com sistemas externos</li>



<li>webhooks de saída (enviar eventos para terceiros)</li>
</ul>



<p>A regra prática: se o usuário já pode seguir o fluxo sem esperar, tire do request.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">2) Integrações externas e chamadas instáveis</h3>



<p><a href="https://leonardonascimento.dev/tag/api/" type="post_tag" id="210">API de terceiros falha</a>, oscila, responde lento. Fila é ótima para isso porque permite retries e isolamento.</p>



<p>Exemplos:</p>



<ul class="wp-block-list">
<li>gateway de pagamento</li>



<li>WhatsApp / SMS</li>



<li>ERP e sistemas legados</li>



<li>qualquer HTTP externo</li>
</ul>



<p>Mas aqui entra o ponto crítico: fila não é desculpa para “tentar infinitamente”. Você precisa controlar tentativas e saber quando desistir.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">3) Processamentos pesados e previsíveis</h3>



<p><a href="https://leonardonascimento.dev/blog/boas-praticas-para-estruturar-projetos-em-laravel-de-medio-e-grande-porte/" type="post" id="2262">Tudo que consome</a> CPU, memória ou I/O e pode gerar timeout em request tende a ser melhor em job.</p>



<p>Exemplos:</p>



<ul class="wp-block-list">
<li>exportar CSV grande</li>



<li>processar lote de dados</li>



<li>recalcular agregações</li>



<li>rodar rotinas de normalização/validação em massa</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">4) Fan-out (um evento dispara várias ações)</h3>



<p>Quando algo acontece e você precisa executar várias tarefas em sequência ou em paralelo, jobs ajudam a manter o sistema organizado.</p>



<p>Exemplo: “pedido pago” dispara:</p>



<ul class="wp-block-list">
<li>enviar confirmação</li>



<li>baixar estoque</li>



<li>emitir nota</li>



<li>notificar financeiro</li>



<li>gerar registro no CRM</li>
</ul>



<p>Se você faz tudo no request, vira um fluxo pesado e frágil. Com jobs, você separa responsabilidades.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">5) Absorver picos sem derrubar o sistema</h3>



<p>Fila é uma forma de “buffer”. Em vez de o sistema tentar processar tudo na hora e morrer, você coloca em fila e processa no ritmo que aguenta.</p>



<p>Isso é útil quando:</p>



<ul class="wp-block-list">
<li>picos são comuns</li>



<li>demanda varia muito</li>



<li>você precisa garantir estabilidade</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">Quando evitar jobs e filas</h2>



<h3 class="wp-block-heading">1) Quando você precisa de resposta imediata e consistente</h3>



<p>Se o usuário precisa saber na hora se deu certo, jogar em fila pode piorar a experiência.</p>



<p>Exemplos:</p>



<ul class="wp-block-list">
<li>login</li>



<li>criar pagamento e retornar confirmação</li>



<li>reservar algo que não pode duplicar</li>



<li>operações transacionais críticas</li>
</ul>



<p>Você até pode usar job para efeitos colaterais, mas a decisão central precisa ser síncrona.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">2) Quando a operação é simples e rápida</h3>



<p>Às vezes a operação leva 20ms e você coloca na fila “por padrão”. Isso adiciona:</p>



<ul class="wp-block-list">
<li>complexidade</li>



<li>delay</li>



<li>necessidade de monitoramento</li>



<li>risco de falha assíncrona</li>
</ul>



<p>Fila não pode ser usada como padrão para tudo. Senão você cria um sistema cheio de jobs pequenos e difíceis de rastrear.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">3) Quando você não tem observabilidade</h3>



<p>Fila sem visibilidade vira caixa-preta.</p>



<p>Se você não tem:</p>



<ul class="wp-block-list">
<li>logs por job</li>



<li>métricas de falha</li>



<li>alertas de backlog</li>



<li>dead-letter ou estratégia de falha</li>
</ul>



<p>você vai descobrir problemas tarde demais. Nesse cenário, manter síncrono pode ser mais seguro até organizar a casa.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">4) Quando você não consegue garantir idempotência</h3>



<p>Jobs podem rodar duas vezes. Isso é normal: retry, timeouts, quedas de worker, reentregas. Se o job não é idempotente, você corre risco de:</p>



<ul class="wp-block-list">
<li>cobrança duplicada</li>



<li>disparo duplicado</li>



<li>registro duplicado</li>



<li>integração duplicada</li>
</ul>



<p>Se não dá para tornar idempotente, trate o caso com mais cuidado. Às vezes o certo é manter a operação central síncrona e colocar apenas efeitos colaterais na fila.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">O ponto que derruba sistemas: duplicidade</h2>



<p>Em produção, o seu job vai rodar duas vezes em algum momento. Não é “se”, é “quando”. Por isso, projetos maduros tratam idempotência como requisito.</p>



<p>Algumas abordagens comuns:</p>



<ul class="wp-block-list">
<li>chave idempotente por evento (event_id / request_id)</li>



<li>lock distribuído (Redis)</li>



<li>uniqueness controlada (Laravel unique jobs quando aplicável)</li>



<li>constraints no banco (único onde fizer sentido)</li>
</ul>



<p>Não é uma bala de prata, mas é obrigatório ter uma estratégia.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">Filas também precisam de limites</h2>



<p>Jobs não podem tentar para sempre. Você precisa definir:</p>



<ul class="wp-block-list">
<li>número de tentativas</li>



<li>backoff entre tentativas</li>



<li>timeout</li>



<li>comportamento ao falhar (alerta, dead letter, reprocessamento manual)</li>
</ul>



<p>E precisa aceitar que algumas coisas falham. O sistema não pode entrar em loop eterno tentando recuperar erro externo.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">Sinais de que você deve ir para fila</h2>



<p>Se você está em dúvida, aqui vão sinais bem práticos:</p>



<ul class="wp-block-list">
<li>requests começando a estourar timeout</li>



<li>picos derrubando a API</li>



<li>integrações externas travando fluxos principais</li>



<li>usuários esperando por coisas que não precisam esperar</li>



<li>o mesmo fluxo acumulando responsabilidades demais</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p>Jobs e filas são uma das melhores ferramentas para dar escala e estabilidade em sistemas Laravel, mas elas exigem maturidade. Quando bem usadas, melhoram performance, isolam falhas e deixam o sistema mais previsível. Quando usadas sem critério, viram um sistema difícil de operar, cheio de jobs duplicados e incidentes intermitentes.</p>



<p>Fila não é atalho. É arquitetura.</p>
<p>The post <a href="https://leonardonascimento.dev/blog/laravel-jobs-filas-e-processamento-assincrono-quando-usar-e-quando-evitar/">Laravel: Jobs, filas e processamento assíncrono: quando usar e quando evitar</a> appeared first on <a href="https://leonardonascimento.dev">Leonardo Nascimento | Engenheiro de Software</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://leonardonascimento.dev/blog/laravel-jobs-filas-e-processamento-assincrono-quando-usar-e-quando-evitar/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Erros que já cometi em produção (e o que aprendi com eles)</title>
		<link>https://leonardonascimento.dev/blog/erros-que-ja-cometi-em-producao-e-o-que-aprendi-com-eles/</link>
					<comments>https://leonardonascimento.dev/blog/erros-que-ja-cometi-em-producao-e-o-que-aprendi-com-eles/#respond</comments>
		
		<dc:creator><![CDATA[Leonardo]]></dc:creator>
		<pubDate>Tue, 06 Jan 2026 15:41:00 +0000</pubDate>
				<category><![CDATA[Sem categoria]]></category>
		<category><![CDATA[aprendizado técnico]]></category>
		<category><![CDATA[arquitetura de software]]></category>
		<category><![CDATA[backend]]></category>
		<category><![CDATA[boas práticas]]></category>
		<category><![CDATA[erros em produção]]></category>
		<category><![CDATA[experiência real]]></category>
		<category><![CDATA[produção]]></category>
		<category><![CDATA[sistemas distribuídos]]></category>
		<guid isPermaLink="false">https://leonardonascimento.dev/?p=2259</guid>

					<description><![CDATA[<p>Produção cobra e cobra caro. E quase sempre ensina do jeito mais desconfortável possível. Ao longo do tempo, com sistemas rodando de verdade, usuários usando, integrações acontecendo e volume crescendo, alguns erros deixam de ser teóricos e passam a ter impacto real. Não são erros de sintaxe ou de framework. São erros de decisão, de [&#8230;]</p>
<p>The post <a href="https://leonardonascimento.dev/blog/erros-que-ja-cometi-em-producao-e-o-que-aprendi-com-eles/">Erros que já cometi em produção (e o que aprendi com eles)</a> appeared first on <a href="https://leonardonascimento.dev">Leonardo Nascimento | Engenheiro de Software</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Produção cobra e cobra caro. E quase sempre ensina do jeito mais desconfortável possível.</p>



<p>Ao longo do tempo, com sistemas rodando de verdade, usuários usando, integrações acontecendo e volume crescendo, alguns erros deixam de ser teóricos e passam a ter impacto real. Não são erros de sintaxe ou de framework. São erros de decisão, de suposição e, principalmente, de experiência.</p>



<p>Compartilhar esses erros não é exposição. É maturidade técnica.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p>Um dos primeiros erros que cometi foi <strong>assumir que o “funciona local” era suficiente</strong>. O sistema atendia aos requisitos, passava nos testes básicos e parecia estável. O problema é que produção adiciona concorrência, latência, falhas externas e volume. Coisas que simplesmente não existem no ambiente local. Aprendi cedo que testar comportamento é diferente de testar contexto.</p>



<p>Outro erro recorrente foi <strong>confiar demais em serviços externos</strong>. APIs de terceiros pareciam estáveis até o dia em que começaram a responder lentamente ou falhar intermitentemente. Sem timeout bem definido, sem fallback e sem isolamento, o problema externo se transformou em indisponibilidade interna. A lição aqui foi clara: dependência externa precisa ser tratada como ponto de falha, não como extensão do seu sistema.</p>



<p>Também já subestimei o impacto da <strong>concorrência</strong>. Processos rodando em paralelo, filas consumidas por múltiplos workers e requisições simultâneas expuseram condições de corrida que nunca apareceram em teste. Duplicidade de execução, dados inconsistentes e comportamentos estranhos surgiram sem aviso. Foi aí que aprendi, na prática, que idempotência não é detalhe, é requisito.</p>



<p>Houve momentos em que <strong>cache foi usado como solução rápida</strong>, sem critério. Funcionou no início, melhorou performance, mas criou uma nova classe de problema: inconsistência. Dados desatualizados começaram a aparecer e o esforço para entender se o problema estava no código, no banco ou no cache aumentou bastante. Cache resolveu o sintoma, mas atrasou o diagnóstico da causa real.</p>



<p>Outro erro comum foi <strong>logar pouco ou logar demais</strong>. Logs insuficientes tornam qualquer incidente uma investigação no escuro. Logs excessivos, por outro lado, dificultam encontrar o que realmente importa. Com o tempo, aprendi que log bom é aquele que ajuda a responder perguntas, não o que registra tudo.</p>



<p>Já deixei passar também a importância de <strong>monitorar comportamento, não só infraestrutura</strong>. CPU e memória estavam normais, mas usuários reclamavam de lentidão. O problema não era recurso, era fluxo. A partir daí, ficou claro que disponibilidade e latência percebida dizem muito mais sobre a saúde do sistema do que gráficos isolados.</p>



<p>Em alguns momentos, tomei decisões de arquitetura rígidas cedo demais. Abstrações complexas criadas “pensando no futuro” acabaram dificultando mudanças simples. Arquitetura precisa dar suporte à evolução, não impedir. Esse tipo de erro não quebra o sistema imediatamente, mas cobra juros altos com o tempo.</p>



<p>Por fim, talvez o erro mais sutil tenha sido <strong>não tratar operação como parte do desenvolvimento</strong>. Código foi escrito pensando em funcionalidade, não em manutenção, observabilidade ou resposta a incidentes. Produção mostrou que escrever código é apenas uma parte do trabalho. Operar o sistema é a outra metade.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">O que ficou de aprendizado</h2>



<p>Produção não perdoa suposições. Ela expõe decisões frágeis, atalhos técnicos e falta de preparo. Cada erro deixou uma lição clara: sistemas precisam ser pensados para falhar, para escalar e para serem operados por pessoas reais.</p>



<p>Errar faz parte. Repetir os mesmos erros é escolha.</p>
<p>The post <a href="https://leonardonascimento.dev/blog/erros-que-ja-cometi-em-producao-e-o-que-aprendi-com-eles/">Erros que já cometi em produção (e o que aprendi com eles)</a> appeared first on <a href="https://leonardonascimento.dev">Leonardo Nascimento | Engenheiro de Software</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://leonardonascimento.dev/blog/erros-que-ja-cometi-em-producao-e-o-que-aprendi-com-eles/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Monitoramento e alertas: o que realmente vale a pena acompanhar</title>
		<link>https://leonardonascimento.dev/blog/monitoramento-e-alertas-o-que-realmente-vale-a-pena-acompanhar/</link>
					<comments>https://leonardonascimento.dev/blog/monitoramento-e-alertas-o-que-realmente-vale-a-pena-acompanhar/#respond</comments>
		
		<dc:creator><![CDATA[Leonardo]]></dc:creator>
		<pubDate>Mon, 05 Jan 2026 13:34:52 +0000</pubDate>
				<category><![CDATA[Programação]]></category>
		<category><![CDATA[Alertas]]></category>
		<category><![CDATA[backend]]></category>
		<category><![CDATA[monitoramento]]></category>
		<category><![CDATA[produção]]></category>
		<guid isPermaLink="false">https://leonardonascimento.dev/?p=2257</guid>

					<description><![CDATA[<p>Monitoramento costuma ser tratado como uma etapa técnica obrigatória, algo que precisa existir porque “todo sistema precisa”. Na prática, muitos sistemas até têm monitoramento, mas poucos têm monitoramento útil. O resultado é previsível: alertas ignorados, gráficos bonitos que ninguém consulta e problemas que continuam sendo descobertos pelo usuário final. Monitorar bem não é coletar o [&#8230;]</p>
<p>The post <a href="https://leonardonascimento.dev/blog/monitoramento-e-alertas-o-que-realmente-vale-a-pena-acompanhar/">Monitoramento e alertas: o que realmente vale a pena acompanhar</a> appeared first on <a href="https://leonardonascimento.dev">Leonardo Nascimento | Engenheiro de Software</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p><a href="https://leonardonascimento.dev/blog/updown-io-receba-notificacao-no-whatsapp-caso-seu-site-fique-indisponivel/" type="post" id="164">Monitoramento </a>costuma ser tratado como uma etapa técnica obrigatória, algo que precisa existir porque “todo sistema precisa”. Na prática, muitos sistemas até têm monitoramento, mas poucos têm <strong>monitoramento útil</strong>. O resultado é previsível: alertas ignorados, gráficos bonitos que ninguém consulta e problemas que continuam sendo descobertos pelo usuário final.</p>



<p>Monitorar bem não é coletar o máximo de dados possível. É escolher, com critério, aquilo que realmente indica a saúde do sistema e permite agir antes que o impacto se torne maior.</p>



<p>O primeiro ponto que merece atenção é a <strong>disponibilidade real</strong>. Não no sentido abstrato de “o servidor está ligado”, mas se o sistema está efetivamente acessível para quem depende dele. Uma aplicação pode estar no ar e, ainda assim, indisponível do ponto de vista do usuário. Monitorar endpoints críticos, fluxos principais e páginas essenciais costuma ser mais valioso do que observar métricas genéricas de infraestrutura isoladamente.</p>



<p>Disponibilidade, no entanto, não conta a história inteira. Muitos problemas começam de forma silenciosa, como uma degradação progressiva de desempenho. Um sistema que responde lentamente por alguns minutos ou horas já está falhando, mesmo sem cair completamente. Acompanhar latência ao longo do tempo ajuda a identificar gargalos antes que eles se tornem incidentes graves, além de revelar dependências externas que começam a responder de forma instável.</p>



<p>Outro ponto frequentemente subestimado é o <strong>comportamento dos erros</strong>. Todo sistema apresenta falhas ocasionais, e isso é esperado. O problema não está no erro isolado, mas na repetição, no padrão e na concentração. Quando uma mesma falha começa a ocorrer com frequência crescente, ela deixa de ser exceção e passa a ser sinal de degradação. Monitoramento eficiente olha para tendências, não apenas para eventos pontuais.</p>



<p>Logs entram exatamente nesse contexto. Em produção, logs não servem para registrar tudo, mas para permitir reconstruir o que aconteceu quando algo dá errado. Logs bem pensados ajudam a responder perguntas simples com rapidez: qual fluxo foi afetado, em que momento, com quais dados e sob quais condições. Quando isso não é possível, o tempo de investigação cresce e a confiança no sistema diminui.</p>



<p>Nenhum sistema moderno funciona isoladamente, e por isso <strong>dependências externas</strong> precisam fazer parte do monitoramento. APIs de terceiros, serviços de mensageria, gateways de pagamento e qualquer recurso externo podem se tornar gargalos ou pontos únicos de falha. Ignorar essas dependências costuma levar a diagnósticos errados, onde o time tenta corrigir um problema interno que, na verdade, começou fora do sistema.</p>



<p>Alertas, por sua vez, exigem ainda mais cuidado. Um alerta só faz sentido se houver alguém responsável por ele e se a ação esperada estiver clara. Alertas em excesso criam ruído, e ruído gera descrédito. Com o tempo, ninguém reage mais. Um bom sistema de alertas dispara pouco, mas quando dispara, exige atenção imediata. Confiabilidade aqui é mais importante do que cobertura total.</p>



<p>Com a evolução do sistema, o monitoramento também precisa evoluir. Fluxos mudam, riscos novos surgem, padrões antigos deixam de ser relevantes. Métricas e alertas que não são revisados acabam perdendo valor e permanecem ativos apenas por inércia. Monitoramento eficaz é um processo contínuo, não uma configuração feita uma única vez.</p>



<p>Vale deixar claro que monitoramento não corrige arquitetura ruim. Ele ajuda a enxergar problemas, não a resolvê-los. Sistemas mal desenhados tendem a gerar alertas constantes, comportamento imprevisível e alto custo operacional. Quando a base é sólida, o monitoramento se torna uma ferramenta de apoio, não uma tentativa de contenção.</p>



<p>No fim, o que realmente vale a pena acompanhar é aquilo que afeta diretamente a operação: disponibilidade percebida, tempo de resposta, comportamento de erros, saúde das dependências externas e padrões anormais de uso. O restante deve existir apenas se contribuir para decisões melhores.</p>



<p>Monitorar sistemas não é uma disputa por quem coleta mais métricas, mas por quem reage melhor aos sinais certos. Quando bem feito, o monitoramento reduz impacto, antecipa problemas e traz previsibilidade à operação. Esse tipo de maturidade técnica raramente aparece por acaso — ela nasce da experiência de quem já lidou com produção de verdade.</p>
<p>The post <a href="https://leonardonascimento.dev/blog/monitoramento-e-alertas-o-que-realmente-vale-a-pena-acompanhar/">Monitoramento e alertas: o que realmente vale a pena acompanhar</a> appeared first on <a href="https://leonardonascimento.dev">Leonardo Nascimento | Engenheiro de Software</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://leonardonascimento.dev/blog/monitoramento-e-alertas-o-que-realmente-vale-a-pena-acompanhar/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Pensar arquitetura antes de escrever código ou sair escrevendo e depois ver no que da?</title>
		<link>https://leonardonascimento.dev/blog/pensar-arquitetura-antes-de-escrever-codigo-ou-sair-escrevendo-e-depois-ver-no-que-da/</link>
					<comments>https://leonardonascimento.dev/blog/pensar-arquitetura-antes-de-escrever-codigo-ou-sair-escrevendo-e-depois-ver-no-que-da/#respond</comments>
		
		<dc:creator><![CDATA[Leonardo]]></dc:creator>
		<pubDate>Sun, 04 Jan 2026 17:56:00 +0000</pubDate>
				<category><![CDATA[Programação]]></category>
		<category><![CDATA[arquitetura de software]]></category>
		<category><![CDATA[backend]]></category>
		<category><![CDATA[boas práticas]]></category>
		<category><![CDATA[manutenibilidade]]></category>
		<category><![CDATA[produção]]></category>
		<category><![CDATA[qualidade de código]]></category>
		<guid isPermaLink="false">https://leonardonascimento.dev/?p=2254</guid>

					<description><![CDATA[<p>É muito comum começar um sistema abrindo o editor e escrevendo código. Cria um controller, faz uma query, retorna uma resposta e segue o jogo. No começo funciona. E exatamente por isso muita gente continua fazendo assim. O problema é que essa forma de trabalhar escala muito mal. Quando o sistema cresce, quando entra mais [&#8230;]</p>
<p>The post <a href="https://leonardonascimento.dev/blog/pensar-arquitetura-antes-de-escrever-codigo-ou-sair-escrevendo-e-depois-ver-no-que-da/">Pensar arquitetura antes de escrever código ou sair escrevendo e depois ver no que da?</a> appeared first on <a href="https://leonardonascimento.dev">Leonardo Nascimento | Engenheiro de Software</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>É muito comum começar um sistema abrindo o editor e escrevendo código. Cria um controller, faz uma query, retorna uma resposta e segue o jogo. No começo funciona. E exatamente por isso muita gente continua fazendo assim.</p>



<p>O problema é que essa forma de trabalhar escala muito mal.</p>



<p>Quando o sistema cresce, quando entra mais gente no time ou quando surgem novas regras, aquele código que “resolvia” começa a virar um emaranhado difícil de mexer. E aí surge a sensação de que qualquer mudança simples dá trabalho demais.</p>



<p>Isso quase nunca é culpa do código em si. Normalmente é arquitetura que nunca foi pensada.</p>



<p>Código muda o tempo todo. Arquitetura não.</p>



<p>Funções são reescritas, métodos são refatorados, nomes são ajustados. Mas a forma como o sistema foi estruturado lá no começo costuma durar anos. Se a base foi mal pensada, você passa muito tempo brigando com decisões antigas.</p>



<p>É por isso que arquitetura não é detalhe. Ela define o quanto o sistema vai te ajudar ou te atrapalhar no futuro.</p>



<p>Outro erro comum é começar pensando em ferramenta.</p>



<p>“Como faço isso no Laravel?”<br>“Qual padrão eu uso aqui?”<br>“Isso vira um service ou um job?”</p>



<p>Essas perguntas vêm cedo demais.</p>



<p>Antes disso, o que realmente importa é entender o problema. O fluxo. O que entra, o que sai, o que pode falhar, o que precisa ser consistente. Quando isso não está claro, qualquer código escrito vira tentativa e erro.</p>



<p>Framework ajuda, mas não pensa por você.</p>



<p>Misturar responsabilidade quase sempre parece produtivo no início.</p>



<p>Coloca regra no controller, resolve ali mesmo, já retorna a resposta e pronto. Funciona rápido. Até o dia em que você precisa reutilizar aquela lógica, testar isoladamente ou mudar um comportamento sem quebrar outro.</p>



<p>Quando tudo está no mesmo lugar, nada está realmente isolado.</p>



<p>Separar responsabilidade não é academicismo. É o que evita que uma mudança pequena vire um risco desnecessário.</p>



<p>Uma coisa que ajuda muito é pensar no fluxo antes de pensar em classes.</p>



<p>De onde vem o dado?<br>O que valida?<br>Onde a regra acontece?<br>O que persiste?<br>O que retorna?</p>



<p>Quando esse caminho está claro na cabeça, o código flui. Quando não está, você sente que está “programando no escuro”.</p>



<p>Arquitetura ruim costuma esconder dependências.</p>



<p>Você só descobre que uma parte do sistema depende de outra quando tenta mexer em algo e tudo quebra. Isso acontece porque essas dependências nunca foram assumidas, só foram surgindo.</p>



<p>Dependência explícita dói menos do que dependência escondida.</p>



<p>Produção exige previsibilidade.</p>



<p>Não é só sobre funcionar agora, é sobre saber o impacto de uma mudança. Quando a arquitetura é confusa, qualquer ajuste vira medo. Quando é clara, você sabe exatamente onde mexer e o que pode ser afetado.</p>



<p>Esse tipo de tranquilidade não vem do código bonito. Vem de decisões bem pensadas.</p>



<p>Também vale um cuidado importante: decisões irreversíveis cedo demais</p>



<p>Criar abstrações complexas, padrões genéricos ou estruturas “pensando no futuro” costuma travar o sistema antes mesmo dele crescer. Boa arquitetura é flexível. Ela resolve o problema atual sem impedir evolução.</p>



<p>Complexidade prematura cobra juros.</p>



<p>Pensar arquitetura não significa desenhar diagramas enormes nem usar nomes sofisticados. Na maioria das vezes, boa arquitetura é simples o suficiente para ser explicada em poucos minutos.</p>



<p>Se você não consegue explicar como o sistema funciona, provavelmente ele já está mais complexo do que deveria.</p>



<p>No começo, pensar arquitetura parece atrasar. Depois de alguns meses, ela economiza tempo. Menos retrabalho, menos bug colateral, menos receio de mexer no código.</p>



<p>O ganho não é imediato, mas é consistente.</p>



<p><strong>Conclusão</strong></p>



<p>Pensar arquitetura antes de escrever código não é tentar prever tudo. É reduzir incerteza.</p>



<p>É entender o problema antes de sair codando. É isso que separa sistemas que evoluem com tranquilidade daqueles que vão acumulando problemas silenciosos até virar dívida difícil de pagar.</p>
<p>The post <a href="https://leonardonascimento.dev/blog/pensar-arquitetura-antes-de-escrever-codigo-ou-sair-escrevendo-e-depois-ver-no-que-da/">Pensar arquitetura antes de escrever código ou sair escrevendo e depois ver no que da?</a> appeared first on <a href="https://leonardonascimento.dev">Leonardo Nascimento | Engenheiro de Software</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://leonardonascimento.dev/blog/pensar-arquitetura-antes-de-escrever-codigo-ou-sair-escrevendo-e-depois-ver-no-que-da/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Código em produção: você tem certeza de que ele está pronto?</title>
		<link>https://leonardonascimento.dev/blog/codigo-em-producao-voce-tem-certeza-de-que-ele-esta-pronto/</link>
					<comments>https://leonardonascimento.dev/blog/codigo-em-producao-voce-tem-certeza-de-que-ele-esta-pronto/#respond</comments>
		
		<dc:creator><![CDATA[Leonardo]]></dc:creator>
		<pubDate>Thu, 01 Jan 2026 15:45:00 +0000</pubDate>
				<category><![CDATA[Programação]]></category>
		<category><![CDATA[arquitetura de software]]></category>
		<category><![CDATA[backend]]></category>
		<category><![CDATA[boas práticas]]></category>
		<category><![CDATA[manutenibilidade]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[produção]]></category>
		<guid isPermaLink="false">https://leonardonascimento.dev/?p=2245</guid>

					<description><![CDATA[<p>Na minha máquina funciona, isso é o suficiente? Muita gente confunde código que simplesmente funciona com código que está realmente pronto para rodar em produção. A diferença entre um e outro costuma aparecer no pior momento possível: em pico de acesso, durante uma campanha, com cliente reclamando ou com o sistema fora do ar. Funcionar [&#8230;]</p>
<p>The post <a href="https://leonardonascimento.dev/blog/codigo-em-producao-voce-tem-certeza-de-que-ele-esta-pronto/">Código em produção: você tem certeza de que ele está pronto?</a> appeared first on <a href="https://leonardonascimento.dev">Leonardo Nascimento | Engenheiro de Software</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Na minha máquina funciona, isso é o suficiente?</p>



<p>Muita gente confunde código que simplesmente funciona com código que está realmente pronto para rodar em produção. A diferença entre um e outro costuma aparecer no pior momento possível: em pico de acesso, durante uma campanha, com cliente reclamando ou com o sistema fora do ar.</p>



<p>Funcionar significa que o código faz o que foi pedido.<br>Código pronto para produção significa que ele continua funcionando <strong>quando tudo começa a dar errado</strong>.</p>



<p>Na prática, código pronto para produção:</p>



<ul class="wp-block-list">
<li>lida com erros de forma previsível;</li>



<li>escala quando a carga aumenta;</li>



<li>se comporta bem sob concorrência;</li>



<li>é observável;</li>



<li>pode ser mantido sem medo;</li>



<li>não depende de sorte.</li>
</ul>



<p></p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">1) Tratamento de erros</h2>



<p>Produção é um ambiente imprevisível. APIs externas caem. Banco fica lento. Cache expira. Timeouts acontecem.</p>



<p>Se o seu código assume que tudo sempre vai responder corretamente, ele vai quebrar — e rápido.</p>



<p>Código de produção:</p>



<ul class="wp-block-list">
<li>trata exceções;</li>



<li>captura falhas externas;</li>



<li>retorna erros claros;</li>



<li>evita estados quebrados.</li>
</ul>



<p>Ignorar erros não faz eles desaparecerem. Só faz você descobri-los tarde demais.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">2) Concorrência</h2>



<p>Concorrência é real. E não é opcional.</p>



<p>Vários usuários, múltiplos processos, jobs rodando ao mesmo tempo, filas sendo consumidas em paralelo. Se o sistema não foi pensado para isso, os problemas aparecem como:</p>



<ul class="wp-block-list">
<li>condições de corrida;</li>



<li>duplicidade de processamento;</li>



<li>registros inconsistentes;</li>



<li>dados sobrescritos.</li>
</ul>



<p>Código que funciona com um usuário não necessariamente funciona com cem.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">3) Idempotência</h2>



<p>Esse ponto é ignorado por muita gente.</p>



<p>Em produção, requisições podem ser reenviadas, jobs podem ser reprocessados, webhooks podem disparar mais de uma vez. Se sua lógica não for idempotente, você terá:</p>



<ul class="wp-block-list">
<li>registros duplicados;</li>



<li>ações executadas mais de uma vez;</li>



<li>efeitos colaterais difíceis de desfazer.</li>
</ul>



<p>Código de produção precisa assumir que <strong>a mesma ação pode chegar mais de uma vez</strong>.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">4) Observabilidade</h2>



<p>Sem logs estruturados, métricas e alertas, você não tem controle — só reação.</p>



<p>Quando algo quebra e você depende de usuário reclamando para descobrir, o problema já escalou.</p>



<p>Código pronto para produção:</p>



<ul class="wp-block-list">
<li>registra eventos relevantes;</li>



<li>gera logs que ajudam a investigar;</li>



<li>permite entender o que aconteceu sem “chutar”.</li>
</ul>



<p>Debug em produção não pode ser baseado em achismo.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">5) Performance previsível</h2>



<p>Performance não é só velocidade. É previsibilidade.</p>



<p>Um endpoint que responde em 50ms hoje e em 5s amanhã é um problema, mesmo que “funcione”.</p>



<p>Código de produção:</p>



<ul class="wp-block-list">
<li>evita queries desnecessárias;</li>



<li>não faz processamento pesado sem controle;</li>



<li>considera impacto de volume e concorrência.</li>
</ul>



<p>O objetivo não é ser rápido no melhor cenário, mas <strong>estável no pior</strong>.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">6) Isolamento de responsabilidades</h2>



<p>Misturar regra de negócio, acesso a dados e controle de requisição cria código frágil.</p>



<p>Quando tudo está acoplado:</p>



<ul class="wp-block-list">
<li>mudanças pequenas viram grandes refatorações;</li>



<li>bugs aparecem em lugares inesperados;</li>



<li>testes se tornam difíceis ou impossíveis.</li>
</ul>



<p>Código de produção separa responsabilidades para reduzir impacto de mudanças.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">7) Dependências externas sob controle</h2>



<p>Qualquer integração externa é um ponto de falha.</p>



<p>APIs de terceiros, serviços de pagamento, mensageria, armazenamento. Tudo isso pode falhar.</p>



<p>Código pronto para produção:</p>



<ul class="wp-block-list">
<li>define timeouts;</li>



<li>controla retries;</li>



<li>trata respostas inesperadas;</li>



<li>evita travar o sistema por dependência externa.</li>
</ul>



<p>Assumir que serviços externos “sempre funcionam” é ingenuidade.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">8) Configuração e ambiente</h2>



<p>Código de produção não depende de configuração hardcoded.</p>



<p>Ambientes mudam: local, staging, produção, múltiplos servidores, múltiplos clientes. Se o código não respeita isso, o deploy vira um risco.</p>



<p>Separar configuração de código não é frescura. É requisito básico.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">9) Manutenibilidade</h2>



<p>Se depois de um mês você não entende o que escreveu, o problema não é memória — é o código.</p>



<p>Produção é manutenção contínua. Código precisa ser:</p>



<ul class="wp-block-list">
<li>legível;</li>



<li>previsível;</li>



<li>organizado.</li>
</ul>



<p>Código bom não é o mais curto nem o mais “esperto”. É o que dá menos medo de mexer.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">10) Pensar no impacto futuro</h2>



<p>Código que funciona resolve o agora.<br>Código pronto para produção considera o depois.</p>



<p>Depois de:</p>



<ul class="wp-block-list">
<li>novos usuários;</li>



<li>novas regras;</li>



<li>novas integrações;</li>



<li>novos desenvolvedores no time.</li>
</ul>



<p>Decisões técnicas ruins não quebram tudo na hora — elas cobram juros com o tempo.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">Conclusão</h2>



<p>Código pronto para produção não é sobre escrever mais código, usar mais ferramentas ou aplicar padrões complexos.</p>



<p>É sobre responsabilidade técnica.</p>



<p>É pensar no que pode dar errado, assumir que vai dar, e preparar o sistema para continuar funcionando mesmo assim. Essa é a diferença real entre sistemas estáveis e sistemas problemáticos.</p>
<p>The post <a href="https://leonardonascimento.dev/blog/codigo-em-producao-voce-tem-certeza-de-que-ele-esta-pronto/">Código em produção: você tem certeza de que ele está pronto?</a> appeared first on <a href="https://leonardonascimento.dev">Leonardo Nascimento | Engenheiro de Software</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://leonardonascimento.dev/blog/codigo-em-producao-voce-tem-certeza-de-que-ele-esta-pronto/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
