Exploring Dynamic Workload Distribution in Multi-Tenant Architectures
Published on 15.12.2025
Multi-tenancy and Dynamic Messaging Workload Distribution
TLDR: This article, sourced directly from the newsletter body, examines the architectural challenges of distributing messaging workloads in multi-tenant systems. It contrasts static processing with the dynamic needs of SaaS platforms, analyzing the trade-offs between horizontal scaling (physical sharding) and vertical scaling (internal partitioning) to handle tenant-specific message streams.
Summary: The author explores the problem of dynamically distributing message processing workloads, a common challenge in multi-tenant SaaS architectures where the consumers cannot know all tenants upfront. The classical approach involves static projections that filter a known set of event types. However, when tenants register dynamically, a more flexible strategy is required. One option is to introduce tenant-based filtering, spinning up a dedicated consumer for each tenant, perhaps as a separate container or pod. This method provides strong physical isolation and scalability (horizontal scaling) but can become expensive and complex to manage as the number of tenants grows into the thousands, due to the high coordination costs.
The alternative is vertical scaling, where a single consumer instance processes messages for multiple tenants. Inside this consumer, the workload is partitioned, for example, by using consistent hashing on the tenant ID to assign messages to specific worker threads. This approach is cheaper and simpler to manage but introduces the risk of the "noisy neighbor" problem, where one tenant's heavy workload can negatively impact others. The author suggests that a hybrid model is often the most pragmatic solution: smaller tenants can be grouped and processed within a single service, while larger or more critical tenants are given their own dedicated, isolated resources. This balances cost-effectiveness with performance guarantees.
The discussion also touches upon leveraging mature messaging platforms like Kafka, which provide robust, built-in partitioning schemes. Kafka partitions data on the producer side, ensuring messages with the same key are sent to the same partition, which is then handled by a single consumer in a consumer group. While efficient, this may be less flexible than consumer-side partitioning if the distribution key isn't known at production time. The author concludes by proposing a design for the Emmett framework that would allow projectors to define a partitionBy key. The consumer would then manage internal worker threads for these partitions, using distributed locking to ensure exactly-once processing, thus providing a powerful and flexible abstraction without reinventing the complex consensus algorithms found in dedicated messaging brokers.
Key takeaways:
- Multi-tenant systems require dynamic workload distribution for messaging, as tenants are not known statically.
- Physical sharding per tenant offers isolation and scalability but comes with high operational costs.
- Logical partitioning within a single service is more cost-effective but risks resource contention.
- A hybrid approach, combining both methods based on tenant needs, is often the most practical architecture.
- It is often better to leverage the battle-tested partitioning features of systems like Kafka than to build custom distribution logic from scratch.
Tradeoffs:
- Gain: Complete tenant isolation and independent scaling through physical sharding. Sacrifice: Higher infrastructure cost and management complexity.
- Gain: Reduced cost and simplified deployment with logical partitioning. Sacrifice: Lack of true isolation and the potential for the "noisy neighbor" problem.
Link: Multi-tenancy and dynamic messaging workload distribution