How connections break
A connection between a phone and a VPN server can break at several levels, and each level needs its own protection.
- Address. A server has an IP address, say 203.0.113.17. Once that address is on a blocklist, nothing gets through to the server.
- Subnet. Addresses come in blocks of 256, called /24 subnets. Neighboring addresses from one hosting provider almost always sit in the same subnet, and a whole block can be blocked at once. VPN operators in Russia report that since late summer 2026 this has been happening more and more often.
- Hosting provider. The provider can switch the server off or take the address back. Sometimes access to a provider's entire network is restricted.
- Protocol. A filter can recognize the connection method itself from how the traffic looks, or throttle UDP on mobile networks. The address is reachable, but no data flows.
Shards deal with the first three levels. Only protocols and their settings help with the fourth.
Address, port, group
An IP address is the server's number on the internet. A port is a numbered "door" at that address, and an address can have many doors. An endpoint is an address, a port and a protocol together: in a VPN app it shows up as a "server". A single address usually carries two endpoints, one over TCP and one over UDP.
Whether endpoints on the same address go down together depends on what gets blocked:
- the address, its subnet or the server at the provider: every port and protocol on it goes down;
- a single port: the other ports keep working;
- UDP: UDP endpoints on every address suffer, TCP keeps working;
- a protocol recognized from its traffic: it stops working everywhere, and only a different protocol helps.
So five ports running the same protocol only protect against a port block. Protocol detection needs a different protocol, an address block needs a different address. Protocols on one address are also tied together: if one of them is detected and the response is to block the address, both die.
A shard is a group of people who were all given the same set of addresses. They don't know the service's other addresses, and nobody outside the group knows theirs. The alternative, where everyone gets every address, is called the shared profile below.
The main rule: every address belongs to exactly one shard. If two shards share an address, blocking it hits both. So you can't put five shards on one address, but you can and should put several addresses in one shard, from different subnets and different providers. A shard is people, not a server: one server can host addresses of different shards.
shard 1 · 40
203.0.113.17tcp · udp
198.51.100.40tcp · udp
shard 2 · 40
203.0.113.18tcp · udp — both down
198.51.100.41tcp · udp
shard 3 · trial
203.0.113.90tcp · udp
198.51.100.77tcp · udp
192.0.2.55 · fallback, shared by shards 1 and 2
for engineersWhat it looks like in the config
In the client config an endpoint is an outbound: address, port, protocol, transport and camouflage settings. A shard gets only the outbounds of its own addresses. If the config uses a domain name instead of an IP, the domain becomes a shared point of failure too: one domain across several shards ties them together. Same with keys: give each shard its own keys and passwords and each user their own ID. Then a leaked account can be disabled, and you can see which shard the leak came from.
Building it step by step
Take a made-up service with 120 users and add addresses one at a time.
The addresses in this example come from ranges reserved for documentation (RFC 5737) and belong to nobody.
Step 1. One address for everyone
| Shard | Addresses | Users |
|---|---|---|
| all | 203.0.113.17 (TCP, UDP) | 120 |
If UDP gets throttled, the app falls back to TCP. If the address gets blocked, all 120 are offline.
Step 2. A second address from the same provider
| Shard | Addresses | Users |
|---|---|---|
| 1 | 203.0.113.17 | 60 |
| 2 | 203.0.113.18 | 60 |
Blocking one address now hits 60 people. But both addresses are in the 203.0.113.0/24 subnet, and blocking it takes all 120 offline again.
Step 3. A second provider
| Shard | Addresses | Users |
|---|---|---|
| 1 | 203.0.113.17 + 198.51.100.40 | 60 |
| 2 | 203.0.113.18 + 198.51.100.41 | 60 |
Each shard now has addresses from two providers in different subnets, and each address still belongs to one shard. Blocking the 203.0.113.0/24 subnet no longer takes anyone offline: 60 people move to their 198.51.100.x addresses, and the other 60 lose their spare. Hence the principle: diversity inside a shard, isolation between shards.
Step 4. A fallback address
Both shards get 192.0.2.55 from a third provider, but a shard only uses it once all its main addresses are down. This is a deliberate exception to the main rule: almost nobody connects through it, so it is hard to spot from traffic. The price is that everyone knows it, and a leak of any config exposes it too. It only stays quiet if the app receives a full config with a balancer; in a plain server list it is just another entry that people can see and pick.
Step 5. Trial users go separately
40 trial users move to a shard of their own, with their own addresses and no fallback.
| Shard | Who | Addresses | Fallback | Users |
|---|---|---|---|---|
| 1 | paying | 203.0.113.17 + 198.51.100.40 | 192.0.2.55 | 40 |
| 2 | paying | 203.0.113.18 + 198.51.100.41 | 192.0.2.55 | 40 |
| 3 | trial | 203.0.113.90 + 198.51.100.77 | none | 40 |
Seven addresses for 120 people: each main address is known to 40 of them, the fallback to the 80 paying users. This is the layout in the simulator. The example only uses three subnets, so all shards share them and a subnet block hits every shard. In real life, give shards subnets of their own.
for engineersThe fallback address in Xray
The shard's main outbounds go into a balancer, and the fallback is set as its fallbackTag. The balancer picks using data from the observatory (or burstObservatory), which probes the outbounds matched by its subjectSelector. If the selector doesn't match the fallback's tag, the fallback isn't probed, and traffic goes there only once the main outbounds are marked as down. False alarms, for example when the user's own network simply dropped, sometimes send traffic there too early.
reader questionWhat about "one provider, one shard"?
Then a provider's trouble stays within its shards, but those shards go down completely unless they have a second address somewhere else. Diversity inside a shard usually works better: a provider outage or a subnet block costs people a spare address, not the connection.
Trial users
Trial access is the easiest to get, so trial configs leak most often. If trial users know the paying users' addresses, such a leak hits paying users too. That is why trial users get shards of their own, with their own addresses and no fallback. This split alone gets you half the benefit: if you split the example only into trial and paying users, a leaked paying config takes 80 people offline instead of 120, and splitting paying users into two shards brings that down to 40.
A single trial shard only works for a small service. With a steady stream of sign-ups, trial users are grouped into cohorts: a shard takes new users until it hits a cap or a day passes, then it closes and newcomers go to a new one. Once the whole cohort's trial has ended, its addresses are retired and never handed to paying users, because people who have left still know them. When someone pays, they move to a paid shard once and get new addresses.
moreWhat changes with 1,000 trial sign-ups a day
The number is hypothetical. With a one-week trial, about 7,000 trial users are active at any time. In a single shard every one of them would know its addresses, and each replacement would reach thousands of new people a day and burn out just as fast.
With cohorts of 200 there are about 35 live trial shards using 35–70 cheap addresses: at the hypothetical prices from the cost section that's €70–140 a month. You can go cheaper with a cap of 500 or one cohort per day. A lower cap means fewer people per address, but more addresses and more replacements. Trial shards don't need a fallback, and several of their addresses can live on one server: for trial users, sharing a server is an acceptable risk.
Cohorts don't stop anyone from collecting addresses through repeated trial sign-ups, but they make it more expensive: yesterday's addresses have nothing to do with today's cohort. Rate-limiting sign-ups cuts that kind of harvesting further.
moreUsers from one influencer, together or spread out?
It's easy to mix up three separate goals here.
- Risk isolation decides who shares addresses with whom. One person who leaks configs will expose their own shard wherever they are. Grouping by source helps in a different case: when many such people arrive through one channel. Kept together, they expose one cohort; spread out, they expose every shard. If a campaign's cohort burns out fast, that also tells you something about the source.
- Load is how many people sit on one address. A spike from a campaign will overflow its shard, so it needs a cap too: the campaign takes up several shards but doesn't mix with the rest.
- Source tracking doesn't need a shard at all: where a person came from is stored as a tag in the database.
A sensible default: group trial users by time, put large campaigns into cohorts of their own with a cap, spread paying users across open paid shards, and keep the source as a tag. Paying is a filter in itself.
What happens when things break
Single blocks: an address, a subnet, a server at a provider. Nobody goes offline, either in the shared profile or with shards, because everyone has an address in another subnet. That's thanks to having different subnets, not to shards. What shards add is something else: only 40 people learn the replacement for a blocked address instead of 120, so it is less likely to leak.
The price. A person in a shard has fewer spare addresses: after a subnet block they have one main address left instead of three in the shared profile. In the example, trial users are down to their last address after such a block, and the next block will take them offline. And when people switch, the load piles onto the shard's one remaining address instead of spreading over five.
Losing a whole set of addresses. Say a config leaks and all its addresses get blocked. That doesn't always happen, and not right away, but it's the worst case to prepare for. In the shared profile all 120 people go offline and all seven addresses need replacing. With shards it's one group of 40 and two or three addresses.
Against scanning of hosting ranges and traffic analysis, it doesn't matter how many people know an address. Shards help against leaked configs and, to some extent, against linking addresses by who connects to them.
moreAll scenarios in one table
"Left" is the number of working main addresses that affected users who are still online have.
| What broke | Shards | Left | Shared profile | Left |
|---|---|---|---|---|
| UDP throttled (60 on mobile data) | 60 switched to TCP | 2, TCP only | same | 6, TCP only |
| 203.0.113.17 blocked | 20 switched, 20 lost a spare, 80 unaffected; 40 learn the replacement | 1 + fallback | 20 switched, 100 lost a spare; 120 learn the replacement | 5 + fallback |
| Subnet 203.0.113.0/24 blocked, or the 198.51.100.x provider switched off its server | 60 switched, 60 lost a spare; 40 trial users on their last address | 1 (paying users + fallback) | 60 switched, 60 lost a spare | 3 + fallback |
| Fallback 192.0.2.55 switched off | 80 paying users without a fallback, nobody noticed | 2 | 120 without a fallback, nobody noticed | 6 |
| Trial config leaked, its addresses blocked | 40 trial users offline, 80 unaffected | — | all 120 offline | — |
| Paying config from shard 1 leaked, its addresses blocked | 40 offline, shard 2 without a fallback, shard 3 unaffected | 2 in shard 2 | all 120 offline | — |
for engineersWhere the model simplifies
The model assumes the app switches to a working address on its own. Clients that receive a full config with a balancer or auto-select can do that; apps with a plain server list need a manual switch. If UDP isn't cut but throttled, connection checks may still pass and no automatic switch happens. The model spreads people evenly across addresses, while balancers pick by latency, so in the shared profile people tend to cluster on the "fast" address, and blocking it hits more than 20 people. The Xray docs warn that regular observatory probes leave a behavioral fingerprint: in the shared profile every client touches every address. Any leaked paying config exposes the shared fallback, so with many paying users each group of shards gets a fallback of its own.
Replacing addresses
A blocked address is replaced, and people stay in their shard. The new address comes from a provider and a subnet the shard doesn't use yet: a neighboring 203.0.113.140 would go down with the subnet at the next block. It's added next to the old one, people get it when their app refreshes its subscription (the config link), and the old one is removed once clients have updated. About a day is a reasonable rule of thumb; in practice, decide by how many people are still connected to the old address. Moving people between shards after every incident would let their new neighbors learn the old shard's addresses.
A blocked address usually stays blocked for a long time, so addresses aren't cycled back into use: an address comes in, works for as long as it lasts, and leaves for good. It's worth measuring address lifetimes per provider and per subnet, with checks from inside the networks that do the blocking: you can't see a block from the server itself.
reader questionWhy not buy 10 addresses and switch every two hours?
Cycling back to an old address almost certainly means returning to a dead one. Frequent switching also exposes every address at once: if all users move to the next address every two hours, all ten will have carried traffic within a day. Every switch drops connections, and apps don't get the new list instantly. Replacing an address ahead of time sometimes makes sense: if a provider's addresses usually last about ten days, you can swap them on day seven. People won't notice a drop, but you'll use about one and a half times as many addresses.
Assignment and group size
A person is assigned to a shard once, when they sign up: round-robin or to the least full shard. The assignment is stored and never changes by itself; otherwise, over time, a person would learn every address. A reasonable size for a paid shard in a small service is 20–50 people. Smaller shards mean more addresses and more replacements, with less and less gain from splitting further. The money goes on addresses. Splitting people across the same addresses costs almost nothing, but each person has fewer spares, and there's more work: more replacements and more to monitor.
moreWhat it costs
Hypothetical prices: €10 a month per server, €2 a month per extra address.
| Step 1 | Shared profile on 7 addresses | Step 5, shards | |
|---|---|---|---|
| Servers | 1 | 3 | 3 |
| Extra addresses | 0 | 4 | 4 |
| Per month | €10 | €38 | €38 |
| Offline if a leaked config's addresses get blocked | 120 | 120 | 40 |
If a shard grows too big, it is split by moving some people to new addresses. This happens rarely and by hand.
What shards don't solve
- Protocol detection. If a filter recognizes the connection method itself, neither a new address nor a new shard helps. Protocols and their settings do.
- Allowlists. If a network only lets through pre-approved addresses, an address from an ordinary hosting provider won't work, however you slice the shards.
- The hosting provider. It can take the address back or switch the server off, sometimes without warning (an example on Habr, in Russian). Only having different providers inside a shard protects against that.
reader questionCan I buy an address the provider can't take back?
Not really. An address "bought separately" from a cloud provider is still the provider's address, sold as a separate service, and they can revoke it. The difference is that you won't have to rebuild the server. You can get your own addresses: a /24 comes from a regional internet registry (RIR), usually through an LIR, or from the secondary market, since free IPv4 space ran out long ago. You can announce it through a provider that allows this, but even then the provider controls the routing and the machine. And your own /24, once blocked, stays blocked at any provider.
reader questionCan I set up a server so the provider doesn't realize it's a VPN?
No. The provider doesn't need to decrypt anything; it's enough to see the flows: hundreds of home and mobile addresses connect to one machine, and incoming volume roughly equals outgoing. That's what a relay typically looks like. Protocols hide the content from filters on the network, but whoever owns the hardware sees the flows. That's why a reliable setup assumes that any address and any server will eventually disappear, and is ready to replace them quickly.