php artisan key:generate writes APP_KEY=base64:... for AES-256-CBC. That value is not a deployment token you refresh for luck. Laravel uses it to encrypt cookies, the session payload when the driver needs it, and any Eloquent attribute you marked as encrypted. Change it and those blobs become noise.
Also Read: From an API JSON PHP payload to $fillable and $casts
New app versus old app
A new checkout, a new staging clone with an empty database, a local .env that never saw production data: generate a key. An app that already has users: do not. If you must rotate, Laravel supports APP_PREVIOUS_KEYS so decrypt can try the old one. Decrypt columns first if your version does not make that easy.
Also Read: Laravel: Can you run
The APP_KEY generator calls the same Encrypter::generateKey('AES-256-CBC') path artisan uses and returns a starter .env block. It is POST-only so the key never lands in a query string or an access log from this form. Treat the result like a password: not in tickets, not in screenshots, not in git.
Also Read: 220 billable days: turning a day rate into take-home pay
It is not related to the PHP version, until it is
The cipher is independent of whether you are on Laravel 10 or 13. The framework that boots the key must still match your interpreter; that is the compatibility matrix. Mixing a Laravel 13 key into a Laravel 8 box is not the usual failure mode. The usual failure mode is copying production .env into a demo and then regenerating the key “to be safe”.
If you are scaffolding a fresh app next to an upgrade, generate the key after Composer has installed, then run migrations. Order matters less than not pointing that key at yesterday’s ciphertext.
