EXAMPLE: Multi-Tenant Data in DynamoDB — Prefix vs Partition Keys


Example post — This is placeholder content to preview how a post in this space would look. Not a real article.

For multi-tenant SaaS on DynamoDB, two patterns show up a lot: tenant ID as a prefix in the partition key (e.g. TENANT#acme#ENTITY#user123) vs one table per tenant. Both work; the tradeoffs are in scaling, operations, and how you model access.

Single table, tenant in the key

You keep one table. The partition key (and maybe sort key) includes the tenant ID, so every item is naturally scoped. Queries are “get me everything for tenant X” or “get entity Y in tenant X.”

Pros: One table to manage, backup, and monitor. Cross-tenant analytics or admin tooling can scan with a filter (or use a GSI) if you ever need it. Cons: Hot partitions if one tenant is huge; you have to design keys so no tenant dominates. Also, IAM can’t easily say “this role can only read tenant X” — you enforce tenant isolation in app code.

Table per tenant

Each tenant gets their own table (e.g. orders-acme, orders-contoso). You create tables on tenant signup (or via a template) and route traffic in the app.

Pros: Perfect isolation; you can give a tenant’s table to a different account or restrict access with IAM. Per-tenant throughput and cost are obvious. Cons: Table sprawl (hundreds or thousands of tables), more operational overhead, and cross-tenant queries are a non-starter without something else (e.g. a warehouse).

When I pick which

  • Prefix in key: Most B2B SaaS where tenant count is high, tenant size is mixed, and you’re doing “normal” CRUD and tenant-scoped queries. You own isolation in the app and in key design.
  • Table per tenant: When tenants are big, compliance or contracts demand hard isolation, or you’re doing per-tenant backups/restores and want a clear boundary. Often fewer, larger tenants.

In practice I usually start with a single table and tenant-prefixed keys, and only move to table-per-tenant when a customer or compliance requirement forces it. Your mileage may vary.

When you’re ready to publish real content, replace this example with a real post or delete it.