Documentation Index
Fetch the complete documentation index at: https://docs.launchmystore.io/llms.txt
Use this file to discover all available pages before exploring further.
Function Active Limits
LaunchMyStore caps how many actively-installed apps a single shop can have running per function type. The cap is enforced at install time — if installing your app would push the merchant over the limit for any of the function types it ships, the install fails with HTTP 409.Why the caps exist
Every active function of a given type is dispatched on everyverifyCart and addClientOrder call. Without an upper bound, a
shop could:
- Compound discounts unbounded — 50 active discount functions all emitting overlapping reductions on the same lines, blowing through the merchant’s margin.
- Stack payment customizations that rename or hide the same method in conflicting ways, producing UI that flickers as each function’s override fires.
- Run order validation rules that each adds latency to checkout; ten 500-ms WASM modules add 5 seconds to every checkout submit.
- Multiply WASM CPU cost for cart-transform pipelines that compete for the same line ids.
cart_transform, order_validation) and generous for low-cost,
additive types (discount).
Per-type limits
These caps are defined inFUNCTION_ACTIVE_LIMITS in the backend
apps/functions/function-contracts.ts and applied by
apps.service.installApp().
| Function type | Active cap | Rationale |
|---|---|---|
cart_transform | 1 | Cart transforms can merge/expand lines; multiple transforms ordering across each other is non-deterministic. One active app at a time keeps the pipeline predictable. |
discount | 25 | Discounts are additive and applied through the documented discountApplicationStrategy (FIRST / MAXIMUM / ALL); merchants commonly stack many automatic + code-based discounts. |
shipping_rate | 5 | Each function adds rates to the same option list — too many makes checkout cluttered. |
payment_customization | 5 | Renames, hides, and reorders compose, but conflicts (two apps renaming the same method) produce undefined order. |
delivery_customization | 5 | Same composition concerns as payment customization. |
order_validation | 5 | Validation runs on every cart change and order submit — latency is multiplicative. |
fulfillment_constraints | 5 | Intersected per line; more functions means smaller allowed-location sets and a higher risk of unfulfillable orders. |
local_pickup_options | 5 | All pickup options are merged into one customer-facing list. |
pickup_point_options | 5 | Same merge semantics as local pickup. |
Caps apply to active installs only. Installing an app, then
disabling its functions (uninstall, suspend, or developer-side
toggle) frees the slot for another app of the same type.
What “active install” means
A function counts toward the cap when all of these are true for an app installed on the shop:- The app’s installation row has
status = 'active'(notuninstalled,suspended, orpending). - The function entry exists in the installed version’s manifest.
- The function hasn’t been disabled by the merchant (per-function toggle in admin).
draft or review status on the developer dashboard don’t
count — only published apps installed on a merchant’s shop.
Hitting the cap
When a merchant tries to install an app that would push them over the cap for any function type the app contributes, the backend returns:Freeing up a slot
Merchants have three ways to free a slot for a competing app:Disable the specific function
Some apps expose per-function toggles in their admin UI. Disabling
a function de-activates that one slot without removing the app.
Edge cases
Multi-function apps
Multi-function apps
An app that contributes a
cart_transform AND a discount
function consumes one slot from each cap. Installing it requires
both caps to have headroom — it’ll fail with 409 even if only one
is full.Reinstall a previously-uninstalled app
Reinstall a previously-uninstalled app
Uninstalling sets the installation row to inactive; the slot frees
immediately. Reinstalling counts the same as a fresh install for
cap purposes.
App version updates
App version updates
Updating an installed app to a new version that adds a new function
type re-checks the cap for that type. If full, the update fails
with 409 and the previous version stays active.
Developer staging stores
Developer staging stores
Caps apply per shop, including the developer’s own dev shop. A
developer testing 10 discount-function variants in one shop must
uninstall some between iterations or stay under 25 active installs.
What about fulfillment_location_rule?
What about fulfillment_location_rule?
Order-routing rules dispatched as type
fulfillment_location_rule
are JSON matchers — not WASM functions — and don’t count toward
any cap. See Order Routing.Designing within the caps
If you’re publishing an app that ships any function, design with the caps in mind:- Bundle related logic into one function where possible. One
discountfunction that picks the right rule based on cart contents beats five thin functions each gated on its own condition. - Use
inputFieldsso your function dispatches faster and is less likely to be cited by merchants as “the slow one.” See Input fields. - Document the cap in your marketplace listing if your app
contributes a
cart_transform— merchants can have only one such app and need to know before committing. - Surface conflicts. If your discount function produces surprising results when another app is also installed, log a warning to the developer dashboard via the test endpoint.
See also
Functions Overview
The nine function types and what each one does.
Input fields
Reduce dispatch cost by projecting the input down to only the
fields your function reads.
App Manifest
Manifest fields for declaring functions.
App Tiers
Tier-based API rate limits run alongside the function caps.