Outbounds & Routing
Shape egress in 3x-ui — WARP and NordVPN outbounds, outbound subscriptions (server pools), routing rules, and load balancers.
Inbounds accept clients; outbounds decide where their traffic goes next. 3x-ui can route traffic through Cloudflare WARP, NordVPN, or arbitrary outbound pools imported from a subscription, and select between them with routing rules and balancers.
Editing outbounds & routing
Outbounds, routing rules, balancers, DNS, and logging all live in the Xray configuration (the config template you edit under Xray Settings). There's no separate per-rule UI — you edit the JSON, and the panel reloads Xray. The panel also offers an outbound connectivity test and a route test (ask the running core which outbound a given destination would use).
Build an outbound
Every outbound is a JSON object with up to four parts: a tag (referenced by
routing rules and balancers), a protocol, protocol-specific settings,
and — for proxy protocols — streamSettings that must match the remote
inbound's transport and security. Two outbounds are almost always present:
freedomsends traffic straight to its destination — the default egress. Optionally set adomainStrategy(e.g.UseIP) to control how hostnames resolve.blackholedrops traffic. Route unwanted destinations (ads, torrents) here.
{
"outbounds": [
{ "tag": "direct", "protocol": "freedom", "settings": {} },
{ "tag": "block", "protocol": "blackhole", "settings": {} }
]
}A proxy outbound (VLESS, VMess, Trojan, Shadowsocks) forwards to another
server — handy for chaining or sending select traffic abroad. Mind the wire
shapes 3x-ui uses: VLESS is the flat form (address/port/id/flow/
encryption), VMess uses settings.vnext[], and Trojan/Shadowsocks use
settings.servers[]. The streamSettings must mirror the destination's
transport and security.
Assemble any outbound below and paste the JSON into Xray Settings → Outbounds:
Outbound config generator
Build an Xray outbound object — freedom, blackhole, a proxy protocol, WireGuard, or WARP — to paste into your Xray configuration.
{
"tag": "proxy",
"protocol": "vless",
"settings": {
"address": "example.com",
"port": 443,
"id": "",
"flow": "",
"encryption": "none"
},
"streamSettings": {
"network": "tcp",
"security": "reality",
"tcpSettings": {
"header": {
"type": "none"
}
},
"realitySettings": {
"fingerprint": "chrome",
"serverName": "www.microsoft.com"
}
}
}Cloudflare WARP
WARP lets your server egress through Cloudflare's network. 3x-ui can register a
WARP account for you and wire it into a WireGuard outbound tagged warp:
Add a warp-tagged outbound
Create a WireGuard outbound with the tag warp in your Xray config.
Register WARP
From the panel's WARP controls, register an account. 3x-ui fills the outbound's keys, addresses, reserved bytes, and peer endpoint automatically.
(Optional) auto-rotate the IP
Set a WARP update interval (in days) to periodically rotate the WARP IP. A free license can also be applied.
Route the traffic you want (for example specific domains) to the warp outbound
with a routing rule.
NordVPN
3x-ui can fetch NordVPN (NordLynx/WireGuard) credentials from an access token (or accept a private key directly) and list countries/servers, so you can build a NordVPN outbound.
Outbound subscriptions (server pools)
An outbound subscription imports a remote share-link subscription and injects its servers as outbounds into the running Xray config — without touching your saved template. This is the recommended way to subscribe to a pool of servers.
| Field | Default | Meaning |
|---|---|---|
url | — | The remote subscription URL (SSRF-guarded). |
tagPrefix | auto | Prefix for generated outbound tags (e.g. hk-); blank = subN-. |
updateInterval | 600 | Refresh interval in seconds. |
prepend | false | Place these outbounds before your manual ones. |
priority | 0 | Merge order (lower first). |
Imported outbounds get stable tags: the same server keeps the same tag across
refreshes, so exact-tag routing/balancer selectors stay pinned — while
prefix/wildcard selectors (e.g. hk-*) automatically pick up new servers as the
pool changes. Supported link schemes: vmess, vless, trojan, ss,
hysteria2 (hy2), and wireguard (wg). The panel refreshes enabled
subscriptions on a timer and reloads Xray when something changes.
Routing rules
Routing rules decide which outbound (or balancer) each connection uses. Each
rule is a field-type matcher: set any of domain, ip, port, network,
protocol, inboundTag, sourceIP, … and point it at an outboundTag or a
balancerTag. Rules are evaluated top-to-bottom — the first match wins, so
put specific rules above general ones.
{
"routing": {
"domainStrategy": "IPIfNonMatch",
"rules": [
{ "type": "field", "domain": ["geosite:category-ads-all"], "outboundTag": "block" },
{ "type": "field", "ip": ["geoip:private"], "outboundTag": "direct" }
]
}
}Balancers
A balancer groups outbounds by a selector (tag prefixes, including the wildcard pools from outbound subscriptions) and spreads or fails traffic over them with a strategy:
| Strategy | Picks… | Needs a monitor |
|---|---|---|
random | a random member per connection | no |
roundRobin | members in rotation | no |
leastPing | the lowest-latency member | observatory |
leastLoad | the most stable member by sampled load | burstObservatory |
Reference a balancer from a rule via balancerTag. leastPing and leastLoad
need a health monitor, which Xray places at the top level of the config
(observatory / burstObservatory, not inside routing). The panel can
report balancer status and override a balancer to a specific outbound for
testing.
Build the routing block — rules, balancers, and the matching observatory — here:
Balancer & routing builder
Compose Xray balancers and routing rules, then copy the routing block (with a matching observatory for leastPing/leastLoad).
Balancers
Rules
{
"routing": {
"domainStrategy": "IPIfNonMatch",
"rules": [
{
"type": "field",
"domain": [
"geosite:category-ads-all"
],
"outboundTag": "block"
},
{
"type": "field",
"ip": [
"geoip:private"
],
"outboundTag": "direct"
}
],
"balancers": [
{
"tag": "balancer",
"selector": [
"proxy"
],
"strategy": {
"type": "leastPing"
}
}
]
},
"observatory": {
"subjectSelector": [
"proxy"
],
"probeURL": "https://www.google.com/generate_204",
"probeInterval": "1m",
"enableConcurrency": true
}
}Outbounds that reach external services are fetched with SSRF protection — by default private/internal addresses are blocked unless you explicitly allow them per source.

3x-ui