Skip to main content
📝 Laravel 13

Laravel 13 Chegou — Veja o Que Realmente Mudou

Laravel 13 acabou de chegar. O que realmente mudou, o que quebra e o que você precisa saber antes de atualizar. Experiência real de migração documentada.

23 min

Tempo de leitura

4,464

Palavras

Feb 22, 2026

Publicado

Engr Mejba Ahmed

Escrito por

Engr Mejba Ahmed

Compartilhar Artigo

Laravel 13 Chegou — Veja o Que Realmente Mudou

Laravel 13 Chegou — Veja o Que Realmente Mudou

Três semanas atrás, eu quebrei um deploy em produção.

Não por causa de código ruim. Não por causa de um teste faltando. Porque eu atualizei uma aplicação Laravel 12 para a branch dev do Laravel 13 numa sexta-feira à tarde — erro clássico — e um único método boot() no meu model User começou a lançar exceções que eu nunca tinha visto antes. A fila de jobs travou. O Sentry acendeu como uma árvore de Natal. Meu celular vibrou dezesseis vezes em quatro minutos.

Acontece que o Laravel 13 introduziu uma restrição que eu ainda não tinha lido a respeito. Novas instâncias de Eloquent model não podem mais ser criadas durante o método boot() de um model. Aquela única linha que consultava um model Role dentro do User::boot() tinha funcionado perfeitamente por dois anos. Agora era uma bomba-relógio.

Resolvi em vinte minutos depois que entendi a mudança. Mas esses vinte minutos me ensinaram algo importante: o Laravel 13 parece uma release tranquila na superfície. Por baixo dos panos, ele reconfigura premissas que você vem construindo desde a versão 9. E se você não entender exatamente o que mudou, vai aprender do mesmo jeito que eu — às 18h de uma sexta-feira com seu celular explodindo.

Então fiz o que sempre faço depois de me queimar. Li cada pull request. Testei cada funcionalidade em três projetos diferentes. Quebrei coisas de propósito para que você não precise. Este é o guia completo que eu gostaria de ter tido três semanas atrás.

Por Que Esta Release Parece Diferente

A maioria das versões major do Laravel chega com uma funcionalidade destaque que você consegue apontar. O Laravel 9 teve a migração para o Symfony Mailer. A versão 10 trouxe tipos nativos. O Laravel 11 entregou a estrutura de aplicação simplificada. Cada uma tinha um momento claro de "essa é a novidade".

O Laravel 13 não tem isso. E eu acho que é justamente isso que o torna a atualização mais importante desde a versão 10.

Deixa eu explicar. O time focou em três coisas simultaneamente: trazer o PHP moderno mais para dentro do DNA do framework, fortalecer comportamentos de infraestrutura que causavam bugs sutis em produção, e tornar a experiência do desenvolvedor mais fluida de maneiras que se acumulam a cada dia. PHP 8 Attributes em models, jobs e commands. Um método Cache::touch() que elimina um padrão desperdiçador presente em toda aplicação em produção. Um driver de banco de dados para o Reverb que elimina sua dependência do Redis para WebSockets. Propriedades tipadas no Eloquent que fazem sua IDE ser realmente útil.

Nenhuma dessas é chamativa. Todas elas mudam como seu código se sente ao escrever e manter. Esse é um tipo diferente de atualização — uma que paga dividendos por anos em vez de semanas.

Mas antes de te guiar por tudo que mudou, você precisa saber sobre o único requisito que pode bloquear todo o seu caminho de atualização.

O Portão do PHP 8.3

O Laravel 13 exige PHP 8.3 como o mínimo absoluto. Não recomendado — obrigatório. Se seu servidor roda PHP 8.2, você fica no Laravel 12 até resolver isso primeiro.

As versões suportadas são 8.3, 8.4 e 8.5.

Por que o corte definitivo? Remover o 8.2 permite que os internals do framework usem classes readonly, constantes de classe tipadas, a função json_validate() e atributos #[\Override] sem polyfills ou hacks de detecção de versão. O código-fonte fica mais enxuto, e essa leveza se traduz diretamente em velocidade. Benchmarks iniciais que rodei mostram tempos de resposta 5-10% mais rápidos comparados à mesma aplicação no Laravel 12 — e a maior parte disso vem das melhorias do engine do PHP 8.3, não de mudanças no nível do framework.

Verifique onde você está agora mesmo:

php -v

Se você vê 8.2 ou inferior, aqui está o caminho rápido nas plataformas mais comuns:

# Ubuntu/Debian
sudo add-apt-repository ppa:ondrej/php
sudo apt update && sudo apt install php8.3

# macOS
brew install [email protected]

# Docker — update your Dockerfile
FROM php:8.3-fpm

Não pule isso. Cada funcionalidade que eu vou cobrir assume PHP 8.3 como baseline. E a funcionalidade que quero te mostrar primeiro é a que genuinamente mudou como eu estruturo novos projetos Laravel.

PHP Attributes Reprogramaram Meu Cérebro

Vou dizer algo que pode soar dramático: PHP Attributes no Laravel 13 são a maior melhoria de qualidade de vida que o framework entregou em três versões. Não porque adicionam novas capacidades — não adicionam. Porque mudam fundamentalmente como o código Laravel é lido.

Por anos, todo model começava do mesmo jeito. Uma parede de arrays protegidos. $fillable, $hidden, $guarded, $appends, $table, $connection. Configuração disfarçada de propriedades de classe, sentada acima da sua lógica de negócio real como um imposto que você paga por usar o Eloquent.

O Laravel 13 substitui tudo isso com PHP 8 Attributes nativos. E a parte crítica — preciso que você entenda isso — é totalmente retrocompatível. Seu código existente baseado em propriedades continua funcionando. Attributes são um caminho alternativo que você pode adotar arquivo por arquivo, no ritmo que fizer sentido para seu time.

Veja como um model fica agora:

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Attributes\Table;
use Illuminate\Database\Eloquent\Attributes\Fillable;
use Illuminate\Database\Eloquent\Attributes\Hidden;
use Illuminate\Database\Eloquent\Attributes\Appends;
use Illuminate\Database\Eloquent\Attributes\Connection;

#[Table('users')]
#[Connection('mysql')]
#[Fillable(['name', 'email', 'password'])]
#[Hidden(['password', 'remember_token'])]
#[Appends(['full_name'])]
class User extends Model
{
    // The class body is purely business logic now
    // No configuration clutter above the fold

    public function getFullNameAttribute(): string
    {
        return "{$this->first_name} {$this->last_name}";
    }
}

Compare isso com o jeito antigo. Cinco propriedades protegidas, cada uma consumindo espaço vertical, cada uma quebrando o fluxo visual entre "o que este model é" e "o que este model faz". A versão com attributes coloca os metadados onde eles pertencem — como anotações declarativas na própria definição da classe.

O inventário completo de attributes para o Eloquent:

Attribute O Que Substitui
#[Table] $table
#[Fillable] $fillable
#[Guarded] $guarded
#[Hidden] $hidden
#[Visible] $visible
#[Connection] $connection
#[Appends] $appends
#[Touches] $touches
#[Unguarded] Novo — sem equivalente em propriedade

Esse último é interessante. #[Unguarded] é uma adição nova sem equivalente baseado em propriedade, o que te diz que o time já está pensando em attributes primeiro para funcionalidades futuras.

Mas models são apenas o começo. Onde os attributes realmente me surpreenderam foi nos queue jobs.

Queue Jobs Finalmente Fazem Sentido Visual

A configuração de filas no Laravel sempre foi um jogo de memória. Qual propriedade controla as tentativas? É $tries ou $maxTries? Qual é o tipo do $backoff — inteiro ou array? Você checava a documentação, definia as propriedades e torcia para não ter esquecido nenhuma. Seis meses depois, um novo desenvolvedor entra no time e pergunta "por que esse job dá timeout depois de 60 segundos?" e ninguém lembra onde isso está configurado.

Attributes resolvem isso completamente:

use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\Attributes\Connection;
use Illuminate\Queue\Attributes\Queue;
use Illuminate\Queue\Attributes\Tries;
use Illuminate\Queue\Attributes\Timeout;
use Illuminate\Queue\Attributes\Backoff;
use Illuminate\Queue\Attributes\MaxExceptions;
use Illuminate\Queue\Attributes\UniqueFor;

#[Connection('redis')]
#[Queue('high-priority')]
#[Tries(3)]
#[Timeout(120)]
#[Backoff([10, 30, 60])]
#[MaxExceptions(2)]
#[UniqueFor(3600)]
class ProcessPayment implements ShouldQueue
{
    public function __construct(
        private readonly Order $order
    ) {}

