Skip to content

community list: default (non-quiet) is 2-30s slower than -q because the 'started' column spins up every community #76

Description

@Rinse12

Summary

bitsocial community list (default, non-quiet) is much slower than bitsocial community list -q, and the gap is highly variable — from ~2s to ~30s on a slower host with ~17 communities. The extra time is entirely the started column, which spins up every community over RPC just to read one boolean that the daemon already knows.

Measurements (slower 8-core host, ~17 communities)

Real CLI, 3 runs each:

Run list -q list (default) started-column delta
1 10.4s 40.5s +30s
2 10.6s 12.2s +1.6s
3 11.9s 15.4s +3.5s

(The ~10s floor is a separate pkc-js import-cost problem — see pkcprotocol/pkc-js#120. This issue is only about the delta the started column adds on top.)

Where the time goes

src/cli/commands/community/list.ts (non-quiet branch):

const communitiesWithStarted = await Promise.all(
    communities.map(async (address: string) => {
        const community = await pkc.createCommunity({ address }); // <-- expensive, per community
        return { address: community.address, started: community.started };
    })
);

For each local community, pkc.createCommunity({ address }) runs a full subscribe → update() → wait-for-first-updatestop() cycle on the daemon (pkc-js pkc-with-rpc-client.ts, the isCommunityRpcLocal branch). Profiling that call directly:

  • When the daemon's communities are warm (recently updated): all ~17 createCommunity in parallel ≈ 1.6s, destroy() ≈ 60ms.
  • When cold / the daemon is busy: each call blocks waiting for the first update (the daemon loading / fetching the community record), pushing the total to ~30s.

So the cost is O(N) blocking update round-trips, purely to populate started. -q skips all of it and is stable.

Impact

The default invocation is the slow one — users hit the worst case unless they know to pass -q. On a node with more (or colder) communities this scales linearly and makes a routine list feel broken.

Suggested directions

  1. Don't instantiate each community to read started. The daemon already tracks which local communities are started. Ideally expose started-state in the communities listing/subscription so the CLI can render the column with no per-community RPC. (May need a small pkc-js/daemon addition — relates to pkc-js takes ~9s just to import on slower hardware (local-node runtime eagerly loaded on the RPC-client path) pkcprotocol/pkc-js#120.)
  2. Short term, if a per-community lookup is unavoidable: avoid the full update()/wait cycle just for a boolean, and/or make the started column opt-in (e.g. --status) so the default list is fast like -q.
  3. At minimum, document that -q is dramatically faster for scripting.

Repro

time bitsocial community list -q
time bitsocial community list

on a daemon with a non-trivial number of communities; compare the delta across cold/warm runs.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions