Pubky Testnet
A local test network for developing Pubky Core or applications depending on it.
All resources are ephemeral, including the database, and all servers are cleaned up when the testnet is dropped.
Quickstart
Option 1: Embedded PostgreSQL (No External DB Required)
For testing without a separate Postgres installation, enable the embedded-postgres feature:
[]
= { = "0.6", = ["embedded-postgres"] }
#
#
#
use EphemeralTestnet;
#
async
The first run will download PostgreSQL binaries (~50-100MB), which are cached for subsequent runs.
Important: If you have multiple tests, see Sharing Embedded Postgres Across Tests below.
Option 2: External PostgreSQL
If you prefer to use an external Postgres instance:
# Example local Postgres with password auth
Then run the testnet binary:
TEST_PUBKY_CONNECTION_STRING='postgres://postgres:postgres@localhost:5432/postgres?pubky-test=true'
Usage
Writing Tests
use EphemeralTestnet;
// Macro ensures ephemeral Postgres databases are cleaned up
async
Custom Postgres Connection
By default (without embedded-postgres), testnet will use postgres://localhost:5432/postgres?pubky-test=true.
The ?pubky-test=true parameter indicates that the homeserver should create an ephemeral database.
To use a custom connection string:
Option A: Set the TEST_PUBKY_CONNECTION_STRING environment variable.
Option B: Pass the connection string programmatically:
use ;
async
Custom Configuration
use ;
async
Sharing Embedded Postgres Across Tests
When using embedded-postgres, each call to .with_embedded_postgres() starts a separate PostgreSQL instance.
The recommended pattern is to start one embedded postgres instance and share its connection string across all tests:
use EphemeralTestnet;
use EmbeddedPostgres;
use OnceCell;
// Shared embedded postgres instance for all tests in this module.
// Started once, reused by every test via its connection string.
static SHARED_PG: = const_new;
async
async
async
Each testnet still gets its own ephemeral database within the shared PostgreSQL instance, so tests remain isolated.
Troubleshooting
GitHub Rate Limiting During Binary Download
The embedded PostgreSQL binary is downloaded from GitHub releases. If multiple tests (or repeated test runs) try to download concurrently, you may hit GitHub's API rate limit (60 requests/hour for unauthenticated requests), causing errors like 403 Forbidden or rate limit exceeded.
Solutions (try in order):
-
Set a GitHub token to raise the rate limit from 60 to 5,000 requests/hour:
The token does not need any scopes — a classic PAT with no permissions works.
-
Run a single test first to populate the cache before running the full suite.
-
Share one embedded postgres instance across tests (see Sharing Embedded Postgres Across Tests).
-
Wait for the rate limit to reset (1 hour from first rate-limited request), then retry with one of the above solutions.
Cache location: ~/.cache/pubky-testnet/postgresql/ (Linux/macOS). If you suspect a corrupt cache, delete this directory and retry.
Binary (Static Testnet)
If you need to run the testnet in a separate process (e.g., to test Pubky Core in browsers), run the binary which creates these components with hardcoded configurations: