perf(stats): read peers from instances, update every 5 minutes

The peers query read the nickname of every remote user every minute
(2.7 s and 1.2M buffer hits on a large instance). The instances table
now has a row for every host we know users from, so read it instead,
and recompute the stats every 5 minutes.

Based on Akkoma 138b1aea2 and 7b76fdeed.

Co-authored-by: Oneric <oneric@oneric.stub>
Co-authored-by: FloatingGhost <hannah@coffee-and-dreams.uk>
This commit is contained in:
Lain Soykaf 2026-10-27 20:49:52 +04:00
commit e8f238359f
No known key found for this signature in database
3 changed files with 11 additions and 13 deletions

View file

@ -8,10 +8,11 @@ defmodule Pleroma.Stats do
import Ecto.Query
alias Pleroma.CounterCache
alias Pleroma.Instances.Instance
alias Pleroma.Repo
alias Pleroma.User
@interval :timer.seconds(60)
@interval :timer.seconds(300)
def start_link(_) do
GenServer.start_link(
@ -64,14 +65,9 @@ defmodule Pleroma.Stats do
}
}
def calculate_stat_data do
peers =
from(
u in User,
select: fragment("distinct split_part(?, '@', 2)", u.nickname),
where: u.local != ^true
)
|> Repo.all()
|> Enum.filter(& &1)
# Hosts are unique in instances, and remote users add theirs. Scanning
# all remote users for their domains was one of the costliest queries.
peers = Repo.all(from(i in Instance, select: i.host))
domain_count = Enum.count(peers)