Forge64 logo
All app types

Marketplace scaling

Marketplace scaling and launch checklist

A marketplace stays fast by paginating every list, indexing the main questions, and deferring heavy work until a measured trigger fires. At launch, apply 8 rules, watch 8 signals and hold the performance targets below.

Last checked

Rules to apply at launch

  • Pagination: Search, seller lists, orders, messages and reviews use keyset pagination on an indexed (sort_key, id) cursor; page size defaults to 24 and is capped at 50; no OFFSET and no count(*) of the full result set (show 'many' beyond a bound).
  • Search: Search is a single indexed query: tsvector + GIN for text, btree for category/price/status, a precomputed rank_key for ordering; facet counts come from a bounded query cached 60 s per filter combination.
  • Caching: Home, category and listing pages are rendered with ISR and edge cache (stale-while-revalidate); listing mutations revalidate the page tag; prices shown are display-only and always re-read from the database at checkout.
  • Idempotency: All order mutations are compare-and-set updates (UPDATE orders SET status = to WHERE id = $1 AND status = from) inside one transaction with the order_events insert; zero rows updated means the transition was already applied or invalid.
  • Rate limits: Per-IP and per-user limits on search, listing creation, message send, checkout creation, report submission and signup, stored in Postgres token buckets; new-account limits are stricter than established-account limits; exceeded limits return 429 and write nothing.
  • Fanout: Message fan-out is O(1): insert the message and increment one unread counter on the conversation row; inbox is one indexed range read; realtime delivery is polling or SSE per open thread only.
  • Realtime: Open conversation pages hold one SSE stream fed by LISTEN/NOTIFY on the conversation id, falling back to 10 s polling; closed tabs consume nothing.
  • Storage: Per-seller storage quota, max 12 images per listing, 10 MB per image; unreferenced uploads are swept after 24 h.

Performance targets

Performance targets for a marketplace
What to measureTarget
Search results APIp95 < 250 ms at 1M published listings, one indexed query plus one cached facet read
Listing page LCP< 2.5 s; TTFB < 200 ms from edge cache; images served as responsive widths
Order state transitionp99 < 100 ms, one compare-and-set update plus one event insert
Message sendp99 < 80 ms, two writes in one transaction
Escrow release throughputrelease job clears 1,000 due orders per run within 5 minutes, bounded by the per-run value cap

What to watch

  • Metric gmv take rate and fee cents: gross merchandise value, platform fee and net per day and category; the business health numbers.
  • Metric order state funnel: counts and dwell time per state; stuck pending_payment, delivered or disputed orders are visible.
  • Metric search latency and zero result rate: p95 latency and share of queries with no results, per category.
  • Log money-movement audit log: every charge, transfer, refund and hold with order id, idempotency key and actor; no card data or tokens.
  • Trace checkout to release trace: one trace id from checkout through webhook to transfer.
  • Slo checkout success: 99.5% of checkout attempts reach a definitive paid or failed state within 60 s.
  • Alert ledger drift or double payout: nonzero ledger drift, more than one payout per order, or a failed transfer retry loop pages immediately.
  • Alert dispute and chargeback rate: dispute rate above 1% of orders over 7 days, or a seller above 3x the platform average, triggers review and payout hold.

Recurring work

  • process_listing_media: runs queue (jobs kind=media). Guard: magic-byte and dimension check, max pixels, resource-limited container, idempotent by object_key, per-seller daily cap.
  • refresh_rank_keys: runs cron 15m. Guard: bounded batch of changed listings, set-based update, never a full table rewrite in one transaction.
  • rollup_seller_ratings: runs cron 5m. Guard: only sellers with reviews newer than the last run, upsert rating_avg and rating_count.
  • expire_unpaid_orders: runs cron 5m. Guard: cancels pending_payment orders older than 30 min and releases nothing else; idempotent by status predicate.
  • enforce_acceptance_deadlines: runs cron 15m. Guard: orders past accept_by are auto-cancelled and refunded through the state machine, capped batch.
  • rollup_seller_stats: runs cron hourly. Guard: recomputes today and yesterday only, upsert by (seller_id, day).

Add when the numbers say so

  • Read replicas: Route search, listing detail and seller storefront reads to read replicas once primary CPU or search p95 crosses the trigger; money paths always read the primary.
  • Search: Move to a dedicated search engine (OpenSearch/Typesense) with geo and learned ranking once Postgres search misses its latency budget.

Deferred until it is needed

Work to defer for a marketplace, with the trigger for adopting it
DeferredAdopt it when
Dedicated search engine (OpenSearch/Typesense) with geo and learned ranking> 5M listings or search p95 > 300 ms.
Read replicas for search and storefront readsprimary CPU > 60% sustained or read p95 > 200 ms.
Dedicated websocket tier for messaging and presence> 5k concurrent open conversations.
Multi-currency presentment and cross-border payoutsfirst non-home-country market launch.
ML fraud scoring and personalised rankingchargeback rate > 0.5% or > 100k monthly active buyers.

On Forge64

Forge64 matches your description to one of 12 reference architectures, writes the plan and data model into the project, generates the app, and runs a quality gate over the code before you see it. Each app gets its own Postgres database and sign-in with no per-user fee. Hosting on Forge Cloud and Forge Payments are rolling out.

Every metered resource on Forge64 has a hard cap, so a traffic spike stops at your limit instead of becoming a surprise bill. This is a reference design for the category, not a promise that every item is generated today. Built-ins such as email, background jobs, file uploads and search are coming soon, so anything here that needs them is something you add yourself for now.

FAQ

When should I worry about scale for a marketplace?
Not before a measured trigger fires. For example, for "Dedicated search engine (OpenSearch/Typesense) with geo and learned ranking": > 5M listings or search p95 > 300 ms.
What performance targets should a marketplace aim for?
Search results API: p95 < 250 ms at 1M published listings, one indexed query plus one cached facet read. Listing page LCP: < 2.5 s; TTFB < 200 ms from edge cache; images served as responsive widths. Order state transition: p99 < 100 ms, one compare-and-set update plus one event insert.
Does Forge64 cap my usage costs?
Yes. Every metered resource has a hard cap, and paid plans add an overage spend cap that you set.

Build your app with Forge64

One prompt to a running app with auth, database, hosting and payments. Start free, no credit card required.

Start building for free