Files
3x-ui/docs/content/docs/en/config/clients.mdx
T
Jack 54d1712544 fix(clients): clarify renewal preview times and estimates (#6662)
* fix(clients): clarify renewal preview times and estimates

The preview rendered RFC3339 strings directly and labeled the server's Local
zone without explaining which clock it represented. Its renewal count also
looked like a record of renewals already performed.

Display readable dates with an explicit UTC offset while preserving the
server's wall time, per-date DST offset and fractional cutoff precision.
Explain the panel/server timezone and read-only preview, and label the
renewal count as estimated allowance consumption in all 13 locales.
Let the first-cutoff button wrap on narrow screens and update the English
and Chinese client documentation plus display/form regression coverage.

This changes presentation only: renewal calculations, stored expiry values,
API payloads and first-use behavior remain unchanged.

* test(clients): remove redundant renewal preview copy checks

The locale-only preview case repeated the Local timezone branch without
covering a distinct behavior. Exact textContent comparisons after matching
the same text with getByText also only pinned constant wording, contrary
to the repository's testing guidance.

Remove that duplicate case, its locale setup and the redundant copy
assertions. Keep the UTC, per-boundary DST offset, fractional precision
and original datetime checks, together with the existing real form-save
tests. Production rendering, translations and renewal behavior are unchanged.

---------

Co-authored-by: JacktheRanger <219502738+JacktheRanger@users.noreply.github.com>
2026-10-07 10:55:06 +02:00

140 lines
8.1 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
title: Clients
description: Manage 3x-ui clients — credentials, traffic and expiry limits, IP limits, groups, bulk actions, external links, and online status.
icon: Users
---
A **client** is a single user, identified by a unique **email**. In the current
panel, clients are first-class records that can be attached to **multiple
inbounds** at once, with per-client traffic accounting.
## Client fields
| Field | Applies to | Meaning |
| -------------- | --------------------- | ------------------------------------------------------------------ |
| **Email** | all | Unique identifier used for accounting and lookups. |
| **ID (UUID)** | VLESS, VMess, TUIC | The client credential. |
| **Password** | Trojan, Shadowsocks, TUIC | The client credential. |
| **Auth** | Hysteria2 | The client credential. |
| **Flow** | VLESS | XTLS flow, e.g. `xtls-rprx-vision`. |
| **Limit IP** | all (except TUIC) | Max simultaneous source IPs (enforced via Fail2ban). |
| **Total (GB)** | all | Traffic quota; the client is disabled when exhausted. |
| **Expiry** | all | Date after which the client stops working. |
| **Auto renewal** | all | Disabled, fixed interval in days, calendar weekly, or calendar monthly. |
| **Telegram ID**| all | Links the client to a Telegram user for self-service/notifications.|
| **Sub ID** | all | Subscription identifier grouping this client's links. |
| **Group** | all | Optional client group for organization and bulk filtering. |
| **Comment** | all | Free-text note. |
<Callout type="info">
Reaching the **traffic** or **expiry** limit disables the client, and a client
disabled or deleted by hand counts too; the panel restarts Xray then
(`restartXrayOnClientDisable`, on by default).
</Callout>
## Limits and IP control
- **Traffic / expiry** caps disable the client when hit; a **Reset** period
auto-renews the quota.
- **Limit IP** caps simultaneous source IPs. Enforcement relies on Fail2ban —
see [Security](/docs/operations/security). You can view a client's recent IPs
and clear them from the client's actions.
- **Online status** and **last-online** times are tracked per client (and per
node in multi-node setups).
## Automatic renewal
The individual and bulk-create forms offer one renewal mode at a time:
| Mode | API fields | Schedule |
| --- | --- | --- |
| Disabled | `reset=0`, `resetDay=0`, `resetWeekday=0` | The expiry is not renewed. |
| Fixed interval | `reset=N`, other two fields `0` | Add exactly N × 24 hours to the previous cutoff. |
| Calendar weekly | `resetWeekday=1..7`, other two fields `0` | Renew at panel-local midnight on Monday (1) through Sunday (7). |
| Calendar monthly | `resetDay=1..31`, `resetWeekday=0` | Renew at panel-local midnight on that day; missing dates clamp to the month's last day without losing the configured day. |
Calendar weeks stay on the selected weekday across daylight-saving changes;
they are not equivalent to a fixed seven-day interval. A skipped midnight uses
the first valid instant of that date; a repeated midnight uses the first one.
If a timezone skips the entire selected date, the next matching week is used.
Existing monthly clients
that also have `reset` set retain monthly precedence. The API rejects weekly
renewal combined with a positive `reset` or `resetDay`.
For a full calendar month, select **monthly, day 1** and set the initial cutoff
to the next month's first midnight. For example, `2030-09-01 00:00:00` is valid
through `2030-08-31 23:59:59`. Day 31 renews at the **start** of the 31st and is
not the same schedule. The existing optional month-end subscription-header
display remains a separate setting and is not enabled by this form.
The preview uses the panel's timezone and the same calendar/catch-up calculation
as automatic renewal. It shows the cutoff, last valid second, next expiry, and
allowances needed. It is informational: it does not save, activate, reserve, or
guarantee a future renewal. When no expiry is set, auto-renewal cannot run; an
explicit button can set the first calendar cutoff. Selecting a mode alone never
rewrites an existing expiry. First-use clients keep their initial duration, and
their calendar dates are available after activation.
Preview dates use the Gregorian format `YYYY-MM-DD HH:mm:ss UTC±HH:mm`,
preserving any fractional seconds in the cutoff. Each date includes its own
UTC offset, so a daylight-saving change can show different offsets before and
after renewal. The heading identifies the panel time zone; **Server local time**
means the server's `Local` setting, not the browser's time zone. For example,
`2026-09-27 05:00:00 UTC+00:00` is 13:00 in UTC+08:00. **Estimated renewals used**
is the allowance this preview would consume, including any catch-up periods,
not a count of renewals already performed. The first-cutoff button uses the same
date format; clicking it still requires saving the form to persist the change.
For legacy last-second calendar cutoffs, the renewal boundary includes the
existing free alignment to the following midnight. The last-valid-second
preview still uses the **stored expiry**, not that alignment: an exclusive
`23:59:59` cutoff is valid through `23:59:58`. Use a next-midnight cutoff for
full-day validity; the preview itself does not repair the initial expiry.
`resetMax=0` means unlimited renewals. A positive limit counts **each elapsed
period**, including offline catch-up, not each scheduler tick or attached inbound.
If the remaining allowances cannot reach a future cutoff, the client stays
expired and its traffic is not reset. Operator-disabled clients stay disabled.
Renewal already resets client traffic. The separate **periodic traffic reset**
does not move the expiry and is unchanged; keep it disabled unless you intend an
additional reset. Quarterly, yearly, and every-N-week/month schedules are not
part of these modes.
<Callout type="warn">
Upgrade the main panel and every participating node before enabling weekly
renewal. Older versions ignore `resetWeekday`; a weekly-only client would not
auto-renew and, after its expiry or quota is exhausted, can be deleted by
**delete depleted clients** because older versions lack the weekly protection.
Back up the database and convert weekly schedules to a renewal mode supported
by every participating version before downgrading. Merely disabling weekly
renewal does not protect a depleted client from deletion. Avoid depleted-client
cleanup while a mixed-version fleet or unconverted weekly clients remain.
Database upgrades default this new field to `0` and preserve existing limits
and dates.
</Callout>
## Share links and external links
Every client has share links and a QR code for its inbounds, plus a combined
[subscription](/docs/config/subscription). You can also attach **external
links** to a client — extra `vless://`, `vmess://`, `trojan://`, `ss://`,
`hysteria2://`, or `wireguard://` links, or a remote subscription URL — so they
appear alongside the panel-generated ones in the client's subscription.
To inspect exactly what a link contains, paste it into the
[share-link inspector](/docs/config/share-links).
## Bulk actions
For managing many clients at once, the panel supports bulk **create, enable,
disable, delete, attach/detach** (to inbounds), **reset traffic**, and
**adjust** (add days / add bytes / set flow). Maintenance actions also let you
delete **depleted** clients (quota/expiry exhausted) and **orphaned** clients
(not attached to any inbound).
<Callout type="warn">
A client's share link contains its credential. Treat links and QR codes like
passwords, and rotate the credential if one leaks.
</Callout>