Complete guide · Browse by setup stage

Complete V2Ray Configuration Guide

Understand the core concepts, install a client, import subscriptions, and configure proxy modes and routing. Get a basic connection working first, then move on to TUN, maintenance, and advanced settings.

For your first connection, follow the quick-start steps in the setup guide. This page explains how each step works, its limitations, and how to troubleshoot it—whether you’re learning in order or looking up a specific issue. Choose an installer for your platform from the Download Center. For quick answers, see the FAQ.

1. Core concepts and connection flow

What the client, core, and server each do

V2Ray setup involves three distinct parts. The GUI client stores servers, manages subscriptions, and exposes settings. The core handles traffic, matches rules, and establishes connections. The remote server provides the actual outbound connection. Installing a client only prepares your device; it does not give you a server to connect to. v2rayN is the recommended desktop client, while v2rayNG and v2flyNG are mobile options. The next chapter covers how to choose.

Project V provides the broader ecosystem behind these proxy technologies. V2Fly continues V2Ray development, while Xray is another core in the same ecosystem. Client and core names do not map one-to-one, and a name alone does not tell you which protocols are supported. After importing a configuration, check which core the client uses, which fields it supports, and what the server requires. A configuration appearing in the GUI does not guarantee that the core can run it.

Understand protocols, transports, and security separately

A protocol defines how the client and server communicate. Common options include VMess, VLESS, Trojan, and Shadowsocks. A transport specifies how that data is carried, such as over TCP, WebSocket, or gRPC. TLS and REALITY are used in the connection handshake. A share link often encodes settings from all these layers, so what looks like a single address can contain a port, identity, transport, and security parameters.

VLESS is not a complete encrypted transport on its own. Whether to use TLS or REALITY depends on the server configuration; REALITY is not a proxy protocol alongside VLESS. When adding a server manually, make sure the address, port, user ID, transport, and server name all match. Two servers using VLESS are not interchangeable: do not copy public keys, short IDs, or paths between them.

Start with a reproducible basic connection

A typical connection works like this: the browser reads the system proxy settings and sends a request to a local inbound port. The core applies routing rules, selects an outbound, and connects to the remote server. Other apps may ignore the system proxy; TUN provides another way to capture traffic. Traffic entering the client and the outbound it uses are separate parts of the flow. Keep that distinction in mind when changing modes so an entry-point issue is not mistaken for a server issue.

For the first test, keep one server configuration from a known source, use the client’s basic routing setup, and leave custom rules disabled. Check that the system clock is correct, close any duplicate proxy processes, start the core, and visit a known test destination. Save the working mode and a short log excerpt as a baseline for comparison. A single speed test does not replace testing real apps or prove that every transport works.

Troubleshoot from the device outward: check that the local inbound is running, the app is using it, the rules select the expected outbound, and the remote connection completes. Startup errors, handshake failures, and request timeouts point to different stages. Identify the failing layer before changing settings. Reinstalling the client usually will not fix an expired address or mismatched server parameters.

2. Choose a client by platform and core

Start with v2rayN on desktop

For Windows, macOS, and Linux desktops, start with v2rayN. This guide’s concepts—subscription groups, servers, parameter settings, routing, and DNS—apply across platforms. Before choosing a package, check your operating system, processor architecture, and package format, not just the file size. The client is free and open source, but runtime dependencies and system integration vary by release, so read the instructions for your platform before installing.

The Windows download page offers two desktop builds: Desktop and the classic WPF version. Desktop follows a cross-platform UI approach and suits users who want a similar experience across desktop systems; WPF is the classic Windows UI. They are not different protocols, and Desktop does not guarantee faster server speeds. Choose one and finish the setup first. Running both while troubleshooting can make them compete for control of the system proxy.

Client and download options
Use caseRecommended optionCheck first
Windowsv2rayN Desktop / WPFx64 architecture and runtime dependencies
macOSv2rayNApple Silicon / Intel
Androidv2rayNG, with v2flyNG as an alternativearm64 / universal build
Linuxv2rayNArchitecture and deb / rpm package format

Choose a mobile client based on configuration compatibility

For Android, v2rayNG is the recommended choice and uses the Xray core. v2flyNG is an alternative using the V2Fly core. Both support the basic workflow of importing a configuration, choosing a server, and connecting, but their protocol implementations and supported fields are not identical. For configurations that use REALITY or specific transport settings, check core support first. Being able to parse a link does not prove compatibility.

