Appearance
Order Capacity Management
Overview
Order Capacity Management controls how many orders and items your kitchen can handle per time slot. This prevents kitchen overload by limiting orders during busy periods.
Key Purpose: Ensure kitchen can fulfill all orders on time by limiting incoming orders based on capacity.
Purpose
This page lets you configure order and item limits per time slot so your kitchen is never overwhelmed, with support for rush protection, category-specific caps, and time-specific rules.
Key Concepts
- Time Slot: A fixed-duration window (e.g., 15 or 30 minutes) used to group orders for capacity counting. Orders are assigned to a slot based on their
order_prep_time, which is the requested time minus preparation time. - Rush Protection: A flexible limit system that allows extra low-value orders when the slot's total order value is below a configured threshold, preventing one large order from blocking the entire slot.
- Category-Specific Limits: Independent item caps per menu category (e.g., max 6 pizzas per slot for oven capacity), checked alongside global order and item limits.
- Time-Specific Rules: Override rules that apply different capacity limits during specific days and time ranges (e.g., reduced limits during lunch rush), with null fields inheriting from base settings.
- Clamp Behavior: During time-specific windows, rush protection's
allow_up_tovalue is automatically clamped to never exceed the time-specific order cap, ensuring time-specific rules are always the hard ceiling.
Actions
Enable/Disable Capacity Management
Toggle the master capacity switch. When disabled, all capacity checks are fully bypassed and all time slots within business hours are shown as available regardless of configured limits.
Configure Order and Item Limits
Set the maximum number of orders and/or total items allowed per time slot. Both limits are checked simultaneously and an order is rejected if any limit would be exceeded.
Set Up Rush Protection
Enable flexible ordering to allow extra low-value orders when a slot's total value is below the threshold. Configure the expanded order limit (allow_up_to) and the value threshold.
Add Time-Specific Rules
Create named rules that override default limits during specific days and time ranges (e.g., "Lunch Rush" Mon-Fri 12:00-13:30 with reduced order cap). Empty fields inherit from base settings.
Configure Category Limits
Set per-category item caps for slow-prep categories like pizzas or grilled items, ensuring equipment-constrained items do not bottleneck the kitchen.
Location
- Backoffice Route:
/online-settings - Applies to: Online Ordering (Pickup & Delivery) only
- Does NOT apply to: In-House / QR Ordering, Kiosk
- Backend Service:
app/Services/OrderCapacity/OrderCapacityService.php - Vue Component:
src/views/in-house/components/forms/OrderCapacityManagement.vue - Translations:
src/plugins/i18n/locales/modules/{lang}/online-settings.ts
Fields
Capacity Enabled (Master Toggle)
| Property | Value |
|---|---|
| Field ID | enabled |
| Label | Enable Order Capacity Management |
| Type | Toggle (Boolean) |
| Default | false |
| Required | No |
Description: Master toggle to enable or disable all order capacity management.
Business Logic:
- When
enabled=false: Hard bypass - all capacity checks are skipped - All time slots show as available regardless of configured limits
- Stale configuration values are ignored (prevents accidental enforcement)
- API response includes
capacity_disabled: trueflag for debugging
Customer Impact:
- Online Ordering: All time slots within business hours are available for selection
Why this matters: Prevents the scenario where a merchant disables capacity management but old configured values accidentally block orders.
Time Slot Duration
| Property | Value |
|---|---|
| Field ID | time_slot_duration_min |
| Label | Time Slot Duration |
| Type | Select |
| Options | 5, 10, 15, 20, 30, 45, 60 minutes |
| Default | 30 |
| Required | Yes |
| Validation | Must be one of the allowed values |
Description: The length of each time slot for capacity calculations. Orders are grouped into these time windows for capacity checking.
Business Logic:
- Orders are grouped into time slots of this duration
- Capacity limits are checked per slot
- Shorter slots = more precise control but harder to manage
- Longer slots = simpler but less granular control
Customer Impact:
- Online Ordering: Customers see available pickup/delivery times rounded to these intervals. With 15-minute slots, times show as 12:00, 12:15, 12:30, etc.
Examples:
- Fast food (high volume, quick prep): 15 minutes
- Standard restaurant: 30 minutes
- Catering/complex orders: 60 minutes
Limit Orders Per Time Slot (Toggle)
| Property | Value |
|---|---|
| Field ID | limit_orders_per_time_slot |
| Label | Limit number of orders per time slot |
| Type | Toggle (Boolean) |
| Default | false |
| Required | No |
Description: Enable to set a maximum number of orders that can be placed in each time slot.
Business Logic:
- When enabled, system counts orders per time slot
- New orders blocked when count >= limit
- Counts both paid and pending orders
Customer Impact:
- Online Ordering: When a time slot reaches its order limit, customers cannot select that time. They see the next available slot.
Related Fields: number_of_orders_per_time_slot
Number of Orders Per Time Slot
| Property | Value |
|---|---|
| Field ID | number_of_orders_per_time_slot |
| Label | Maximum orders per time slot |
| Type | Number |
| Default | 10 |
| Required | Yes (when toggle enabled) |
| Validation | min: 1 |
| Depends On | limit_orders_per_time_slot must be true |
Description: The maximum number of orders allowed in each time slot.
Business Logic:
- System counts all orders with
order_prep_timein the slot - Includes paid orders and pending payment orders
- New orders blocked when count >= this limit
Customer Impact:
- Online Ordering: If set to 5, only 5 customers can order for the 12:00-12:15 slot. The 6th customer sees "Time slot unavailable" and must choose another time.
Examples:
- Small kitchen: 3-5 orders per slot
- Medium kitchen: 8-12 orders per slot
- Large kitchen: 15-25 orders per slot
Troubleshooting:
- If customers report no available times → limit may be too low
- Check transaction history to see actual order volume per slot
- Consider increasing during slow periods, decreasing during rush hours
Protect Rush Capacity (Rush Protection)
Currency note: All monetary examples in this section use numbers only. The actual currency depends on your store configuration (€, $, etc.).
| Property | Value |
|---|---|
| Field ID | enable_flexible_limit_order_per_time_slot |
| Label | Protect rush capacity |
| Type | Toggle (Boolean) |
| Default | false |
| Required | No |
| Depends On | limit_orders_per_time_slot must be true AND number_of_orders_per_time_slot > 0 |
Description: Allow extra low-value orders when the slot's total value is still low. Prevents one large order from blocking your entire rush capacity.
UI Behavior (Configure → Summary pattern):
- Toggle ON + fields empty → shows input fields with hint "Configure how many extra orders to allow and the value threshold"
- Toggle ON + fields configured → shows summary: "Accept up to X extra orders, as long as slot total stays under [configured amount]" with Edit button
- Fields use placeholders instead of pre-filled defaults
Business Logic:
- If timeslot total value < threshold → allow up to
allow_up_toorders - Otherwise → use standard
number_of_orders_per_time_slotlimit - Clamp behavior: During time-specific windows,
allow_up_tois automatically clamped to never exceed the time-specific order cap. This ensures time-specific rules are always the hard cap. - Note: Rush protection never increases capacity beyond the highest order limit currently in effect (default or time-specific).
Customer Impact:
- Online Ordering: Small orders (like just drinks) may still be accepted even when the slot would otherwise be "full" for larger orders.
Merchant Explanation: "Rush protection lets you accept a few extra low-value orders, as long as the total value of the time slot stays manageable for your kitchen."
Related Fields: allow_up_to, value_threshold_per_time_slot
Rush Protection: Allow Up To
| Property | Value |
|---|---|
| Field ID | allow_up_to |
| Label | Allow up to X extra orders |
| Type | Number |
| Default | null (empty with placeholder "5") |
| Required | Yes (when rush protection enabled) |
| Validation | min: 1, should be > number_of_orders_per_time_slot |
| Depends On | enable_flexible_limit_order_per_time_slot must be true |
Description: Maximum orders allowed when the time slot's total value is below the threshold.
Business Logic:
- This is the "expanded" limit for low-value slots
- Clamp: During time-specific windows, this value is automatically reduced to match the time-specific order cap if it would exceed it
- Example: Base
allow_up_to=5, time-specific cap=2 → effectiveallow_up_to=2during that window
Rush Protection: Value Threshold
| Property | Value |
|---|---|
| Field ID | value_threshold_per_time_slot |
| Label | Slot total threshold |
| Type | Currency |
| Default | null (empty with placeholder showing example amount) |
| Required | Yes (when rush protection enabled) |
| Validation | min: 0 |
| Depends On | enable_flexible_limit_order_per_time_slot must be true |
Description: If the total order value in a time slot is below this amount, the rush protection limit (allow_up_to) applies instead of the standard limit.
Note: The value threshold always uses your store's configured currency (€, $, or any supported currency). No conversion is applied.
Business Logic:
- Sum of all order totals in slot compared to this threshold
- If sum < threshold → use
allow_up_tolimit - If sum >= threshold → use
number_of_orders_per_time_slotlimit
Examples (amounts in your store's currency):
- Set to 45: If slot has 30 in orders, rush protection allows extra orders
- Set to 100: More room for small orders before standard limit kicks in
Merchant Explanation: "Accept up to [X] extra orders, as long as the slot total stays under [your configured amount]."
Limit Items Per Time Slot (Toggle)
| Property | Value |
|---|---|
| Field ID | limit_items_per_time_slot |
| Label | Limit total items per time slot |
| Type | Toggle (Boolean) |
| Default | false |
| Required | No |
Description: Enable to set a maximum number of items (across all orders) that can be processed in each time slot.
Business Logic:
- Counts total quantity of all items in all orders for the slot
- More granular than order count
- Prevents kitchen overload from large orders
Customer Impact:
- Online Ordering: A single order with 20 items counts as 20 toward the limit. Large orders may be rejected or pushed to later slots.
Related Fields: number_of_items_per_time_slot
Number of Items Per Time Slot
| Property | Value |
|---|---|
| Field ID | number_of_items_per_time_slot |
| Label | Maximum items per time slot |
| Type | Number |
| Required | Yes (when toggle enabled) |
| Validation | min: 1 |
| Depends On | limit_items_per_time_slot must be true |
Description: The maximum total number of items allowed across all orders in each time slot.
Business Logic:
- Each item in an order counts toward this limit
- Modifiers do NOT count separately
- Quantity matters: 3x Pizza = 3 items
Examples:
- If limit is 15: Order A (5 items) + Order B (8 items) = 13 items
- Order C (3 items) would be rejected (13+3=16 > 15)
Enable Category-Specific Limits
| Property | Value |
|---|---|
| Field ID | enable_limit_specific_categories |
| Label | Set limits for specific item categories |
| Type | Toggle (Boolean) |
| Default | false |
| Required | No |
Description: Enable to set different capacity limits for specific menu categories. Useful when some items take longer to prepare.
Business Logic:
- Each category can have its own item limit per slot
- All category limits are checked independently
- An order is rejected if ANY category limit would be exceeded
Customer Impact:
- Online Ordering: If pizza limit is reached but burger limit is not, customer can still order burgers but not pizzas.
Related Fields: limit_specific_categories
Category-Specific Limits
| Property | Value |
|---|---|
| Field ID | limit_specific_categories |
| Label | Category limits |
| Type | Array of objects |
| Required | No |
| Depends On | enable_limit_specific_categories must be true |
Item Schema:
json
{
"category_id": "string (MongoDB ObjectId)",
"category_name": "string",
"number_of_items_per_time_slot": "number (min: 1)"
}Description: Define maximum items per time slot for specific categories.
Business Logic:
- For each category, count items in that category across all orders in the slot
- Each category limit is checked independently
- Order rejected if any category limit exceeded
Examples:
- Pizzas: 5 per slot (oven capacity)
- Fries: 10 per slot (fryer capacity)
- Drinks: 20 per slot (easy to prepare)
Time-Specific Rules
| Property | Value |
|---|---|
| Field ID | time_specific_rules |
| Label | Time-specific capacity rules |
| Type | Array of objects |
| Required | No |
Item Schema:
json
{
"name": "string (e.g., 'Lunch Rush')",
"time_range": {
"from": "string (HH:mm)",
"to": "string (HH:mm)"
},
"active_days": ["Monday", "Tuesday", ...],
"number_of_orders_per_time_slot": "number",
"number_of_items_per_time_slot": "number (optional)",
"limit_specific_categories": [
{
"category_id": "string",
"category_name": "string",
"number_of_items_per_time_slot": "number"
}
]
}Description: Override default capacity settings during specific time periods. Perfect for managing rush hours.
UI Behavior:
- Time-specific rules only show order/item limit overrides (simplified UI)
- "Leave empty to use default": If a field is left empty (null), the base default value is used
- Category limits and rush protection are always inherited from base settings
Business Logic:
- Rules are checked by day and time
- If current time matches a rule, that rule's limits are merged with base settings:
- If time-specific value is set (>0) → override base
- If time-specific value is null/empty → inherit from base
- Rush protection always inherited from base (clamped to time-specific cap)
- Category limits always inherited from base
- Multiple rules can exist; first matching rule applies
Clamp Behavior:
- During time-specific windows, rush protection
allow_up_tois automatically clamped to never exceed the time-specific order cap - Example: Base
allow_up_to=5, time-specific cap=2 → effective limit is 2 (not 5) - Merchant explanation: "Rush protection can help within a time-specific window, but it will never exceed the rush-hour limit you set."
Examples:
- Lunch Rush (11:30-13:30, Mon-Fri): Reduce to 3 orders/slot
- Weekend Dinner (18:00-21:00, Sat-Sun): Reduce to 5 orders/slot
- Happy Hour (16:00-18:00, Mon-Thu): Increase drinks category to 30/slot
Business Logic
How Limits Work Together
All enabled limits are checked simultaneously. An order is rejected if ANY limit would be exceeded.
Enforcement Order:
- Check if order count limit would be exceeded
- Check if total items limit would be exceeded
- Check if any category-specific limit would be exceeded
- If time-specific rule applies, use those limits instead of defaults
- If flexible ordering enabled and slot value < threshold, use flexible limit
Time Slot Calculation
How the system determines which time slot an order belongs to:
- Take the order's requested pickup/delivery time
- Subtract preparation time to get
order_prep_time - Round
order_prep_timedown to nearest slot boundary - That slot is where the order's capacity is counted
Example:
- Customer requests pickup at 12:45
- Preparation time is 20 minutes
order_prep_time= 12:25- With 15-minute slots, order counts toward 12:15-12:30 slot
Split Order Handling
When an order is too large for one slot, it can be split across multiple slots:
- Calculate how many items can fit in current slot
- If not all items fit, check next available slot
- Continue until all items are allocated
- Order is assigned to first slot, but capacity counted in all slots
Backend Implementation
Key methods in OrderCapacityService.php:
checkOrderCapacity()- Validates if order can be placedgetOrderCapacity()- Gets capacity settings for locationgetSentAt()- Calculates when order should be sent to kitchencalculateSplitTimeslots()- Handles large orders across slotsgetTimeslotAvailableCapacity()- Checks remaining capacityisWithinBusinessHours()- Validates against business hours
Customer Impact
Online Ordering
- Customers see only available time slots
- Full slots are hidden from selection
- If no slots available, message shows "No delivery/pickup times available"
- Large orders may show later times if current slots are near capacity
- Time slots respect business hours
KDS (Kitchen Display System)
- Kitchen sees orders grouped by time slot
- Helps staff prepare for upcoming rush periods
- Orders appear with their scheduled time
Relations
Depends On
- Business Hours: Capacity only applies within business hours
- Locations: Each location has its own capacity settings
- Menu Categories: Category limits reference menu categories
Affects
- Online Ordering: Determines available time slots for pickup/delivery
- Transactions: Orders tagged with time slot info
Related Features
Business Rules
- Order capacity only applies to online ordering (pickup and delivery); it does not affect kiosk orders, in-house/QR orders, or POS orders. Kiosk and online ordering dine-in ("ForHere") orders bypass capacity checks entirely.
- When capacity management is disabled (
enabled=false), all configured limits are fully bypassed -- stale configuration values are ignored and no capacity checks are applied. - All enabled limits (order count, item count, category-specific) are checked simultaneously; an order is rejected if any single limit would be exceeded.
- The system uses database-level locking with retry logic when updating transaction capacity data to prevent race conditions during concurrent order placement.
- After a transaction is assigned to a time slot, the cache for that slot is immediately cleared to prevent stale reads from allowing over-capacity orders.
FAQs
- Does order capacity affect kiosk or POS orders? No. Capacity management only applies to online ordering (pickup and delivery). Kiosk, QR ordering, and POS orders are not subject to capacity limits.
- What happens when I disable capacity management? All limits are fully bypassed immediately. Old configured values are ignored and all time slots within business hours become available. The API response includes a
capacity_disabledflag for debugging. - How does the system handle concurrent orders? The backend uses database-level locking with retry logic to prevent two orders from being assigned to the same slot when it is at capacity. If lock acquisition fails after retries, the customer sees a "try again in a moment" message.
- Can a large order be split across multiple time slots? Yes. When an order is too large for one slot, the system calculates how many items fit in the current slot and allocates the remainder to subsequent slots. The order is assigned to the first slot but capacity is counted across all affected slots.
- What is the difference between time-specific rules and rush protection? Time-specific rules set hard limits for specific days and time ranges. Rush protection allows extra low-value orders within those limits when the slot value is still low. Time-specific rules always take priority and rush protection can never exceed a time-specific cap.
Troubleshooting
Problem: Customers report no available time slots
Possible Causes:
- Order limits set too low for actual demand
- Time-specific rule reducing capacity during peak hours
- Business hours not configured correctly
- All slots filled with existing orders
Solutions:
- Check current order volume in Transactions
- Temporarily increase limits during testing
- Review time-specific rules for conflicts
- Verify business hours include expected ordering times
- Check if there's a backlog of pending orders
Problem: Kitchen is overwhelmed despite capacity limits
Possible Causes:
- Limits set too high
- Category limits not configured for slow-prep items
- Time slot duration too long
- Large orders not being split properly
Solutions:
- Reduce orders per slot limit
- Add category-specific limits for complex items (pizzas, grilled items)
- Use shorter time slots (15 min instead of 30)
- Add time-specific rules for rush hours
- Review item preparation times
Problem: Orders being rejected unexpectedly
Possible Causes:
- Multiple limits active and one is being hit
- Time-specific rule with stricter limits
- Category limit reached for specific item
- Pending orders counting toward capacity
Solutions:
- Check which limit is being hit in order logs
- Review all active limits and time-specific rules
- Consider if all limits are necessary
- Check for stuck pending orders
Examples
Small Pizza Shop
json
{
"time_slot_duration_min": 15,
"limit_orders_per_time_slot": true,
"number_of_orders_per_time_slot": 4,
"limit_items_per_time_slot": false,
"enable_limit_specific_categories": true,
"limit_specific_categories": [
{
"category_name": "Pizzas",
"number_of_items_per_time_slot": 6
}
]
}Explanation: Max 4 orders per 15 minutes, but never more than 6 pizzas. This accounts for oven capacity (typically 2-3 pizzas at a time, ~5 min each).
Busy Lunch Restaurant
json
{
"time_slot_duration_min": 30,
"limit_orders_per_time_slot": true,
"number_of_orders_per_time_slot": 15,
"time_specific_rules": [
{
"name": "Lunch Rush",
"time_range": { "from": "12:00", "to": "13:30" },
"active_days": ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"],
"number_of_orders_per_time_slot": 8
}
]
}Explanation: Normal capacity is 15 orders/slot, but during lunch rush it drops to 8 to maintain quality and prevent delays.
Coffee Shop with Flexible Ordering
json
{
"time_slot_duration_min": 15,
"limit_orders_per_time_slot": true,
"number_of_orders_per_time_slot": 10,
"enable_flexible_limit_order_per_time_slot": true,
"allow_up_to": 15,
"value_threshold_per_time_slot": 50
}Explanation: Normally max 10 orders per slot. But if the slot's total value is under 50 (in your store's currency, e.g. €50 or $50), allow up to 15 orders. This maximizes throughput for quick drinks while protecting against too many complex food orders.
Common Merchant Questions
1. "Why are orders still coming in even though I set a limit?"
Order capacity only applies to online ordering (pickup & delivery). It does not affect in-house orders, QR ordering, kiosk, or POS orders.
2. "I turned order capacity off — are my old limits still active?"
No. When order capacity is disabled, all limits are fully bypassed. Old values are ignored and no capacity checks are applied.
3. "What's the difference between a time-specific rule and rush protection?"
- Time-specific rules set hard limits for specific days and times (e.g. Friday 18:00–20:00).
- Rush protection allows a few extra low-value orders within those limits when the kitchen can still handle them.
4. "Which one wins if they overlap?"
Time-specific rules always win. Rush protection can never exceed the limit set by a time-specific rule.
5. "If I leave a field empty, what happens?"
Empty fields mean "use the default setting", not zero. Limits are only enforced when a value is explicitly set.
6. "Why does rush protection use a value threshold instead of item count?"
Because value is a good proxy for kitchen workload. Many small, low-value orders are often faster to prepare than a few large, complex ones. The threshold is always evaluated in your store's currency.
7. "Does rush protection apply all the time?"
No. It only applies:
- When enabled
- When properly configured
- And only within the active order capacity limits
8. "Can rush protection increase my limits during busy hours?"
No. Rush protection can help during quieter moments, but it never increases limits during busy or restricted time windows.
9. "Why do I see time slots available even when capacity is off?"
When capacity is disabled, all available business hours are shown as open. This is expected behavior.
10. "What happens if I set limits that are too strict?"
If a time slot is full, customers will be asked to choose a later time — or confirm a delayed order if enabled.
11. "Is the value threshold per order or per time slot?"
It's per time slot, not per order. The total value of all orders in the slot is evaluated together.
12. "Does this affect POS / phone orders?"
No. Order capacity only affects online orders placed through your ordering website or app. Orders entered directly in the POS are not blocked.
13. "Why does a time slot disappear instead of showing 'full'?"
Full time slots are hidden to guide customers toward available times and avoid failed checkouts. This reduces frustration and abandoned orders.
14. "What happens if my preparation time changes?"
Capacity is calculated using preparation time. If you increase prep time, orders may shift into earlier time slots for capacity counting. This can affect availability during busy periods.
15. "Why does a small order get accepted when a larger one is rejected?"
Because rush protection allows extra low-value orders when the slot total is still under the threshold. Larger orders push the slot value over the threshold faster.
16. "Can I use rush protection without limiting orders per slot?"
No. Rush protection only works on top of an order limit. It adjusts how the limit behaves; it does not replace it.