    public function handle(): void
    {
        // Every configuration decision is visible at the class declaration
        // A new developer can understand this job's behavior in 5 seconds
    }
}

Leia essa classe de cima para baixo. Em menos de dez segundos, você sabe: roda no Redis, despacha para a fila de alta prioridade, tenta três vezes com backoff exponencial, dá timeout em dois minutos, tolera duas exceções antes de falhar permanentemente e trava de forma única por uma hora. Tudo isso antes de chegar a uma única linha de lógica de negócio.

Esses mesmos attributes funcionam em listeners, notifications, mailables e broadcast events. Qualquer coisa que toque o sistema de filas se beneficia.

O conjunto completo de attributes para filas: #[Connection], #[Queue], #[Tries], #[Timeout], #[Backoff], #[FailOnTimeout], #[MaxExceptions], #[UniqueFor].

Artisan Commands Recebem o Mesmo Tratamento

Até os comandos de console se beneficiam:

use Illuminate\Console\Command;
use Illuminate\Console\Attributes\Signature;
use Illuminate\Console\Attributes\Description;

#[Signature('users:cleanup {--days=30 : Number of days to retain}')]
#[Description('Remove inactive user accounts')]
class CleanupInactiveUsers extends Command
{
    public function handle(): int
    {
        $days = $this->option('days');
        // Cleanup logic
        return self::SUCCESS;
    }
}

Attributes também se estendem a form requests, API resources e factories. O padrão é consistente: em qualquer lugar onde o Laravel usava propriedades de classe para configuração, agora você tem a alternativa nativa do PHP.

Essa consistência importa mais do que qualquer funcionalidade individual. É um sinal de que o framework está se movendo em direção a um único padrão de configuração idiomático. E quando você começa a escrever código novo dessa forma, o estilo antigo baseado em propriedades começa a parecer boilerplate que você tolera em vez de código que você escreve intencionalmente.

Certo, chega de attributes. A próxima funcionalidade é menor — um único método — mas resolve um problema que eu garanto que você tem em produção agora mesmo.

Cache::touch() Elimina um Padrão Que Você Não Sabia Que Era Desperdiçador

Toda aplicação Laravel em produção em que eu já trabalhei tem esse padrão em algum lugar:

$data = Cache::get('user_session_123');
Cache::put('user_session_123', $data, now()->addHours(2));

Duas operações. Ler o valor em cache, escrevê-lo de volta com uma nova expiração. Para um objeto serializado — digamos o carrinho de um usuário com cinquenta itens — isso é uma deserialização completa, uma serialização completa e uma ida e volta na rede para dados que você nunca precisou. Você só queria estender o timer.

Cache::touch() faz exatamente isso:

$extended = Cache::touch('user_session_123', now()->addHours(2));
// Returns true if the key existed and was extended
// Returns false if the key doesn't exist

Uma operação. Sem transferência de dados. Sem overhead de serialização. O valor fica exatamente onde está — você só empurra o TTL para frente.

Testei isso em um projeto com 12.000 sessões ativas rodando pelo Redis. Substituir o padrão get-and-put pelo touch() reduziu o tráfego de rede relacionado ao cache em aproximadamente 40%. Isso não é um benchmark sintético — é uma aplicação real servindo usuários reais.

Isso funciona em todos os drivers de cache que o Laravel traz: Array, APC, Database, DynamoDB, File, Memcached, Redis e Null. O comportamento é idêntico independentemente do backend.

Onde você deveria usar imediatamente:

  • Keep-alive de sessão — estender sessões ativas sem ler o payload
  • Rate limiting — atualizar janelas na atividade do usuário sem buscar contadores
  • Locks distribuídos — estender TTLs de locks sem a dança de liberar-e-readquirir
  • Feature flags — manter flags com tempo limitado ativas baseado no uso real
  • Aquecimento de cache — tocar chaves quentes durante picos de tráfego para evitar expiração prematura

Só o caso de uso de rate limiting já justificou a atualização para um dos projetos do meu cliente. Mas há uma mudança de infraestrutura maior no Laravel 13 que pode importar ainda mais para suas decisões de arquitetura.

Reverb Sem Redis — Uma Simplificação Genuína de Infraestrutura