Most recent Android devices use arm64 packages, but you cannot determine architecture by purchase date alone. Some devices have 64-bit hardware but a different system environment. Check the device information or use the universal build if you are unsure; it supports more architectures but may be larger. If installation fails, check the architecture, system requirements, and whether an existing install has a different signature before switching clients.

Switching cores does not replace checking server settings

Depending on the release and supported features, v2rayN can use different cores, commonly Xray and sing-box. Before switching, confirm the target core can represent your current configuration, especially its routing, DNS, and TUN settings. Cores do not share every JSON field, and the client may translate GUI options differently. Do not paste a complete configuration for one core into another core’s custom configuration field.

For a basic connection, start with the standard core option the client recommends for that server type. Try another core only when you have a specific compatibility issue or need a particular feature. After switching, restart the connection and review the generated configuration and logs. Make sure the proxy entry point, rules, and DNS settings were not reset. Seeing the same server name in the GUI does not mean the connection flow is unchanged.

When using multiple devices, focus on what each setting does rather than expecting identical button names. On desktop, the browser can use the system proxy. Android typically routes app traffic through the system VPN interface, with different OS permissions and restrictions. Find installers in the Download Center. For details on the Desktop and WPF UI options, see Desktop vs. WPF: What’s the Difference?. Choose a client before moving on to installation.

3. Install and check the first launch

Before installing, check the architecture, install location, and existing configuration

The goal is a client environment that can start the core, save settings, and request the permissions it needs. Quit any existing client and back up servers and routing settings you want to keep. Then choose the right package from the Download Center. The desktop configuration directory must be writable by your account. If you downloaded an archive, extract it fully before launching; do not run the main program from inside the archive.

Do not combine migration with a first-time install. Launch the new environment first and confirm that the window opens and basic settings save correctly; then import your old configuration. Replacing the entire old directory may bring along outdated core files, port settings, or custom parameters. Use the installer’s process if it manages the program files. If you use a standalone directory, keep its files together and avoid mixing core and UI files from different sources.

First launch on Windows and macOS

On Windows, launch v2rayN and check for missing runtime dependencies or core startup errors. If a dependency is missing, follow the instructions for your release; administrator privileges will not fix missing files. The system proxy usually does not require running as administrator all the time. TUN and other system-level network settings may require elevated permissions. Permissions, dependencies, and port conflicts are separate issues—check each one independently.

On macOS, check About This Mac for the chip type and choose the Apple Silicon or Intel build accordingly. Follow the installation steps to place the app in the usual Applications folder, then open it for the first time. If macOS blocks an app from an unidentified developer, verify the download source and check for an option to allow that app under System Settings → Privacy & Security. Do not disable system-wide security just to run one client.

Even after granting permission, check whether the system blocks network-related actions. An app opening successfully does not mean it can change the system proxy or start a virtual interface. Allow required actions as prompted, then restart the connection. An “app is damaged” warning is not always a permissions issue. First download the package that matches your architecture and verify the installation steps. For more, see Installing v2rayN on macOS and handling permissions.

Installation on Linux and Android

On Linux, choose deb or rpm according to your distribution, then check whether you need x64 or arm64. Prefer the system package manager so dependencies and program files are installed normally. Desktop sessions, privilege tools, and system proxy integration vary by environment. If the app opens but the system proxy does not work, configure the local proxy directly in one app to distinguish a UI startup issue from a system integration issue.

When installing v2rayNG or v2flyNG on Android, the system may ask you to allow the current browser or file manager to install apps. Grant this permission only for the current operation. If an update fails, check the package architecture or signature mismatch and back up your data before deciding whether to uninstall. On first connection, Android usually prompts for VPN permission; the app traffic entry point is created only after you approve. Check battery restrictions separately once the connection is stable.

Before quitting for the first time, check whether the system proxy is still enabled. Some clients minimize to the tray when you close the window, leaving the core running. Others exit but may fail to restore the proxy after a crash. Reopen the client to confirm the actual state and note the local inbound port. You will need it to check whether apps are reaching the right entry point; do not rely on memory of a default port.

4. Import subscriptions and manage servers

Subscription URLs and share links are different

A subscription URL retrieves and updates multiple servers; a share link usually describes one server. Both may look like long strings, but they use different import options. Check which type the provider gave you. A website URL is not necessarily a subscription, and a single VLESS share link does not belong in a subscription download field. A QR code is just a way to encode text; after scanning, check whether it contains a subscription or a single server configuration.

