DEV Community

Cover image for Data Partitioning and Sharding: How Systems Scale Data
Sushant Gaurav
Sushant Gaurav

Posted on

Data Partitioning and Sharding: How Systems Scale Data

When engineers first learn about scalability, the conversation usually revolves around application servers.

If traffic increases, add more servers. If requests increase, add a load balancer. If latency increases, introduce caching. For a while, this works remarkably well.

Application servers are relatively easy to scale because they are typically stateless. If one server becomes overloaded, another can be added behind the load balancer, and traffic can simply be distributed between them.

Databases are different.

Unlike application servers, databases hold state. They contain user information, transactions, product catalogues, messages, orders, and every other piece of information that gives an application meaning. They are the memory of the system.

And because databases hold state, scaling them becomes significantly harder.

Eventually, almost every growing system encounters the same problem:

The application can still handle more traffic, but the database cannot.

This is where data partitioning enters the picture.

Why Bigger Databases Are Not Always the Answer

The first response to a struggling database is usually straightforward.

  • Increase the machine size.
  • Add more CPU cores.
  • Add more memory.
  • Upgrade to faster SSDs.
  • Move to a more powerful server.

This approach is known as vertical scaling, and just like application servers, databases can benefit from it for a surprisingly long time.

DB Server

For many startups and medium-sized applications, vertical scaling is often enough.

However, every machine eventually reaches physical and financial limits.

There is always a larger server available—until there isn't.

At some point, upgrading hardware stops providing meaningful improvements. Even worse, the entire system becomes dependent on a single machine.

No matter how powerful that machine becomes, it is still only one machine.

If it fails, the database fails. If the database fails, the application fails.

This creates both a scalability problem and an availability problem.

The question therefore, changes from:

"How do we make this database bigger?"

to:

"How do we distribute the database itself?"

Understanding Data Partitioning

Data partitioning is the process of dividing a large dataset into smaller and more manageable pieces.

Instead of storing all users, all products, and all orders on a single database server, the data is split into multiple partitions and distributed across several machines.

The idea itself is surprisingly intuitive.

Imagine a library containing one hundred million books.

Storing every book inside a single building would eventually create problems. The building would become too large, too expensive, and too difficult to maintain.

A more practical solution would be to divide the books among multiple buildings.

Each building stores only a subset of the collection. Together, the buildings form a complete library system. Individually, each building only manages a portion of the data.

Databases use the same principle.

Partition

From the perspective of the application, the database may still appear to be a single logical system.

Behind the scenes, however, the data is physically distributed across multiple machines.

This separation between logical simplicity and physical complexity is one of the defining characteristics of modern distributed systems.

What Is Sharding?

The terms partitioning and sharding are often used interchangeably, and in many practical discussions they effectively mean the same thing.

Strictly speaking, partitioning refers to the broader concept of splitting data into smaller pieces.

Sharding is a specific type of partitioning in which those pieces are distributed across different physical machines.

You can think of sharding as horizontal partitioning of data.

Instead of making a single database server larger, we make the database wider by adding more machines.

Sharding

Each shard becomes responsible for storing a subset of the overall dataset.

The application no longer talks to a single database server.

Instead, it communicates with a routing layer that determines which shard owns the requested data.

This may sound like a small architectural change.

In reality, it changes everything.

Because the moment data exists in multiple locations, entirely new problems begin to emerge.

Why Replication Alone Cannot Solve This Problem

When discussing database scaling, many engineers initially assume replication can solve everything.

After all, if one database becomes overloaded, why not simply create additional copies of it?

Replication certainly helps, but it solves a very different problem.

Replication creates multiple copies of the same data.

Sharding divides the data into different pieces.

Consider an application with one hundred million users.

With replication, every replica contains all one hundred million users.

Replication

This approach improves read scalability because read requests can be distributed across multiple replicas.

It also improves availability because the system can continue operating if one replica fails.

However, the primary database still receives every write request.

Every new user registration, every order creation, and every transaction still goes to the same machine.

Eventually, that machine becomes the bottleneck.

Sharding addresses a completely different dimension of scalability.

Instead of asking:

"How do we serve more readers?"

It asks:

"How do we store and write more data?"

Why Large Internet Systems Depend on Sharding

Modern internet companies operate at scales that simply cannot be supported by a single database server.

A social media platform may store billions of posts.

An e-commerce platform may process millions of transactions every day.

A ride-sharing platform may continuously ingest location updates from millions of devices.

The volume of data alone makes single-node databases impractical.

Sharding allows these systems to continue growing incrementally.

When storage requirements increase, additional shards can be introduced.

When write throughput increases, new shards can absorb part of the workload.

Instead of upgrading to increasingly expensive hardware, capacity can be expanded horizontally.

This is one of the reasons why sharding is often described as bringing horizontal scaling to databases.

The philosophy is the same as horizontal scaling for application servers.

Rather than building larger machines, we build larger systems.

The Hidden Complexity of Sharding

At this point, sharding may sound almost too good to be true.

  • More storage.
  • More throughput.
  • Better scalability.

So why doesn't every application use it from day one?

Because sharding introduces complexity that simply does not exist in single-database systems.

The system must now answer difficult questions.

  • How does the application know which shard contains a particular user's data?
  • What happens when one shard becomes significantly larger than the others?
  • How are transactions handled when data spans multiple shards?
  • What happens if a shard fails?
  • How are backups managed?
  • How are joins performed across shards?
  • These problems are not implementation details.
  • They are some of the hardest challenges in distributed systems.

And solving them requires entirely new techniques and architectural patterns.

The Fundamental Question of Sharding

The moment a system decides to split its data across multiple database servers, a surprisingly simple question becomes one of the most important architectural decisions in the entire system:

How do we decide which shard stores which data?

A single database never has to think about this problem. Every query goes to the same machine. Every user record lives in the same place. Every order, product, message, and transaction can be found by asking a single database server.

Sharding changes this completely.

Now the system must determine where data belongs before it can even execute a query.

If a user with ID 125847 logs into the application, the system first needs to answer:

Which shard owns user 125847?

Only then can the actual database query begin.

This process is known as a sharding strategy, and the choice of strategy has enormous implications for scalability, performance, and operational complexity.

Range-Based Sharding

One of the earliest and most intuitive approaches is range-based sharding.

The idea is simple.

Each database server becomes responsible for a specific range of values.

For example:

  • Shard 1 stores users with IDs from 1 to 1 million.
  • Shard 2 stores users with IDs from 1 million to 2 million.
  • Shard 3 stores users with IDs from 2 million to 3 million.

Visually, the architecture looks something like this:

Sharding based on user and ID

At first glance, this approach seems almost perfect.

It is easy to understand. It is easy to implement. It is easy to debug. If someone asks where user 2,345,678 lives, the answer is immediately obvious.

The problem is that real-world data is rarely distributed evenly.

Imagine a social media platform where new users are constantly signing up.

Most new users will have the latest IDs.

This means almost all write traffic ends up hitting the newest shard while older shards remain relatively idle.

One database server becomes overloaded while others sit underutilised.

This phenomenon is known as a hotspot, and it is one of the biggest challenges in distributed databases.

Understanding Hotspots

Hotspots occur when certain shards receive significantly more traffic than others.

The issue may arise from user growth patterns, geographical concentration, or uneven business activity.

Consider an e-commerce platform during a flash sale.

If products are partitioned based on category and electronics happens to be the most popular category, the shard responsible for electronics suddenly receives an overwhelming amount of traffic.

Meanwhile, other shards continue operating normally.

Hotspot Sharding

The irony is that the system may have dozens of database servers available, yet performance still suffers because the load distribution itself is uneven.

This is one of the reasons engineers started looking for more balanced approaches.

Hash-Based Sharding

Hash-based sharding attempts to solve this problem by distributing data more evenly across servers.

Instead of storing data according to ranges, the system applies a mathematical hash function to the shard key.

The result of the hash determines where the data will live.

Conceptually, it works like this:

hash(user_id) % number_of_shards
Enter fullscreen mode Exit fullscreen mode

Suppose the system currently has four shards.

If the hash value of a user ID results in 2, that user is stored on shard two.

If the result is 3, the user belongs to shard three.

The actual values are less important than the outcome:

The distribution becomes much more uniform.

Hash-Based Sharding

Unlike range-based sharding, newly created users are unlikely to end up on the same shard.

Writes become naturally distributed across the cluster.

This significantly reduces hotspots and improves scalability.

However, hash-based sharding introduces a new problem.

Humans lose predictability.

With range sharding, engineers immediately know where a user lives.

With hash sharding, finding the location of a record requires executing the hashing algorithm.

The routing layer becomes mandatory.

The Problem of Growth

Eventually, every successful system encounters another difficult question:

What happens when four shards are no longer enough?

The obvious answer seems simple:

Add a fifth shard.

Unfortunately, hash-based systems make this surprisingly painful.

Consider the following example:

hash(user_id) % 4
Enter fullscreen mode Exit fullscreen mode

Now suppose we add a fifth shard:

hash(user_id) % 5
Enter fullscreen mode Exit fullscreen mode

Suddenly, almost every user maps to a different shard than before.

Data that previously belonged to shard one may now belong to shard three.

Data from shard three may move to shard five.

A huge percentage of the database needs to be migrated.

For systems containing billions of records, this migration can become extraordinarily expensive and risky.

This challenge led to one of the most elegant ideas in distributed systems.

Consistent Hashing

Consistent hashing was developed specifically to minimise data movement when infrastructure changes.

Instead of mapping data directly to servers, both servers and data are placed on a logical ring.

Each piece of data is assigned to the next available server in the ring.

Consistent Hashing

Now imagine adding a new server.

Instead of redistributing the entire dataset, only a small portion of the data moves to the new machine.

Most records remain exactly where they were.

This dramatically reduces migration costs and makes scaling much safer.

Consistent hashing is widely used in distributed systems because infrastructure growth becomes a normal operational activity rather than a major migration project.

Systems such as distributed caches, distributed databases, and object storage platforms frequently rely on this technique.

Choosing the Right Shard Key

Interestingly, one of the most important decisions in sharding is often overlooked:

choosing the shard key.

The shard key is the attribute used to determine where data lives.

Examples include:

  • User ID
  • Customer ID
  • Geographic region
  • Product category
  • Organisation ID

Choosing the wrong shard key can create a severe imbalance in the system.

Suppose a ride-sharing platform partitions data by city.

This may work well initially.

But if one city suddenly becomes ten times larger than every other city, that shard becomes a permanent hotspot.

Similarly, partitioning social media users by country may appear reasonable until a handful of countries dominate global traffic.

A good shard key distributes data evenly while still allowing efficient queries.

Finding that balance is often one of the hardest design decisions in large systems.

Why Cross-Shard Queries Become Expensive

In a traditional database, a query can freely join tables because all the data lives on the same machine.

Sharding changes this assumption.

Imagine a query asking for information that spans multiple shards.

The database can no longer answer the question locally.

Instead, the system must:

  • Send requests to multiple shards.
  • Wait for responses from each server.
  • Merge the results.
  • Return the final response.

Cross-Shard Queries

A query that once required a single machine now becomes a distributed operation involving network communication and coordination.

This is why sharding often forces teams to rethink their data models and access patterns.

The Reality of Modern Systems

The truth is that most large internet companies use a combination of techniques rather than relying on a single strategy.

Sharding is combined with:

  • Replication for availability.
  • Caching for performance.
  • Load balancing for traffic distribution.
  • CDNs for global content delivery.

Modern distributed systems are rarely built from one idea alone.

They are ecosystems of complementary techniques working together.

A shard may contain replicas.

Those replicas may sit behind load balancers.

Frequently accessed data may never reach the database at all because it is served from a cache.

This layered architecture is what allows modern systems to operate at a global scale.

Final Thoughts

Sharding is often introduced as a database optimisation technique.

In reality, it is much more than that.

It represents the moment when data itself becomes distributed.

And once data becomes distributed, the system enters an entirely new world of trade-offs involving routing, coordination, consistency, and fault tolerance.

Scaling application servers is relatively straightforward.

Scaling data is where distributed systems become truly interesting.

Because at the internet scale, the challenge is no longer simply storing information.

The challenge is knowing where that information lives, how to find it quickly, and how to keep the entire system functioning while millions of users are trying to access it simultaneously.

Top comments (0)