I've been working on several projects using a single-table design in DynamoDB, and I'm documenting the approaches I find effective. The first topic I'd like to dive into is the SaaS multi-tenant pattern. I focus on four main entities: Tenant, User, Project, and Subscription, and I discuss how to manage ten different access patterns while consolidating three dedicated GSIs into one overloaded GSI to reduce write costs. One crucial insight is that by placing Tenant, Subscription, Users, and Projects all under a single partition key (named `TENANT#`), you can effectively query various slices of tenant data using different SK conditions. The GSI primarily serves for cross-tenant lookups, such as email logins or admin tenant lists. I've included full entity definitions if anyone uses the ElectroDB library. I'm eager for feedback, especially from those who run multi-tenant DynamoDB setups in production. How do you handle tenant listing GSI hot partitions at scale? Do you simply perform scans, or have you devised a more efficient method?
4 Answers
From what I gather, you're concerned that a GSI for tenant indexing might result in a hot partition. But how often do you actually need that request? I’d recommend creating a partition key like {pk TENANT#, sk:METADATA} for each tenant, with a property TYPE=TENANT. You might actually face more risk of hot partitioning with your PK/SK design since it’s always based on tenant id, which determines partitioning.
Also, what's your approach to enforcing tenant isolation?
Why don't you just go with separate tables for each tenant? It offers hard isolation which is useful for compliance, and it might help manage complexities. But I see your point about operational overhead. With many tenants, managing thousands of tables could get unmanageable. Just curious about your thoughts on that.
Yeah, it makes sense to consider dedicated tables for strict compliance needs or when tenants require significantly different scales.
I’ve seen teams try separate tables, but the overhead increases linearly, so when you hit a larger number, it can be a headache.
I really like your article! I haven't implemented a single-table design for a multi-tenant setup yet, but if I do, I'm definitely coming back to this as my reference.
Also, great job on the website. Just a heads up, the tables on mobile can be a bit tricky to read, but that's a minor issue. Looking forward to your other patterns!
How do you handle multi-tenancy? Do you use separate tables for each tenant?
Your breakdown of the single-table design was fantastic! Just wanted to add, regarding schema changes—DynamoDB is great because it’s schema-less per item. You can add a new field easily, but structural changes, like modifying PKs/SKs, are a real nightmare. I’ve struggled with refactors that require migrating data to a new pattern. Anyone else frustrated with that aspect?
I totally get where you’re coming from. Managing those changes is tricky, especially with less tooling available for migrations.
Schema migration in the DynamoDB ecosystem feels like a significant gap, for sure. How do you manage that in your apps?

True, the tenant index isn't a major concern if the volume is low—more of an admin function. However, your idea of breaking PKs into subcategories is interesting, though it sacrifices the ability to query multiple entity types in one go. I think it really comes down to your access patterns.