In v2rayN, open subscription groups, add a group name and subscription URL, save, then update. Name groups by source or purpose, not by connection quality. In v2rayNG and v2flyNG, use the subscription settings or the relevant import menu, then save and update the configuration. Menu labels may vary, but the sequence is the same: add a source, retrieve configurations, check the results, and select a server.

Check the fields after updating, not just the list

After an update, make sure the servers appear in the expected group, then check their protocol, address, port, transport, and security settings. A label in the list is for identification; it does not prove the connection works. Updates may replace existing entries, making your selected server unavailable or moving it. Recheck the current selection after each update so the client does not keep using a deleted configuration or one the current core cannot handle.

Use the clipboard import option to add a share link. Copy the entire string; chat apps may truncate trailing parameters, or you may accidentally include surrounding instructions. Add a server manually only if you know what each field does. If you have a complete share link, import it first and then check each field to avoid missing a path, server name, public key, or short ID.

Protect subscriptions and individual server configurations separately. Tokens, user IDs, and authentication fields in a URL may let someone access or use the service. Do not include them in public screenshots, forum posts, or sample code. When asking someone to troubleshoot, show field names and error messages but hide actual addresses and identity data. If a subscription is exposed, regenerate or revoke it with the provider; deleting the entry from the client is not enough.

Troubleshoot update failures at the retrieval, parsing, and runtime stages

Stage one, retrieval: can the subscription domain resolve, is the URL still valid, is the system clock correct, and did a login page replace the expected response? Stage two, parsing: does the content use a supported format, encoding, and protocol? Stage three, runtime: the entries imported, but the core may not support a field or the server may be unreachable. Each failure calls for a different fix; do not lump them all together as a “broken subscription.”

For your first import, try “Update subscription (without proxy)” so the update does not depend on a proxy connection you have not established yet. If the subscription URL really does require a proxy, keep another working server available before updating through it. There is no single option that works for every URL. The key is to avoid routing the update request through a connection that is being replaced, has expired, or points back to itself.

Keep subscriptions from different sources in separate groups so you can track where entries came from. Before enabling automatic updates, check whether they overwrite entries and regenerate custom labels or parameters. If updates keep failing, save a working configuration and pause automatic updates. Then follow the subscription update troubleshooting checklist to check the response and update method. Configure the proxy entry point after this stage to make troubleshooting more focused.

5. System proxy modes and app entry points

The mode controls the entry point, not every outbound connection

The system proxy mode controls how the OS provides proxy settings to apps. Routing rules decide whether requests that reach the core go direct or through a proxy. When “Set system proxy automatically” is enabled, a browser may start using the local entry point, but routing rules can still send its requests direct. “System proxy enabled” and “all traffic routed through the server” are different states. Check the app entry point and actual outbound separately.

Common v2rayN options include Clear system proxy, Set system proxy automatically, and Do not change system proxy. Clear removes the current system proxy settings. Automatic configuration writes the client’s local address and port. Do not change keeps the existing settings. This last option does not remove a stale port: if the system still points to a client that has exited, apps may continue to fail.

What each system proxy mode changes
OptionSystem setting changeWhat to check first
Clear system proxyRemoves system proxy settingsDoes direct access work after quitting?
Set system proxy automaticallySets the local proxy entry pointEntry port and core status
Do not change system proxyKeeps existing settingsWhich program does the existing address point to?

Test app proxy settings separately from the system proxy

Not every app reads the system proxy. Some have their own HTTP or SOCKS settings; others read environment variables only at startup and need to be restarted after a system change. Start with a browser known to support the system proxy, and rule out extensions or in-app settings that override it. Then test other apps to tell a client connection failure from an app that never sent traffic to the client.

When configuring an app’s proxy directly, the address is usually the local loopback address and the port must match what the client actually shows. The proxy type must also match the listening entry point. HTTP and SOCKS are different protocols; selecting the wrong one can cause the handshake to fail. If the inbound listens only on loopback, other devices cannot use it directly. Do not expose it on every network interface just for convenience—that also expands who can access the local proxy.

This guide does not assume a default port. Existing configurations, client builds, and user changes can all use different ports. If the log reports that an address is already in use, close other proxy processes, check for duplicate instances, and only then consider changing the port. Update the system proxy or in-app settings as well. Changing the client alone while leaving the browser on the old port is a common reason the core starts but pages will not load.

Confirm a successful connection and recover cleanly from failures

After configuring the system proxy, start the connection, visit a known destination, and check the logs from around that time. First confirm that the connection is established; do not start by comparing speed. The client’s built-in test may measure a different destination or connection stage, so its result does not directly reflect website performance. If request or routing logs are available, check whether the request appears and which outbound it selects to narrow down the issue.

If no request reaches the core, check the app’s proxy settings, system settings, and local port first. If the request arrives but the remote handshake fails, check server parameters and core compatibility. If the handshake completes but the destination is unavailable, look at DNS, routing, or the destination service. This is more effective than cycling through every mode and preserves evidence of where the failure occurred.

Android usually routes traffic through the system VPN interface, so do not copy the desktop system proxy steps. Check system permissions, app coverage, and background restrictions separately. First confirm that one foreground app can access the network, then test with the screen locked and after switching networks. Move on to routing only after the entry point is stable; otherwise, you may mistake an app connection issue for a rule issue.

6. Routing and DNS

Rule matching order matters

Routing should select an outbound based on clear conditions, not accumulate as many rules as possible. Common strategies include Bypass mainland China (Whitelist), Blacklist, and Global, but the default rules vary by client configuration. The names are helpful labels, but actual behavior depends on rule content, order, and the default outbound when nothing matches. Review the rules in use rather than relying on the label alone.

Most rules are evaluated in order, so an earlier match can prevent later rules from taking effect. Make private and local network addresses explicitly direct, put specific business domains before general rules, and leave broad fallback rules near the end. If a domain keeps using the wrong outbound, check whether an earlier domain, address, or port condition already matches it. Adding a rule to the bottom of the list may not change the result.

What domain and address rules match against

geosite:cn references a domain collection; geoip:private references a private address collection. The core must be able to access the corresponding data files. Domain rules need the original domain name, while address rules match the destination IP. If an app resolves a name locally and sends only the IP to the entry point, domain matching may be limited. Sniffing can recover domain information for some traffic, but it cannot identify every protocol.

DNS is part of the same flow: who makes the lookup, which outbound carries it, and which address is returned all affect routing and connectivity. Do not enable several overlapping DNS features just to change the resolved address. First understand the roles of the app’s DNS and the core’s DNS, then check that direct and proxy DNS requests are not using the same upstream in a way that creates a dependency loop.

Add rules you can explain to an existing configuration

This Xray / V2Ray-style routing snippet shows how to send private addresses and a domain collection direct. It is not a complete client configuration: an outbound tagged direct must already exist, and the relevant geodata files must be available. GUI users should create an equivalent rule in the routing settings. If you use another core, express the rule in that core’s format.

{
  "routing": {
    "domainStrategy": "AsIs",
    "rules": [
      {
        "type": "field",
        "ip": ["geoip:private"],
        "outboundTag": "direct"
      },
      {
        "type": "field",
        "domain": ["geosite:cn"],
        "outboundTag": "direct"
      }
    ]
  }
}

AsIs means the routing stage does not actively resolve a domain just to match an IP address. It does not mean DNS is never used when connecting. Domain strategies affect when lookups happen and when address rules are tried; changing the strategy may make previously unmatched address rules start working. Keep the basic strategy while learning, and change it only after identifying which match information is missing. A strategy name is not a guaranteed performance tweak.

Start by testing one clearly defined domain with a custom rule. Specify whether it should go direct or through a proxy, then check the logs to confirm a match before expanding to a domain collection. When testing a local device, check private IP rules, local domain resolution, and whether TUN captures the app. Sending private IPs direct will not necessarily fix a local domain lookup failure; verify routing and DNS separately.

Updating rule resources can change results, and custom rules may conflict with a subscription or default template. Save the configuration before and after each change, and record the test destination and matched outbound. If something breaks, revert the most recent change. A complex setup should let you answer what each rule matches, why it is in that position, and what happens if it does not match. Otherwise, it will become harder to maintain over time.

7. TUN virtual interfaces and traffic capture

Go beyond app proxy settings to capture network traffic

TUN receives IP-layer traffic through a virtual network interface, making it useful for apps that do not read the system proxy. It expands which traffic can enter the client; it cannot fix an unavailable server or guarantee that every app protocol will work. Before enabling it, confirm that the basic connection works and that you understand the current routing setup. Otherwise, simultaneous issues with the entry point, DNS, and server will be difficult to diagnose.

