Boot optimization candidate decisions
This record applies the admission rules from the Capell boot performance plan to eager provider work. A candidate is retained only when its owning phase is at least 10 ms or 3% of boot, focused behavior remains unchanged, and paired p75 does not regress.
The benchmark measures full in-process Laravel application creation and bootstrap. Child-process overhead remains diagnostic data and is not used to admit an optimization.
Profile evidence
Section titled “Profile evidence”Profiling on 24 July 2026 identified these first-party provider medians:
| Provider | Register p50 | Boot p50 | Decision |
|---|---|---|---|
| Core | 13.746 ms | 1.025 ms | Investigate registration candidates |
| Admin | 28.153 ms | 6.838 ms | Move to the separate admin-activation phase |
| Frontend | 1.023 ms | 14.229 ms | Preserve required listener and component lifecycle |
| Marketplace | 0.086 ms | 0.993 ms | Below the admission threshold |
The host did not satisfy the baseline stability gate during this investigation: load averages ranged from approximately 10 to 25 on 12 cores, the corrected production median spread reached 6.62%, and IQR/median reached 18.77%. Measurements below are therefore used only to reject regressions, never to claim an improvement.
Accepted closeout baseline
Section titled “Accepted closeout baseline”After the runtime lifecycle fixes were committed in a98aee15d, the host load
settled sufficiently to establish the required optimized-cache baseline. Each
profile was measured in three independent runs of 25 samples after five
warmups:
| Profile | Run p50 medians | Median spread | Worst IQR / median | Fingerprint |
|---|---|---|---|---|
| Production | 108.33, 107.39, 107.57 ms | 0.87% | 2.90% | 5fe3451cbfbeb16f022d9e38af5da5d3a4778563f9f26cb49ecffee170378ae9 |
| Public | 48.93, 47.94, 47.72 ms | 2.52% | 5.97% | f1b774cb70141e8eea9c1d6836eb69ab546e7bc3ee07c0da4dddf7f55ac77881 |
| Admin | 108.25, 108.34, 107.37 ms | 0.90% | 6.05% | a08050cf80923380cccd58e93671fc9a6f913ef2b285d3ef3cf6700a11be37d7 |
All three profiles satisfy the baseline gate of no more than 3% median spread and no more than 10% IQR/median. Tukey outliers remain in the retained raw samples and were not removed from the reported statistics.
Rejected: lazy Core built-in registries
Section titled “Rejected: lazy Core built-in registries”The candidate moved built-in renderable and linkable-content definitions into their singleton factories. Focused link, renderable, and boot-contract tests passed, but all three optimized production pairs regressed:
| Pair | p50 delta | p75 delta |
|---|---|---|
| 1 | +0.788 ms | +8.995 ms |
| 2 | +6.798 ms | +10.608 ms |
| 3 | +9.011 ms | +14.837 ms |
The candidate was reverted. It is not part of a delivery branch.
Preserved lifecycle work
Section titled “Preserved lifecycle work”- Core settings configuration must be ready before the Spatie settings provider consumes it. Dependency default configuration is loaded from the filesystem only when configuration is uncached; cached production boot keeps that fallback disabled.
- Core event-sourcing projectors, reactors, aggregates, and rollback validators must be registered before Spatie builds the projectionist.
- Frontend component contributors are already materialized through lazy container bindings.
- Frontend cache invalidation observers, the documented bounded wildcard model listeners, and route-reservation contributions must remain available during normal provider registration and boot.
- Marketplace provider time is below the candidate threshold.
No further independently deferable Core, Frontend, or Marketplace candidate was retained. Admin surface materialization and bridge boot are handled by the separate idempotent admin runtime activation change.
Safety outcome
Section titled “Safety outcome”This phase changes no runtime code. It preserves contribution ordering, anonymous rendering and cache contracts, wildcard listeners, routes, middleware, and extension declarations. No new database or filesystem work is introduced at boot.
CAP-0029 (2026-07-25)
Section titled “CAP-0029 (2026-07-25)”Measurement environment — not comparable to the CAP-0028 baseline
Section titled “Measurement environment — not comparable to the CAP-0028 baseline”CAP-0028’s figures come from the local Testbench boot benchmark. CAP-0029 was
measured against a real Laravel 13.22 install of the public Capell packages
(12 capell-app/* packages, MariaDB 10.5, Redis, demo content) on a shared
2-core host, with the benchmark confined to one core at nice 19.
Absolute milliseconds therefore do not transfer between the two documents; proportions do. Observed run-to-run spread on this host is roughly 45%, which means it cannot resolve differences below about 50 ms. Every verdict below is stated against that floor.
Profile evidence
Section titled “Profile evidence”Bootstrapper split ($kernel->bootstrap() is ~96% of boot):
| Bootstrapper | ms | % |
|---|---|---|
| BootProviders | 528.9 | 68.4% |
| RegisterProviders | 222.6 | 28.8% |
| RegisterFacades | 10.7 | 1.4% |
| HandleExceptions | 5.5 | 0.7% |
| LoadConfiguration | 4.8 | 0.6% |
| LoadEnvironmentVariables | 0.3 | 0.0% |
89 providers total: 14 first-party, 54 third-party, 21 Laravel.
Slowest boot contributors: Filament 221.6 ms (36.8%), Livewire 68.5 ms, FilamentTinyEditor 66.2 ms, HtmlCache 55.5 ms, LayoutBuilder 32.2 ms, BlockLibrary 29.2 ms. Slowest register contributors: CapellServiceProvider 92.5 ms (39.7%), PowerJoins 27.2 ms, AdminServiceProvider 17.9 ms.
End-to-end cached public homepage through nginx + PHP-FPM: n=20, min 56.0 ms, p50 65.3 ms, p95 78.8 ms. Render alone once booted is ~1.7 ms, so boot dominates a public request almost entirely.
Config caching is not the lever. LoadConfiguration is 0.6% of boot, which matches the measured result that caching config/routes/events/views moved CLI boot only 433 ms -> ~404 ms, inside noise.
Rejected: batch manifest registration and de-duplicated registry write
Section titled “Rejected: batch manifest registration and de-duplicated registry write”ManagesPackages::registerManifestPackages() collapsing per-package memo wipes
into one, plus removing the duplicate CapellPackageRegistry write already
performed by fill(). 12 interleaved pairs: baseline median 86.0 ms, candidate
median 86.3 ms. Reverted; not part of a delivery branch.
Rejected: process-constant probe memoisation
Section titled “Rejected: process-constant probe memoisation”Static memoisation of isLivewireV3(), isDiscoveringPackages() and
resolvePackagePath() on AbstractPackageServiceProvider. 10 interleaved
pairs: baseline median 104.3 ms, candidate median 97.7 ms, but paired median
delta +0.7 ms. resolvePackagePath() is called once per provider class per
boot, so there are no repeat calls to memoise. Reverted.
Rejected: Filament component caching as a measured win
Section titled “Rejected: Filament component caching as a measured win”filament:cache-components showed no improvement here: baseline median
229.8 ms vs cached median 279.8 ms, with fully overlapping ranges. The test
install has a nearly empty panel, so there is almost nothing to discover — this
result does not generalise to a production panel. It is still applied at
deploy time as documented Filament hardening, but no measured gain is claimed.
Accepted: targeted reflection in extension page navigation suppression
Section titled “Accepted: targeted reflection in extension page navigation suppression”CapellAdminManager::suppressExtensionPageNativeNavigation() built a full
ReflectionClass and walked hasProperty()/getProperty()/isStatic() to
reach one protected static property, forcing the whole Filament Page ancestor
property table to resolve. Replaced with a single targeted ReflectionProperty
plus a per-manager memo so a page registered twice does not pay twice.
| Pair | baseline | candidate | delta |
|---|---|---|---|
| 1 | 60.4 ms | 58.6 ms | -1.8 ms |
| 2 | 88.5 ms | 42.2 ms | -46.3 ms |
| 3 | 54.8 ms | 42.7 ms | -12.1 ms |
| 4 | 56.3 ms | 55.1 ms | -1.2 ms |
| 5 | 42.3 ms | 44.8 ms | +2.5 ms |
Mean 60.5 ms -> 48.7 ms (-19.5%), 4 of 5 pairs improved. Reflection remains
required because the property is protected; the behaviour, including the
silent no-op when the property is absent or non-static, is unchanged and pinned
by ExtensionsPageTest.
Findings recorded rather than fixed here
Section titled “Findings recorded rather than fixed here”- Provider boot performs database work. A
Schema::hasTable()probe runs during boot viaRuntimeSchemaState. It is alreadyscoped()and memoised per request, and a process-level cache was rejected as unsafe (test isolation and staleness across an Octane worker).config/deploy.phpin capell-app documents forcing an in-memory connection for its control plane because of this behaviour. - Deploys shipped with no warm caches. The build phase deleted
bootstrap/cache/filamentandbootstrap/cache/capelland never rebuilt them. Fixed in capell-app’sconfig/deploy.php. - CLI has no opcache.
opcache.enable_cli=0, so every artisan invocation recompiles all sources. Enabling it with a file cache measured CLI boot at 215-253 ms versus ~404 ms. - Admin-only providers boot on public requests. Filament, TinyEditor, Shield and Curator together are ~320 instrumented ms that a public page never needs. Deferring them is architecturally sound but was assessed as the last lever to pull, worth an estimated 25-35 ms real p50, and is not attempted here.
Verification boundary
Section titled “Verification boundary”Measured on one shared 2-core host; absolute values are host-specific. No
throughput or concurrency testing was performed, deliberately, because the host
also serves unrelated production sites. packages/core/tests/Arch/PackagesTest.php
could not be executed in this environment and its state is unverified.