Skip to content

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

@Rinse12

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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions