Velocity and performance for integrations
This page is for integrators whose code runs on sites served by Velocity, the persistent-worker web server that
is part of Exponential 6.0.15 (se7enxweb/exponential-velocity, started with php bin/php/console exp:velocity).
Velocity boots the kernel once and keeps workers alive, so it answers far faster than one PHP process per request;
it also changes a few things an integration must respect
(Velocity: running Exponential in a persistent-worker web server).
Contents
- What changes for integration code
- Deploying a changed integration
- API answers and the response cache
- Where the load should run
- Measuring
What changes for integration code
| Topic | With PHP-FPM | With Velocity | What to do |
|---|---|---|---|
| Classes | Loaded per request | Loaded when the server starts; workers inherit them | Restart Velocity after adding or changing classes |
| Static properties | Empty at each request | Can survive from one request to the next | Reset request state at the start of each request; never keep the current user or a credential in a static |
| Listeners and registrations | Attached per request | Attached once from settings | Never attach listeners in code that runs per request: they accumulate |
| Settings | Read per request (with the INI cache) | Read at start and cached | Clear the INI cache (--clear-tag=ini) and restart after settings changes |
| Long calls | Hold one FPM child | Hold one worker | Keep remote calls out of requests; defer to cronjobs |
The kernel itself shows the pattern: the REST layer resets the API key state at the start of every request
(expApiKeyRest::reset()), because a persistent worker would otherwise remember the previous request's key.
Deploying a changed integration
php bin/php/console exp:velocity deploy --dry-run --allow-root-user # what it would do
php bin/php/console exp:velocity deploy --allow-root-userexp:velocity deploy regenerates the extension autoloads, clears the INI cache and the template caches, reloads
PHP-FPM, restarts Velocity, and then clears the content and response caches, in that order, stopping at the first
failure (Deploying). Without it, do the same steps by
hand; clearing caches before the reload lets pages rendered by the old code be cached again.
A new class that a setting names (a login handler, a workflow event type, a search engine) must exist in the workers before the setting is active: deploy the code and restart first, then switch the setting on.
API answers and the response cache
Velocity's response cache is off until enabled. When it is on, it keeps a GET answer only when the request
carries no Authorization header and no session cookie, the response sets no cookie, and Cache-Control says
neither no-store nor private (Velocity response cache).
For integrations this means:
- Requests with an API key, OAuth token or
expservicestoken (Authorizationheader) are never answered from the cache. - Anonymous
GETcalls (a public RSS feed, an anonymousezjscorecall) may be answered from the cache for the page's lifetime; theX-Cache: HITandAgeheaders say so. SendCache-Control: no-storefrom endpoints of your own that must always be fresh. - After an import, clear the response cache (
php bin/php/console exp:velocity cache clear --apply) if anonymous clients must see the change at once (Caching after imports).
Where the load should run
- Bulk work on the command line. Imports, exports and reindexing run as CLI scripts or cronjob parts, not as thousands of HTTP requests; they do not take workers away from visitors.
- Rate limits per server. The API key rate limit (
RateLimitPerMinute) is counted in APCu per PHP-FPM pool or per Velocity server; with several servers the effective limit is higher. Do not rely on it as a capacity plan. - Nice the batch. Run large imports with a lower priority (
nice -n 15 php ...) on a shared host. - Off-peak. Schedule full syncs at quiet hours; a large import can clear every view cache (Caching after imports).
Measuring
php bin/php/console exp:velocity statusand the Velocity control panel show the workers and their load (Velocity control panel).php bin/php/benchmark.php --helpdescribes the benchmark command for request throughput (Benchmarking).- Time your own runs and log the duration in the summary line; a run that gets slower each week is the first sign of a growing table or a missing index.
Related pages
- Velocity: running Exponential in a persistent-worker web server
- Deploying with Velocity for app creators
- Velocity is part of Exponential 6.0.15
- Caching after imports
- Free documentation: this page is free to copy, translate and improve under the GNU FDL 1.3.
Become an Exponential Partner
Partners share their information, provide funding, contribute back and develop the products with us, and that is how Exponential grows. A partner website and dashboard are planned for mid-2027: please become a partner today to speed up our growth rate and land new features faster.