Desktop TUN usually creates a virtual interface and modifies system routes, so it may require elevated privileges or a network component. The “Enable Tun mode” option in v2rayN is only the control to start the process; actual behavior also depends on the core, platform, and settings. Confirm that your environment supports the feature and follow the client’s instructions. Do not repeatedly toggle system routes while the core is stopped or dependencies are missing.

Check loopback, local networks, and other tunnels

Before enabling TUN, quit other proxy or VPN apps that modify routes to prevent two entry points from competing for the default route or DNS. Multiple virtual interfaces do not necessarily indicate a problem, but you should know which one is capturing traffic. After enabling TUN, confirm that the client logs successful interface creation, test an app, then check local devices and a normal direct destination. Do not rely on the toggle’s appearance alone.

Traffic used to reach the remote server should not be routed back into the TUN entry point, or a loop may form. Clients and cores typically offer automatic routing, interface selection, or bypass settings, but multiple network adapters, hotspot sharing, and custom routes can change the assumptions. If the logs show repeated connection attempts that never complete, turn off TUN to restore the system proxy baseline, then check the outgoing interface and the route to the server address.

Local network access depends on both private-address routing and name resolution. If a printer, router admin page, or network storage device is unavailable, test its local IP first, then its device name. If the IP fails, suspect routing or the firewall; if only the name fails, suspect DNS. Do not try to fix every local network issue with a broad proxy rule—it may send requests that should stay local to a remote server.

How to test DNS, UDP, and network changes

TUN is often paired with DNS capture, but DNS capture alone does not provide a complete resolution strategy. Find out where system queries go, how the core resolves remote server names, and whether the DNS upstream itself depends on the proxy connection. If resolving the server address requires a tunnel that has not yet started, startup can deadlock. Keep a resolution path that can establish the initial connection instead of sending all DNS traffic through the same outbound by default.

A browser loading web pages does not prove that UDP or every type of app traffic works. Test voice, real-time communication, and other apps using their own protocols, and check whether the server and transport support the required traffic. If a test fails, check whether the traffic reached the core, matched the correct outbound, and was allowed by the system firewall. Enabling TUN alone does not guarantee the same connection experience for every app.

When switching from wired to wireless, waking from sleep, or joining a different hotspot, the outgoing interface and DNS may change. Restart the connection and test before rewriting all your rules. On Android, also check the system VPN status, background restrictions, and which apps are covered. Confirm the results in the foreground, in the background, and after switching networks before deciding whether the setup is suitable for daily use.

8. Routine maintenance and layered troubleshooting

Keep a working baseline and a minimal backup

Keep a verified working configuration that records the client, core, subscription groups, proxy mode, routing setup, and any necessary DNS settings. Back up only what you need to restore; do not keep all logs in your configuration archive. Exports may contain subscription credentials and server identity data. Store them securely, and avoid exposing them through public sync or accidental sharing when migrating.

Update subscriptions, clients, cores, and rule resources separately. Make one change at a time, restart the connection, and test common destinations before moving on. Updating everything at once makes it hard to tell whether a failure came from changed server entries, parameter conversion, rule matching, or program dependencies. Your maintenance notes do not need to be elaborate, but should say what changed, why, and how to revert it.

Read logs by failure stage

If the core fails to start, check configuration syntax, field compatibility, resource files, and port conflicts. If it starts but the app sends no requests, check the entry point. If a request arrives but times out, check the server address, network, and outbound. For handshake errors, verify identity, TLS, or REALITY parameters. Error messages are clues: match them to the time of your test, and do not treat an old connection error as proof about the current configuration.

Symptoms and the first layer to check
SymptomCheck firstNext step
Core will not startConfiguration, dependencies, portReview the basic parameters
No app requests appearSystem or app entry pointCheck the listening address and port
Subscription will not updateURL, retrieval method, response contentDistinguish retrieval from parsing errors
Some destinations fail after split routingRule matches and DNSTest the outbound with one destination

Temporarily increase log detail when you need to collect diagnostics, reproduce one specific action, then restore the usual level. Excessive logs can use storage and may record destination domains, addresses, or account-related fields. Remove credentials and unrelated requests before sharing logs. Include only the client environment, time of the error, steps to reproduce, and relevant log entries. A precise problem report makes it easier to get testable advice.

Check the clock, ports, and network environment

An incorrect system clock can affect certificate checks and authentication for some protocols. Check it especially after extended offline periods, waking from sleep, or disabling automatic time sync. Port conflicts are often caused by duplicate instances or another proxy app; exit cleanly before retrying. If you change a port, update the app settings too. After a network change, check DNS, the outgoing interface, and whether a captive portal login is required.

If the same configuration works on one network but not another, keep the client settings unchanged for an apples-to-apples test. Check normal access and DNS on the network first, then see exactly where the connection fails. Different results for different destinations do not mean every server is down; a single failed server does not prove the client needs reinstalling. Keep the comparison consistent so you can identify the right layer.

After an update, rollback should restore the configuration and a compatible runtime environment, not just replace one program file. A newer settings format may not be fully understood by an older UI, so keep a separate backup before migrating. Android may delete app data on uninstall, and desktop uninstallers may not preserve the configuration directory. Before proceeding, confirm that your export can be read and protect any sensitive information it contains.

For common questions, check the FAQ. To rebuild a basic connection, return to the setup guide. The goal of maintenance is to reduce uncertainty, not to keep every setting on the latest version. Being able to explain the configuration, reproduce an issue, and roll back reliably is the foundation for advanced setup.

9. A learning path for advanced configuration

Inspect generated configurations before writing your own

The first step in advanced setup is understanding what the client has already generated, not building a complete configuration from scratch. Inspect the active configuration’s inbounds, outbounds, routing, and DNS to see how GUI settings map to fields. Generated files may be overwritten the next time the client starts, so make changes through supported settings rather than treating edits to temporary files as a long-term solution.

When reading a configuration, follow the tags: which inbound receives app requests, which outbound a rule selects, and what the default outbound is. Then review transport and security settings, followed by DNS and special features. Trace one request at a time to see whether a field affects its connection. An outbound that is never referenced or a rule that never matches does not become active just because it appears in the file.

Learn rule matching with a minimal test

Start with one clearly scoped domain rule, verify that it matches, then expand to a domain collection. This snippet sends example.com and its subdomains through the outbound named direct. It is for testing rule behavior, not a recommendation that this domain should always go direct. Add it to an existing Xray / V2Ray-style routing rules array, and make sure the corresponding outbound tag exists.

{
  "type": "field",
  "domain": ["domain:example.com"],
  "outboundTag": "direct"
}

Record the original rule order before testing. Then check whether traffic for the target domain reaches the core, whether its domain name is preserved, and whether it selects the intended outbound. If the rule does not match, inspect earlier rules and the entry-point information before changing DNS or sniffing. Understand the failure before adding more conditions; otherwise, you may end up with a configuration that worked once by chance but cannot be explained.

Explore DNS and FakeDNS when needed

FakeDNS assigns addresses from a reserved pool to domain names and keeps a mapping between them so later traffic can recover the original destination. It is often used with TUN and domain-based routing, but it is not a regular public DNS address and is not suitable for every setup. App caching, local network resolution, or incomplete traffic capture can cause problems. First understand how the address is returned, how the core receives it, and when it becomes a real connection.

Before exploring this feature, learn how to test regular DNS, TUN, and domain routing separately. After enabling it, test domain access, direct IP access, local devices, and recovery after turning it off. Pay particular attention to apps that may cache previously returned addresses. For details on how it works and when to use it, see FakeDNS explained: using it with TUN. It is not a general-purpose fix for connection failures.

Turn advanced experiments into a maintainable setup

Test custom configurations, complex routing, and rule conversions between cores in a separate setup, keeping your everyday configuration intact. For each feature, document its purpose, inputs, dependencies, and rollback steps. For example, a domain rule may depend on the app preserving the domain name; a TUN setting may require permissions and a particular outgoing interface; a DNS setup may depend on the proxy connection starting first. These prerequisites matter more than copying a long block of parameters.

Control variables when evaluating performance. Keep the network, server, and test destination fixed, and separately observe connection setup, page loading, and real app behavior. Do not extrapolate a short test to every situation. Log detail, concurrent apps, and DNS caching can all affect results. Add an experimental setting to your everyday setup only when the results are repeatable and you can explain how it changes the connection flow.

Follow this guide in order, then repeat as needed: verify installation and subscriptions, confirm the app entry point, test routing and DNS, then expand to TUN and custom features. If you still have questions about the basics, read 10 V2Ray FAQs for beginners to review the terminology, then return to the relevant chapter. A simple, explainable configuration is easier to maintain than a collection of parameters you do not understand.