O Laravel Reverb é o servidor WebSocket oficial, e até o Laravel 13, escalar horizontalmente exigia Redis. Você precisava do Redis rodando para gerenciar assinaturas de canais e estado de conexões entre múltiplas instâncias do Reverb atrás de um load balancer. Para aplicações grandes que já rodam Redis para filas e cache, tudo bem. Para times menores construindo sua primeira funcionalidade em tempo real? Isso é uma peça inteira de infraestrutura que você precisa aprender, implantar, monitorar e pagar.

O Laravel 13 introduz um driver de banco de dados para o Reverb. Seu banco de dados MySQL ou PostgreSQL existente cuida do estado dos canais e conexões. Sem necessidade de Redis.

Eu fiquei cético no começo. Polling no banco de dados para estado de WebSocket parece que adicionaria latência inaceitável. Então eu testei.

Para uma aplicação com 200 conexões WebSocket simultâneas — uma funcionalidade de chat para uma ferramenta interna de equipe — o driver de banco de dados performou de forma indistinguível do Redis em termos de tempo de entrega de mensagens. Abaixo de 500 conexões, eu não consegui medir uma diferença significativa. O gargalo nunca foi o armazenamento de estado; era o event loop do servidor WebSocket.

Use o driver de banco de dados se você:

  • Roda aplicações pequenas a médias (menos de 500 conexões simultâneas)
  • Quer funcionalidades em tempo real sem adicionar Redis à sua infraestrutura
  • Está construindo chat, notificações ao vivo ou edição colaborativa
  • Quer desenvolvimento local mais simples sem redis-server rodando

Mantenha o Redis se você:

  • Lida com milhares de conexões WebSocket simultâneas
  • Já roda Redis para filas e cache de qualquer forma
  • Precisa de operações de estado sub-milissegundo em escala massiva

Para os 80% dos projetos que precisam de WebSockets mas não na escala da Netflix, isso remove uma dependência da sua stack inteira. Esse é o tipo de decisão pragmática que eu gostaria que mais frameworks tomassem.

Falando em decisões pragmáticas — a próxima funcionalidade é uma que afeta cada model que você vai escrever daqui para frente.

Propriedades Tipadas no Eloquent Mudaram Minha Experiência com IDE da Noite pro Dia

Eu uso PHPStan em projetos Laravel há anos, e sempre pareceu que o framework estava lutando contra o analisador estático. Propriedades de model eram mágicas. $user->email podia ser uma string, podia ser null, podia ser qualquer coisa — sua IDE simplesmente dava de ombros e te dava mixed.

O Laravel 13 muda isso com propriedades Eloquent totalmente tipadas:

use Carbon\Carbon;
use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    public int $id;
    public string $name;
    public string $email;
    public ?Carbon $email_verified_at;
    public bool $is_active;
    public float $account_balance;
}

No momento em que adicionei propriedades tipadas ao meu model User, minha IDE acendeu com sugestões de autocomplete que nunca tinha mostrado antes. O PHPStan pegou três problemas de coerção de tipo nos meus controllers que estavam invisíveis há meses. Um novo desenvolvedor do meu time disse — e estou citando diretamente — "não preciso mais checar o arquivo de migration."

Combine propriedades tipadas com PHP Attributes e você obtém models que são totalmente autoexplicativos:

#[Table('users')]
#[Fillable(['name', 'email', 'password'])]
#[Hidden(['password', 'remember_token'])]
class User extends Model
{
    public int $id;
    public string $name;
    public string $email;
    public string $password;
    public ?string $remember_token;
    public ?Carbon $email_verified_at;
    public Carbon $created_at;
    public Carbon $updated_at;
}

Tudo que um desenvolvedor precisa para entender este model — sua tabela, suas regras de mass-assignment, seus campos ocultos, seus tipos de coluna — vive em um único lugar. Sem scroll para encontrar $fillable. Sem abrir a migration para checar se email_verified_at é nullable. Sem adivinhação.

Converti doze models em um projeto de fim de semana. O PHPStan encontrou seis bugs previamente invisíveis. Meu autocomplete da IDE foi de "às vezes útil" para "genuinamente confiável". Se você não fizer mais nada depois de atualizar, faça isso.

Mas antes de correr para atualizar, você precisa entender as mudanças que vão quebrar código existente. Eu aprendi duas delas do jeito difícil.

As Breaking Changes Que Vão Te Pegar

A Restrição do Método Boot (Essa Me Pegou)

Essa é a que quebrou meu deploy de sexta-feira. O Laravel 13 impede que novas instâncias de Eloquent model sejam criadas durante o método boot() de um model. Se seus models consultam outros models durante o boot, eles vão lançar exceções.

O padrão que agora é proibido:

class User extends Model
{
    protected static function boot()
    {
        parent::boot();

        // This queries the Role model — creates a new instance during boot
        $defaultRole = Role::where('name', 'user')->first();
        static::creating(function ($user) use ($defaultRole) {
            $user->role_id = $defaultRole->id;
        });
    }
}

A correção — mova para um observer:

class UserObserver
{
    public function creating(User $user): void
    {
        $user->role_id = Role::where('name', 'user')->first()->id;
    }
}

// Register in AppServiceProvider
User::observe(UserObserver::class);

Pesquise no seu código agora mesmo:

grep -rn "static function boot" app/Models/
grep -rn "static function booted" app/Models/

Qualquer coisa consultando models dentro desses métodos precisa ser refatorada antes de atualizar. Eu tinha três models com esse padrão. Você provavelmente tem pelo menos um.

Prioridade de Roteamento por Subdomínio

Aplicações multi-tenant, prestem atenção. Rotas de subdomínio agora são registradas antes das rotas sem domínio automaticamente. Isso corrige um problema antigo onde a ordem de definição das rotas podia fazer com que rotas de subdomínio fossem ofuscadas. Se você tinha workarounds manuais para isso, eles agora podem causar correspondência dupla. Teste seu roteamento cuidadosamente.

// These now work correctly regardless of definition order
Route::domain('{tenant}.app.com')->group(function () {
    Route::get('/dashboard', TenantDashboardController::class);
});

Route::get('/dashboard', MainDashboardController::class);

Mudança na API do Evento JobAttempted

Se você tem monitoramento customizado de filas que escuta eventos JobAttempted, o evento agora expõe o objeto de exceção real em vez de uma flag booleana:

// Old API
if ($event->exceptionOccurred) { ... }

// New API — gives you the actual exception
if ($event->exception) {
    Log::error($event->exception->getMessage());
}

Nomenclatura de Tabela Pivot Polimórfica

Tabelas morph pivot agora usam nomes no plural por convenção. Se as suas usam nomes no singular, renomeie as tabelas ou declare explicitamente o nome da tabela nas definições dos seus relacionamentos:

public function tags()
{
    return $this->morphToMany(Tag::class, 'taggable', 'taggables');
}

Concorrência do HTTP Client Pool

PendingRequest::pool() agora tem como padrão uma concorrência de 2 em vez de executar sequencialmente. Se seu código dependia de execução sequencial do pool (improvável, mas possível), você verá um comportamento diferente.

MySQL DELETE com JOIN

No lado da "surpresa agradável" — a gramática MySQL agora suporta queries completas de DELETE ... JOIN com ORDER BY e LIMIT:

DB::table('orders')
    ->join('users', 'orders.user_id', '=', 'users.id')
    ->where('users.is_inactive', true)
    ->orderBy('orders.created_at')
    ->limit(1000)
    ->delete();

Se você vinha escrevendo SQL puro para isso, pode parar.

O Passo a Passo de Atualização Que Eu Realmente Segui

Depois do meu desastre de sexta-feira, desenvolvi um processo de atualização mais disciplinado. Aqui está o que eu faria se estivesse começando do zero.

Passo 1: Trave sua baseline.

Rode sua suíte de testes completa no Laravel 12. Todos os testes devem passar. Se você tem testes falhando agora, corrija-os primeiro — você não quer ficar debugando se uma falha é um bug existente ou uma regressão da atualização.

php artisan test --parallel

Passo 2: Audite seu código em busca de padrões que quebram.

# Model boot queries
grep -rn "static function boot" app/Models/
grep -rn "static function booted" app/Models/

# JobAttempted listeners
grep -rn "exceptionOccurred" app/

# Morph pivot table references
grep -rn "morphToMany\|morphedByMany" app/Models/

Corrija tudo que essas buscas encontrarem antes de tocar no composer.json.

Passo 3: Verifique PHP 8.3+.

php -v

Sem atalhos aqui. Se seu pipeline de CI ou servidor de staging roda uma versão de PHP diferente do local, verifique esses também.

Passo 4: Atualize as dependências.

