Resin is a high-performance intelligent proxy pool gateway built for operating massive numbers of proxy nodes.
It helps shield your services from unstable upstream proxies and aggregates them into a single HTTP gateway with session stickiness (sticky routing).
- Massive-scale management: Easily handles 100k+ proxy nodes with native high-concurrency performance.
- Smart scheduling and circuit breaking: Fully automated passive + active health checks, outbound IP probing, and latency analysis to remove bad nodes precisely. Uses P2C plus domain-aware latency-weighted scoring for optimal node selection.
- Business-friendly sticky proxying: Keeps the same business account bound to a stable outbound IP. If a node fails, Resin seamlessly switches to another node with the same IP.
- Dual access modes: Supports both standard forward proxy (HTTP Proxy) and URL-based reverse proxy.
- Observability: Detailed metrics and logs, plus a visual Web UI. Includes complete structured request logs for querying and auditing by platform, account, target site, and more.
- Simple and powerful: Works out of the box with default settings, while still offering deep customization for enterprise-grade needs.
- Cross-subscription deduplication: Automatically merges identical nodes from different subscriptions and shares their health state.
- Hot reload: Update common settings without restart. Refresh subscriptions without dropping existing traffic.
- Persistent state: Keeps node health, latency stats, and lease bindings across restarts.
- Zero-intrusion sticky access: Can extract account identity from existing request headers (for example API keys), so clients often need no code changes.
- Incremental subscription refresh: Syncs subscription updates without interrupting current connections.
- Flexible node isolation: Use Platform rules (regex, region, etc.) to build independent proxy pools for different business scenarios.
Tip
You can feed this README and DESIGN.md to AI and ask it anything about the project.
- Remote subscription URL:
http://orhttps://. - Local subscription content: paste subscription content directly in the UI/API.
- sing-box JSON:
{"outbounds":[...]}or raw outbound array[...]. - Clash JSON/YAML:
{"proxies":[...]}or YAMLproxies:. - URI line format (one node per line):
vmess://,vless://,trojan://,ss://,hysteria2://,http://,https://,socks5://,socks5h://. Forhttp://,https://,socks5://,socks5h://, usescheme://[user:pass@]host:port(optional#tag;httpsalso supportssni/servername/peerandallowInsecure/insecurequery parameters). - Plain HTTP proxy lines:
IP:PORTorIP:PORT:USER:PASS(IPv4 and IPv6). - Base64-wrapped text subscriptions (for URI lines/plain-text node lists).
- For sing-box JSON/raw outbounds:
socks,http,shadowsocks,vmess,trojan,wireguard,hysteria,vless,shadowtls,tuic,hysteria2,anytls,ssh. - For Clash conversion:
ss/shadowsocks,socks/socks4/socks4a/socks5,http,vmess,vless,trojan,wireguard/wg,hysteria,hysteria2/hy2,tuic,anytls,ssh.
In just three steps, you can turn your proxy subscriptions into a highly available proxy pool.
Docker Compose is the recommended quick-start path:
# docker-compose.yml
services:
resin:
image: ghcr.io/resinat/resin:latest
container_name: resin
restart: unless-stopped
environment:
RESIN_AUTH_VERSION: "V1" # Required: LEGACY_V0 or V1
RESIN_ADMIN_TOKEN: "admin123" # Change to your admin dashboard password
RESIN_PROXY_TOKEN: "my-token" # Change to your proxy password
RESIN_LISTEN_ADDRESS: 0.0.0.0
RESIN_PORT: 2260
ports:
- "2260:2260"
volumes:
- ./data/cache:/var/cache/resin
- ./data/state:/var/lib/resin
- ./data/log:/var/log/resinRun docker compose up -d to start the service.
(If you don't want Docker, jump to Other Deployment Options.)
- Open
http://127.0.0.1:2260in your browser (replace with your server IP if needed). - Log in with the
RESIN_ADMIN_TOKENyou set. - Go to Subscriptions in the left menu and add your node subscription.
- Wait briefly for the node pool to refresh.
Use one of the client access modes in the following sections.
If you just need a high-performance, large-capacity proxy pool with automatic health management, Resin works out of the box.
Once Resin is running, point your app to http://127.0.0.1:2260.
If you do not want a proxy password, explicitly set RESIN_PROXY_TOKEN="" (the variable must still be defined). Then connect directly to http://127.0.0.1:2260.
Example with curl:
curl -x http://127.0.0.1:2260 \
-U ":my-token" \
https://api.ipify.orgIf your client supports overriding BASE_URL, you can also use reverse-proxy mode.
URL format: /token/Platform(optional).Account(optional)/protocol/target.
Example request to https://api.ipify.org:
curl http://127.0.0.1:2260/my-token/./https/api.ipify.orgChoosing forward vs reverse proxy: when possible, reverse proxy is recommended for better observability. If your client cannot change BaseURL, or requires scenarios better served by forward proxy (such as uTLS or non-WebAPI traffic), use forward proxy.
If your service needs specific nodes (for example by region, subscription source, or name regex), use Resin's Platform feature.
Open http://127.0.0.1:2260/ui/platforms and create a Platform. For example, to use only US and HK nodes, create MyPlatform and set region filters to:
us
hk
For forward proxy, put Platform in proxy auth info:
curl -x http://127.0.0.1:2260 \
-U "MyPlatform:my-token" \
https://api.ipify.orgFor reverse proxy, include Platform in the URL prefix:
curl http://127.0.0.1:2260/my-token/MyPlatform/https/api.ipify.orgWhen your business depends on IP continuity or long-lived interactions, use Resin's core feature: sticky proxying.
First, understand two core concepts:
- Platform: An isolated node pool. You can build it with filters (for example, only US nodes). Resin provides a default
Defaultplatform containing all available nodes. - Account: A unique business identity (for example
Tomoruser_1). For requests carrying an Account, Resin anchors traffic to a dedicated high-quality outbound node. If that node fails, Resin retries seamlessly and switches to another node with the same IP.
With RESIN_AUTH_VERSION=V1, the identity format is: Platform.Account:RESIN_PROXY_TOKEN.
To keep the legacy V0 format, set
RESIN_AUTH_VERSION=LEGACY_V0and continue usingRESIN_PROXY_TOKEN:Platform:Account.
Write identity directly in proxy auth username:
# V1 format: -U "platform.account:token"
# Bind business account user_tom to a stable dedicated outbound IP
curl -x http://127.0.0.1:2260 \
-U "Default.user_tom:my-token" \
https://api.ipify.orgBy replacing your service BaseURL with Resin reverse-proxy URL, traffic goes through Resin directly.
Advanced URL format: http://host:2260/token/platform.account/protocol/target:
# Example: user_tom accesses api.ipify.org over https
curl "http://127.0.0.1:2260/my-token/Default.user_tom/https/api.ipify.org"The URL Account segment is designed for quick use and manual debugging. For long-running production integrations, prefer passing Account by header (
X-Resin-Account).
If your client/SDK supports custom request headers, pass Account explicitly with X-Resin-Account.
This is the recommended and most stable method.
Account source priority: X-Resin-Account header > Account in reverse-proxy URL > header extraction rules.
Example:
curl "http://127.0.0.1:2260/my-token/MyPlatform/https/api.example.com/v1/orders" \
-H "X-Resin-Account: user_tom"If your client cannot set X-Resin-Account, Resin can still extract Account from existing business headers (for example API Key, Token, Cookie) via header rules.
Assume your requests already include an Authorization header:
- In Platform Configuration, set
Reverse-proxy empty-account behaviortoExtract specified request headers as Account. - Set
Headers used to extract AccounttoAuthorization.
Then even if Account is omitted in URL, Resin can still parse it from headers:
curl "http://127.0.0.1:2260/my-token/MyPlatform/https/api.example.com/v1/orders" \
-H "Authorization: sk-abc123"In this example, Resin uses sk-abc123 as Account. Future requests with the same key are intended to stay bound to the same outbound IP whenever routing conditions allow.
Tip
Beyond Platform header config, Resin also supports advanced rules that pick extraction headers by URL prefix. You can ask AI to explain both modes with this README and DESIGN.md.
Enable header-based Account extraction only when you have a valid legal basis (for example user authorization or contractual permission), and ensure your logging, retention, and access-control policies comply with applicable laws and target-service terms.
Different clients integrate Resin differently, with different code-intrusion levels.
💡 If you do not need sticky proxying
| Access Method | Code Intrusion | Notes |
|---|---|---|
| Forward proxy | 🟢 Zero intrusion | Just configure proxy address http://127.0.0.1:2260 and credentials. |
| Reverse proxy | 🟢 Zero/low intrusion | Usually only requires changing service BaseURL. |
💡 If you need sticky proxying
| Access Method | Code Intrusion | Notes |
|---|---|---|
| Forward proxy | 🟡 Medium intrusion | Per-user requests need different auth info, such as platform.account:token (V1). |
| Reverse proxy | 🟡 Medium intrusion | Add X-Resin-Account request header or build reverse-proxy URL paths dynamically with account information. |
| Reverse proxy + header rules | 🟢 Zero/low intrusion | Resin can extract Account from original headers (for example Authorization) and bind IP automatically. |
👉 Fast integration script/prompt: If you are a developer and want AI to help modify an existing project for native Resin sticky integration, use:
Option 1: Run prebuilt binary
Go to the project's Release page and download the package for your OS/architecture. After extraction, run the single binary
resin.
RESIN_ADMIN_TOKEN=<admin-dashboard-password> \
RESIN_AUTH_VERSION=V1 \
RESIN_PROXY_TOKEN=<proxy-password> \
RESIN_STATE_DIR=./data/state \
RESIN_CACHE_DIR=./data/cache \
RESIN_LOG_DIR=./data/log \
RESIN_LISTEN_ADDRESS=0.0.0.0 \
RESIN_PORT=2260 \
./resinOption 2: Build from source
Prerequisites: Go 1.25+ and Node.js installed.
# 1. Clone Resin source
git clone https://github.com/Resinat/Resin.git
# 2. Build WebUI
cd Resin/webui
npm install && npm run build
cd ..
# 3. Build Resin core
go build -tags "with_quic with_wireguard with_grpc with_utls" -o resin ./cmd/resin
# 4. Run
RESIN_ADMIN_TOKEN=<admin-dashboard-password> \
RESIN_AUTH_VERSION=V1 \
RESIN_PROXY_TOKEN=<proxy-password> \
RESIN_STATE_DIR=./data/state \
RESIN_CACHE_DIR=./data/cache \
RESIN_LOG_DIR=./data/log \
RESIN_LISTEN_ADDRESS=127.0.0.1 \
RESIN_PORT=2260 \
./resin- Q: Startup fails with
RESIN_PROXY_TOKENundefined?- A: Even if you do not want a proxy password, you must explicitly set it to empty:
RESIN_PROXY_TOKEN="".
- A: Even if you do not want a proxy password, you must explicitly set it to empty:
- Q: Startup fails with
RESIN_AUTH_VERSIONundefined?- A: Set it to
LEGACY_V0orV1. For new deployments, useV1. For upgrades with legacy data, see doc/v1.0.0-migration-guide.md.
- A: Set it to
- Q: Is there a dedicated v1.0.0 migration guide?
- A: Yes. See doc/v1.0.0-migration-guide.md.
- Q: How to write reverse-proxy paths for WebSocket (ws/wss)?
- A: In the URL path, the protocol field must still be
httporhttps(notws/wss). Resin auto-detects and handles WebSocket upgrade.
- A: In the URL path, the protocol field must still be
- License: This project is licensed under the MIT License.
- Use scope: This project is provided for technical research and engineering practice in proxy scheduling and management. It does not constitute legal, compliance, audit, or security advice.
- Lawful use requirement: You are responsible for ensuring your usage complies with applicable laws, regulations, target-service Terms of Service (ToS), and data-processing obligations, and for ensuring you have proper authorization for proxy nodes, target resources, and related data.
- Prohibited use: You must not use this project for unauthorized access, control-evasion, fraud, attacks, abusive traffic generation, or other illegal or non-compliant activity.
- No warranty: This project is provided on an "AS IS" basis, without express or implied warranties, including but not limited to merchantability, fitness for a particular purpose, and non-infringement.
- Limitation of liability: To the maximum extent permitted by applicable law, authors and contributors are not liable for any direct, indirect, incidental, special, exemplary, or consequential damages arising from use of, or inability to use, this project.