Skip to main content

Chapter 18 — Snapshots & the Config Layers

Attend onboarding guide · ~6 min read · ↑ Back to contents

Chapter 17 built the raw inventory. But the fan-facing home page can't recompute everything on every visit — so there's a second, pre-baked copy. This chapter covers that snapshot, and then the four config layers that decide how a store behaves.

The home-page problem

Think about what the home page must show per event: the available suites, a "from" price, a breakdown by suite type. Computing that live means walking the whole pipeline — active program → inventory type → pricing → build the suites → total them up → add-ons — for every request.

Now a team sends a marketing blast and 1,000 fans land at once. Even with caching, the first wave all arrive before the cache is warm, so they each trigger the full computation — a cache stampede that can flatten the server.

The fix: an inventory snapshot

So Attend pre-computes it. A cron job runs about every 5 minutes and writes a snapshot per event:

  • Starting price = the cheapest currently-available option for that event.
  • It's stored per suite type too (e.g. cheapest Club Level vs cheapest Mezzanine).

The deliberate trade-off: the snapshot is not real-time. It can be up to ~5 minutes stale. That's the price of surviving a traffic spike — the home page reads a ready-made answer instead of doing "the next six steps" on demand.

⚠️ Scope: this is a Premium / Suite-Level mechanism. The snapshot cron iterates only Premium schemas (getActivePremiumSchemas()) and pre-computes suite-level programs — which is why the example above is all about suites and suite types. Plain Flex seat-level stores don't use a pre-baked snapshot; their seat inventory is read live via getInventory (with normal caching).

Example: the Warriors email 50,000 fans at 10am. Thousands open the store in the same minute, but the home page just serves each of them the latest snapshot — available suites and "from" prices — without recomputing pricing per visit.

The four config layers

A store's behavior is decided by configuration at four different scopes. Knowing which layer owns a setting saves a lot of hunting.

LayerScopeWhat it holds
Base configGlobal (per store, doesn't change per program)auth token expiry times, the team's time zone
Program configPer programinventory type, pricing mode, pack structure (Chapter 16)
Client configPer clientwhich ledger and account groups to use (wired but not active yet)
Frontend configFront enda pure data dump of UI values (languages, per-page settings)

Base config holds the global defaults that don't change when you swap programs — for example accessTokenExpiry: '15m', refreshTokenExpiry: '30d', and the team timezone.

Two are worth a closer look:

  • Base config vs program config. Base config is the stuff that shouldn't change when you swap programs — token lifetimes, the team's time zone. Program config is everything that should (Chapter 16). When you wonder "is this setting per-program or global?", that's the line.
  • Frontend config has no backend logic at all — the backend just stores and returns it ("get and send"). It exists so the frontend can pull its languages and page settings from one place. That's why there's nothing clever to document about it.

Recap

  • The home page can't recompute pricing per visit, so a ~5-minute cron writes a per-event snapshot (available suites, starting price, by suite type) — non-real-time by design, to survive traffic spikes.
  • A store is configured in four layers: base (global, e.g. time zone), program (per program), client (ledger + account groups), and frontend (a UI data dump with no backend logic).

Next → Chapter 19 — Suites, Continued: Types & Partial Sales