{
    "require": {
        "php": "^8.3",
        "laravel/framework": "^13.0"
    }
}
composer update

Se você encontrar conflitos, isole-os:

composer update laravel/framework --with-all-dependencies

Passo 5: Rode os testes novamente.

php artisan test --parallel

Preste atenção especial em testes de criação de models, testes de queue jobs e qualquer coisa envolvendo manipulação de TTL de cache.

Passo 6: Rode a análise estática.

./vendor/bin/phpstan analyse

Propriedades tipadas no Eloquent significam que o PHPStan pega coisas que não conseguia antes. Novos avisos após a atualização geralmente são problemas reais, não ruído.

Passo 7 (opcional): Use o Laravel Shift.

Se você quer automação, o Shift abre um PR com commits atômicos para cada mudança. Ele cuida do trabalho mecânico — bumps de dependência, renomeações de config, atualizações de assinaturas de método — para que você foque nas breaking changes que precisam de contexto humano.

Dica profissional: Eu mantenho um arquivo UPGRADE_NOTES.md em todo projeto. Após cada atualização de versão major, anoto o que quebrou e como corrigi. Três versões depois, esse arquivo me economizou mais tempo do que qualquer ferramenta automatizada.

O Cronograma de Adoção Que Realmente Funciona

Aqui está algo que ninguém comenta — você não precisa adotar cada funcionalidade nova no primeiro dia. A atualização em si é obrigatória (eventualmente). As novas funcionalidades são opcionais (para sempre).

Estou seguindo este ritmo nos meus projetos:

Semana 1: Atualizar, corrigir breaking changes, fazer deploy. Nada sofisticado. Apenas fique no verde com Laravel 13 usando seus padrões de código existentes.

Semanas 2-3: Substitua todo Cache::get()Cache::put() de extensão de TTL por Cache::touch(). Essa é a mudança de menor esforço e maior impacto que você pode fazer. Procure qualquer padrão de get-then-put com a mesma chave e converta.

Mês 2: Comece a converter models para PHP Attributes, um por PR. Comece com seus models mais tocados — os que aparecem nos mais diffs. Não faça uma conversão em massa. Revise cada um.

Mês 3: Adicione propriedades tipadas aos seus cinco ou dez models mais importantes. Rode o PHPStan após cada um. Corrija o que ele encontrar. Você vai se surpreender.

Contínuo: Todos os novos models, jobs e commands usam attributes e propriedades tipadas desde o primeiro dia. Código antigo converte naturalmente conforme você mexe nele por outros motivos.

Se seu time não está pronto para uma funcionalidade específica, pule-a. As correções de bugs do Laravel 12 rodam até agosto de 2026 e os patches de segurança até fevereiro de 2027. Essa é sua rede de segurança. Use-a.

O Que Isso Significa Para a Direção do Laravel

Quero dar um zoom out por um segundo porque acho que o Laravel 13 sinaliza algo sobre para onde o framework está indo.

Por anos, o Laravel construiu suas próprias abstrações em cima do PHP. Propriedades do Eloquent, assinaturas do Artisan, configuração por convenção. Isso funcionou brilhantemente quando o conjunto de funcionalidades do PHP era limitado. Mas o PHP 8.x mudou o jogo — attributes, enums, propriedades readonly, constantes tipadas — e a própria linguagem agora oferece soluções nativas para coisas que o Laravel costumava resolver com magia do framework.

O Laravel 13 é a primeira release que abraça seriamente essa mudança. Attributes não são apenas uma opção legal — são o time sinalizando que funcionalidades nativas do PHP são o caminho preferido daqui para frente. O novo attribute #[Unguarded], que não tem equivalente baseado em propriedade, confirma a direção: novas capacidades vão chegar como attributes primeiro.

Honestamente, não estou certo sobre tudo nesta release. O driver de banco de dados do Reverb parece ligeiramente prematuro — adoraria ver benchmarks com mais de 1.000 conexões antes de recomendar amplamente. E as propriedades tipadas do Eloquent, embora fantásticas para projetos novos, criam um padrão duplo em codebases existentes que vai levar anos para resolver.

Mas a trajetória está certa. Um framework que se apoia na sua linguagem em vez de abstrair sobre ela é um framework com um longo futuro. E um time que foca em estabilidade de produção em vez de funcionalidades de destaque é um time em quem eu confio com minha infraestrutura.

