Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Preload Laravel Package

laragear/preload

Laragear Preload helps Laravel apps use PHP OPcache preloading. It generates a preload script, lets you include application and vendor files, and provides Artisan commands to build and refresh the preload list for faster bootstrapping.

View on GitHub
Deep Wiki
Context7

Getting Started

laragear/preload generates a PHP preload script for OPcache (opcache.preload), so that a chosen set of files is compiled once when PHP-FPM boots instead of on every request. It is a build/deploy-time tool, not a request-time one — you will touch it on deploys, rarely in application code.

  1. Install and publish the config.

    composer require laragear/preload
    php artisan vendor:publish --tag=preload.config
    

    Open the published config/preload.php first. It defines what gets preloaded (autoloader, vendor paths, app paths, ignore rules), where the script is written (preload.php at the project root by default), and any discovery/tracing options.

  2. Confirm OPcache is available in the SAPI you actually serve with:

    php -i | grep -i opcache
    
  3. Generate the script.

    php artisan preload:generate
    

    This writes the preload.php file. Look at the generated file — it is plain, readable PHP and is the single best documentation of what the package is doing.

  4. Wire it into php.ini for the FPM pool:

    opcache.preload=/var/www/app/preload.php
    opcache.preload_user=www-data
    

    Then restart/reload PHP-FPM. Preloaded scripts cannot be unloaded at runtime, so a reload is mandatory after every change.

  5. Verify it took effect. Preload statistics are exposed by PHP itself:

    opcache_get_status()['preload_statistics'];
    // ['scripts' => [...], 'memory_consumption' => ..., 'classes' => n, 'functions' => n]
    

First use case: preload the handful of framework and app files that are included on every request (service providers, base classes, heavily used support classes), confirm via preload_statistics that they are actually in shared memory, and benchmark before/after. Start small and measurable; do not paste your entire vendor/ directory in on day one.

Implementation Patterns

Curated list (default choice). Maintain an explicit, version-controlled set of files in config/preload.php or a dedicated list file. This is deterministic, reviewable in a diff, and safe to run in CI. Grow it iteratively: profile what is included on each request, add the top offenders, re-measure. This is the pattern most teams should end up with.

Discovery/tracing, then prune. Rather than reasoning about includes by hand, exercise the application so the package can observe which files were actually loaded, export that list, and turn it into the preload set. Practical workflow:

  • Enable the discovery/tracing option (and its middleware, if your version ships one) in a local or staging environment only.
  • Hit a representative set of routes — login, dashboard, the heaviest index pages — plus php artisan boot paths you care about.
  • Export/generate the collected list, then hand-prune it: drop anything environment-specific, anything with side effects, and anything that changes per deploy.
  • Commit the pruned result as a static list. Treat the tracer as a generator, never as a production feature.

Deploy pipeline integration. Generate at build time, not on the live host if you can avoid it:

  • Run php artisan preload:generate as part of the release build, using the same PHP minor version as production.
  • Ship the resulting preload.php alongside the release (commit it, or produce it as a build artifact so it is diffable).
  • In the deploy step: swap the release, then systemctl reload php-fpm (or equivalent). The reload must come after the code swap, otherwise you preload the previous release's bytecode.
  • Keep a one-line rollback: comment out opcache.preload and reload. This recovers instantly from a bad preload.

Environment-scoped configuration. Preloading is a production/staging concern. Keep it off (or generating a trivial script) in local development, where you edit files constantly and want fast feedback rather than a stale shared-memory snapshot. Drive the file list from config so each environment can have a different set.

Programmatic extension. For lists that depend on runtime discovery (installed packages, feature flags, module registries), append entries from a service provider via the package's facade rather than hardcoding them in config. Keep this logic pure — no database calls, no HTTP — because it runs at preload/startup time.

Sanity check in CI. Add a job that generates the script and boots PHP with it in a container matching production, failing loudly on any fatal. A broken preload script takes down the entire FPM pool, so this check is cheap insurance.

Gotchas and Tips

A bad preload file is a hard outage, not a warning. Syntax errors, missing files, or unreadable paths cause PHP-FPM to fail to start — every worker, not one request. Always validate in staging first, and always keep the php.ini change as the easily-reverted switch.

Use absolute paths, and mind the user. opcache.preload needs an absolute path. If the FPM master runs as root, PHP refuses to preload without opcache.preload_user set to the pool user. The preload file must be readable by that user at startup.

Top-level code executes at preload time. Preloading is not "cache this file for later" — the file's top-level statements run once in the FPM master context. Files that echo, read env vars, register globals, open connections, or define conditionally-guarded classes can behave very differently here than in a request. Skip anything not purely declarative.

Ordering and duplicate declarations. Classes must be preloaded after their parents, interfaces, and traits. Two paths to the same file (symlinked release directories, realpath mismatches) can produce "Cannot declare class … name is already in use" at startup. Use consistent, resolved paths, and check that opcache.revalidate_path matches how your deploys are laid out.

Never preload churn. Compiled Blade views, generated proxies, per-deploy cache artifacts, and anything that changes frequently bloat shared memory and give zero benefit. Same for large chunks of vendor/ that only load on rare code paths — measure, don't guess.

CLI is not FPM. php artisan preload:generate runs under the CLI binary with the CLI php.ini. Different extensions, different ini values, different user. Always validate the generated file under FPM (a staging reload) rather than trusting the CLI run.

Preloaded scripts are immutable for the process lifetime. opcache_reset() will not swap them out. Every code change that touches a preloaded file requires an FPM reload. If you see "old code still running" after a deploy, this is almost always why.

Memory pressure is real. Preloading pulls everything into shared memory up front. Watch opcache_get_status()['preload_statistics']['memory_consumption'] against opcache.memory_consumption; if you start seeing cache-full restarts, either raise the limit or trim the list. There is a point of diminishing returns — preloading more than the hot path can make things slower to start and no faster to serve.

Keep tracing off outside local/staging. Discovery modes accumulate state per request; left enabled in production they are a memory leak and an information-disclosure surface.

Extension points worth knowing: the published config (file list, ignore rules, output path), the generation command (safe to wrap in your own deploy script), and the facade for appending entries at boot. Between those three you can cover nearly every case without forking.

On v4.x specifically: this is a new major. If you are coming from v3, read the changelog before upgrading — config keys, command names, and the shape of the generated script have changed between majors historically. Regenerate preload.php from scratch after upgrading rather than reusing the old artifact, and re-run your staging boot check, since a stale generated script combined with a new API is the most likely upgrade failure mode.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
robertmarney/lara-hierarchial-collections
simonschaufi/rule-doc-generator
emissaoja/emissaoja
blackbricksoftware/gravityforms-civicrm-form-processor
al-rahabi/fancy-crud
jinas/dhivatar-component
mltstephane/laravel-quality
bernskiold/laravel-talentlms
bernskioldmedia/laravel-form-architect
youbar/easy-crud
c-point-labs/laravel-hostyourai
dbravoan/dbcms-admin-theme-dbcms
dbravoan/dbcms-theme-db-cyber
dbravoan/dbcms-blocks-basic
dbravoan/dbcms-module-content-audit
dbravoan/dbcms-module-ai-assistant
paygate-to/paygate-php
padosoft/askmydocs-connector-base
defstudio/supercharged-carbon
bernskioldmedia/laravel-matomo