The Hard Parts of White-Label Ordering on AWS
The short version
- The tenant key is the scaling strategy, not just the security check.
store_iddoes four jobs at once in this platform — it authorizes the request, it gives the index its locality, it owns the cache entry, and it is the shard route you will need later. A query that sortsordersbycreated_atwithout it is both a cross-tenant leak and full-table pressure; the same query withWHERE store_id = ?and a keyset cursor rides a composite index on(store_id, created_at DESC). - A queue absorbs bursts and hands you a correctness problem. Square, DoorDash, Uber and Stripe events land in SQS, and at-least-once means the same event will arrive twice. Verify the signature, claim an idempotency key, then apply the state change — and acknowledge only after the durable transition succeeds, so the second delivery of event 8341 is a no-op rather than a second order.
- Consistency is a per-flow decision, not a global setting. Aurora reader endpoints buy read capacity, and a fetch that immediately follows a write can still observe the previous state. Read-after-write flows go through the writer; everything else stays on the replicas.
- Two questions need two data paths. The operational database answers one merchant’s current request; Redshift answers historical questions across time. Canonical events go through Firehose and a JQ partitioner into S3 as typed Parquet, then a bulk COPY into Redshift. Dashboards never turn Aurora into a warehouse.
- Give a table its lifecycle before it is large. Append-only tables are partitioned by
created_atfrom the start, old partitions archive to S3, and history lives in Redshift — because partitioning a live table later is the expensive version of this decision.
The clients are the other half of it. A mobile build stays in the wild for months after the backend moves, so the API has to serve versions that cannot deploy together: additive contract first, then a server-side version gate, then a new endpoint version, and a forced upgrade only when nothing else works. The same logic applies to infrastructure — CDK makes a change repeatable, but cdk synth and a diff exist so someone reviews replacement and data risk before production, and cross-stack values travel through explicit CloudFormation exports rather than by hand.
Which leaves the coupling that’s left. The most useful architecture review asks where two definitions can drift apart: the Glue payload struct and the analytics service’s canonical event type, a renamed CloudFormation export that is quietly an API change, and local Node versions against CodeBuild’s. Four rules held up under real product constraints — put the tenant key in every boundary, make retries safe before adding throughput, choose consistency per user flow, and treat schemas, clients and stacks as versioned contracts.
Want this delivered to your team, or a second pair of eyes on a multi-tenant platform of your own? Book a call.