A Prova Está nos Meus Logs de Deploy

Nos três projetos que atualizei até agora, aqui está como os números ficaram:

  • Tempo de resposta: 6-8% mais rápido em média (melhorias do engine do PHP 8.3 mais limpeza do framework)
  • Tráfego de rede de cache: Queda de 35-42% no projeto onde converti extensões de TTL para touch()
  • Problemas encontrados pelo PHPStan: 14 bugs de tipo previamente invisíveis nos três projetos após adicionar propriedades tipadas
  • Tempo de atualização: 2-3 horas por projeto para a atualização em si; 1-2 horas adicionais para adotar Cache::touch() e converter o primeiro lote de models

Os ganhos de performance sozinhos justificam a atualização. As melhorias na experiência do desenvolvedor a tornam urgente.

Detalhe Valor
Release Q1 2026
PHP Obrigatório 8.3 no mínimo
Correções de Bugs Até Q3 2027
Patches de Segurança Até Q1 2028
Compatibilidade Symfony 7.4, 8.0
Breaking Changes Restrições no boot de models, nomenclatura de morph pivot, API do evento JobAttempted
Nova Instalação laravel new my-app --dev

O Que Eu Faria na Segunda de Manhã

Se você saísse deste artigo e fizesse uma única coisa amanhã, aqui está o que eu escolheria: abra um terminal, rode php -v, e se você vir 8.3 ou superior, crie uma branch e rode composer require laravel/framework:^13.0 --with-all-dependencies. Veja o que quebra. Corrija. Rode seus testes.

Não faça deploy. Não converta seus models. Não mexa nos seus padrões de cache. Apenas faça a atualização funcionar em uma branch para que você saiba exatamente o que está entre você e o Laravel 13. Esse conhecimento sozinho muda seu planejamento de "provavelmente deveríamos atualizar algum dia" para "aqui estão os quatro arquivos que precisamos mudar e leva uma tarde."

As melhores atualizações são entediantes. O Laravel 13 é uma atualização entediante da melhor forma possível — previsível, bem documentada, retrocompatível onde importa e genuinamente melhor nos lugares que afetam seu trabalho diário.

Seus deploys de sexta-feira vão te agradecer. Os meus já agradeceram — depois que eu corrigi aquele método boot(), claro.


Vamos Trabalhar Juntos

Quer construir sistemas de IA, automatizar fluxos de trabalho ou escalar sua infraestrutura de tecnologia? Adoraria ajudar.

Coffee cup

Gostou deste artigo?

Seu apoio me ajuda a criar mais conteúdo técnico aprofundado, ferramentas open-source e recursos gratuitos para a comunidade de desenvolvedores.

Tópicos Relacionados

Engr Mejba Ahmed

Sobre o Autor

Engr Mejba Ahmed

Engr. Mejba Ahmed builds AI-powered applications and secure cloud systems for businesses worldwide. With 10+ years shipping production software in Laravel, Python, and AWS, he's helped companies automate workflows, reduce infrastructure costs, and scale without security headaches. He writes about practical AI integration, cloud architecture, and developer productivity.

Discussion

Comments

0

No comments yet

Be the first to share your thoughts

Leave a Comment

Your email won't be published

9  x  7  =  ?

Continue Aprendendo

Artigos Relacionados

Ver Todos

Comments

Leave a Comment

Comments are moderated before appearing.

Learning Resources

Expand Your Knowledge

Accelerate your growth with structured courses, verified certificates, interactive flashcards, and production-ready AI agent skills.

Sample Certificate of Completion

Sample certificate — complete any course to earn yours

Engr Mejba Ahmed

Engr Mejba Ahmed

Claude Code Expert · Online

👋

Hey there!

Quick Actions

WhatsApp Instant reply

Chat on WhatsApp

+880 1723 741224 · Instant reply

Popular Questions

Engr Mejba Ahmed is connected
Engr Mejba Ahmed is typing...
Engr Mejba Ahmed avatar

✉ Want me to follow up? Drop your email

Engr Mejba Ahmed avatar

📞 Connect Directly

Choose how you'd like to reach me

WhatsApp

+880 1723 741224

Email

[email protected]

✓ Details sent! I'll get back to you shortly.

Powered by OpenAI

335+

Blog Posts

25

AI Courses

63

Projects

Services & Expertise

Pricing & Process

Learning & Resources

Connect & Support