mirror of
https://github.com/binwiederhier/ntfy.git
synced 2026-11-10 14:44:04 +08:00
Show the reset time and the sync delay on the account page, document shared daily limits
Claude-Session: https://claude.ai/code/session_01DeXuhSjq5Gta5qPJgSceFe
This commit is contained in:
1 parent
c113e20677
commit
c3ecea55c4
5 files changed
+46
-10
No files matched your search
+16
-3
@@ -410,7 +410,7 @@ This generator helps you configure your self-hosted ntfy instance. It's not full
|
||||
</div>
|
||||
|
||||
## Database options
|
||||
ntfy uses a database for storing messages ([message cache](#message-cache)), users and [access control](#access-control), and [web push](#web-push) subscriptions.
|
||||
ntfy uses a database for storing messages ([message cache](#message-cache)), users and [access control](#access-control) (which includes the visitors' daily usage counts, see [message limits](#message-limits)), and [web push](#web-push) subscriptions.
|
||||
You can choose between **SQLite** and **PostgreSQL** as the database backend.
|
||||
|
||||
### SQLite
|
||||
@@ -1926,7 +1926,17 @@ For instance, if the request limit allows for 15,000 requests per day, and all o
|
||||
to publish messages, then that is the daily message limit.
|
||||
|
||||
To limit the number of daily messages per visitor, you can set `visitor-message-daily-limit`. This defines the number
|
||||
of messages a visitor can send in a day. This counter is reset every day at midnight (UTC).
|
||||
of messages a visitor can send in a day. The day is a rolling 24-hour period per visitor (per account, or per IP address
|
||||
for anonymous visitors), not the calendar day: each visitor's period starts at its own time of day, derived from the
|
||||
visitor, so not every count resets at once. The account page shows when a visitor's counts reset next.
|
||||
|
||||
The daily counts (messages, e-mails and phone calls) are kept in the user database if `auth-file` (SQLite) or
|
||||
`database-url` (PostgreSQL) is set, so they survive a restart. With PostgreSQL, all ntfy servers sharing the database
|
||||
also share the counts: each server writes what it counted every 5 seconds and reads what the others counted, so a visitor
|
||||
gets one daily allowance in total, not one per server (it may overshoot by a few seconds of traffic). An anonymous
|
||||
visitor's message count is only written once it reaches 10% of its daily limit, so the many visitors that publish a
|
||||
few messages never touch the database; a restart forgets those few. Without a user database, the counts are kept in
|
||||
memory only and start over with every restart.
|
||||
|
||||
### Attachment limits
|
||||
Aside from the global file size and total attachment cache limits (see [above](#attachments)), there are two relevant
|
||||
@@ -1948,6 +1958,9 @@ are enabled):
|
||||
* `visitor-email-limit-burst` is the initial bucket of emails each visitor has. This defaults to 16.
|
||||
* `visitor-email-limit-replenish` is the rate at which the bucket is refilled (one email per x). Defaults to 1h.
|
||||
|
||||
Visitors without a tier can send at most 24h / `visitor-email-limit-replenish` e-mails per day (24 by default), a daily
|
||||
limit that, like the message limit, survives restarts and is shared between servers if a user database is configured.
|
||||
|
||||
### Topic creation limits
|
||||
To mitigate topic-enumeration / squatting attacks (where a single source pokes thousands of guessable
|
||||
topic names to inflate the server's in-memory topic map), there is a per-visitor limit on how many *new*
|
||||
@@ -2559,7 +2572,7 @@ variable before running the `ntfy` command (e.g. `export NTFY_LISTEN_HTTP=:80`).
|
||||
| `visitor-attachment-daily-bandwidth-limit` | `NTFY_VISITOR_ATTACHMENT_DAILY_BANDWIDTH_LIMIT` | *size* | 500M | Rate limiting: Total daily traffic limit per visitor, covering attachment downloads/uploads and messages replayed from the cache by poll requests. This is to protect your bandwidth costs from exploding. |
|
||||
| `visitor-email-limit-burst` | `NTFY_VISITOR_EMAIL_LIMIT_BURST` | *number* | 16 | Rate limiting:Initial limit of e-mails per visitor |
|
||||
| `visitor-email-limit-replenish` | `NTFY_VISITOR_EMAIL_LIMIT_REPLENISH` | *duration* | 1h | Rate limiting: Strongly related to `visitor-email-limit-burst`: The rate at which the bucket is refilled |
|
||||
| `visitor-message-daily-limit` | `NTFY_VISITOR_MESSAGE_DAILY_LIMIT` | *number* | - | Rate limiting: Allowed number of messages per day per visitor, reset every day at midnight (UTC). By default, this value is unset. |
|
||||
| `visitor-message-daily-limit` | `NTFY_VISITOR_MESSAGE_DAILY_LIMIT` | *number* | - | Rate limiting: Allowed number of messages per day per visitor, reset every 24 hours at the visitor's own time of day. By default, this value is unset. |
|
||||
| `visitor-request-limit-burst` | `NTFY_VISITOR_REQUEST_LIMIT_BURST` | *number* | 60 | Rate limiting: Allowed GET/PUT/POST requests per second, per visitor. This setting is the initial bucket of requests each visitor has |
|
||||
| `visitor-request-limit-replenish` | `NTFY_VISITOR_REQUEST_LIMIT_REPLENISH` | *duration* | 5s | Rate limiting: Strongly related to `visitor-request-limit-burst`: The rate at which the bucket is refilled |
|
||||
| `visitor-request-limit-exempt-hosts` | `NTFY_VISITOR_REQUEST_LIMIT_EXEMPT_HOSTS` | *comma-separated host/IP/CIDR list* | - | Rate limiting: List of hostnames and IPs to be exempt from request rate limiting |
|
||||
|
||||
@@ -2288,6 +2288,18 @@ and the [ntfy Android app](https://github.com/binwiederhier/ntfy-android/release
|
||||
|
||||
## Not released yet
|
||||
|
||||
### ntfy server v2.36.0 (UNRELEASED)
|
||||
|
||||
**Features:**
|
||||
|
||||
* Daily limits (messages, e-mails, phone calls) are kept in the user database (`auth-file` for SQLite, or `database-url` for PostgreSQL) and survive restarts; with PostgreSQL, all servers share them, so a visitor gets one daily allowance in total, not one per server (see [message limits](config.md#message-limits))
|
||||
|
||||
**Behavior changes:**
|
||||
|
||||
* Daily limits now reset on a rolling 24-hour period per account or IP address instead of for everyone at midnight UTC: each visitor's period starts at its own time of day, which spreads the resets over the day. The account page and the `/v1/account` API (`stats.reset_at`) show when the visitor's counts reset
|
||||
* Visitors without a tier have a daily e-mail limit again (24h / `visitor-email-limit-replenish`), now that it is shared between servers and survives restarts
|
||||
* The daily reset job is gone; the `stats_*` columns of the user table are zeroed by the upgrade and no longer read or written
|
||||
|
||||
### ntfy iOS app v1.8.0 (UNRELEASED)
|
||||
|
||||
**Features:**
|
||||
|
||||
+6
-3
@@ -398,9 +398,12 @@
|
||||
# visitor-request-limit-replenish: "5s"
|
||||
# visitor-request-limit-exempt-hosts: ""
|
||||
|
||||
# Rate limiting: Hard daily limit of messages per visitor and day. The limit is reset
|
||||
# every day at midnight UTC. If the limit is not set (or set to zero), the request
|
||||
# limit (see above) governs the upper limit.
|
||||
# Rate limiting: Hard daily limit of messages per visitor and day. The day is a rolling 24-hour
|
||||
# period per visitor (account or IP), starting at a time of day of the visitor's own, so not
|
||||
# every count resets at once. If the limit is not set (or set to zero), the request
|
||||
# limit (see above) governs the upper limit. The daily counts (messages, emails, calls) are
|
||||
# kept in the user database ("auth-file", or "database-url"), so they survive a restart and,
|
||||
# on PostgreSQL, are shared by all servers; without one, they are counted in memory only.
|
||||
#
|
||||
# visitor-message-daily-limit: 0
|
||||
|
||||
|
||||
@@ -267,7 +267,8 @@
|
||||
"account_usage_title": "Usage",
|
||||
"account_usage_of_limit": "of {{limit}}",
|
||||
"account_usage_unlimited": "Unlimited",
|
||||
"account_usage_limits_reset_daily": "Usage limits are reset daily at midnight (UTC)",
|
||||
"account_usage_limits_reset_at": "Daily usage limits reset every 24 hours, next at {{time}}",
|
||||
"account_usage_approximate": "Usage figures are updated every few seconds and may be slightly behind.",
|
||||
"account_basics_tier_title": "Account type",
|
||||
"account_basics_tier_description": "Your account's power level",
|
||||
"account_basics_tier_admin": "Admin",
|
||||
|
||||
@@ -840,12 +840,16 @@ const AddPhoneNumberDialog = (props) => {
|
||||
const Stats = () => {
|
||||
const { t, i18n } = useTranslation();
|
||||
const { account } = useContext(AccountContext);
|
||||
const { dateFormat, timeFormat } = usePrefCache();
|
||||
|
||||
if (!account) {
|
||||
return <></>;
|
||||
}
|
||||
|
||||
const normalize = (value, max) => Math.min((value / max) * 100, 100);
|
||||
const resetDaily = t("account_usage_limits_reset_at", {
|
||||
time: formatDateTime(account.stats.reset_at, dateFormat, timeFormat),
|
||||
});
|
||||
|
||||
return (
|
||||
<Card sx={{ p: 3 }} aria-label={t("account_usage_title")}>
|
||||
@@ -881,7 +885,7 @@ const Stats = () => {
|
||||
title={
|
||||
<>
|
||||
{t("account_usage_messages_title")}
|
||||
<Tooltip title={t("account_usage_limits_reset_daily")}>
|
||||
<Tooltip title={resetDaily}>
|
||||
<span>
|
||||
<InfoIcon />
|
||||
</span>
|
||||
@@ -911,7 +915,7 @@ const Stats = () => {
|
||||
title={
|
||||
<>
|
||||
{t("account_usage_emails_title")}
|
||||
<Tooltip title={t("account_usage_limits_reset_daily")}>
|
||||
<Tooltip title={resetDaily}>
|
||||
<span>
|
||||
<InfoIcon />
|
||||
</span>
|
||||
@@ -942,7 +946,7 @@ const Stats = () => {
|
||||
title={
|
||||
<>
|
||||
{t("account_usage_calls_title")}
|
||||
<Tooltip title={t("account_usage_limits_reset_daily")}>
|
||||
<Tooltip title={resetDaily}>
|
||||
<span>
|
||||
<InfoIcon />
|
||||
</span>
|
||||
@@ -1018,6 +1022,9 @@ const Stats = () => {
|
||||
</Pref>
|
||||
)}
|
||||
</PrefGroup>
|
||||
<Typography variant="body1" sx={{ pt: 3 }}>
|
||||
{t("account_usage_approximate")}
|
||||
</Typography>
|
||||
{account.role === Role.USER && account.limits.basis === LimitBasis.IP && (
|
||||
<Typography variant="body1" sx={{ pt: 3 }}>
|
||||
{t("account_usage_basis_ip_description")}
|
||||
|
||||
Reference in new issue
Block a user